/* ---------------------------------------------------------------------------
   Juno Solutions — site stylesheet

   Hand-written rather than a utility framework on purpose. The old pages
   pulled cdn.tailwindcss.com, which is the development build: it compiles
   stylesheets in the browser on every page load and prints a console warning
   telling you not to use it in production. An integrating operator's
   engineer opens devtools.

   The design commits to one dark palette rather than following the viewer's
   theme. Game art is dark, operator lobbies are dark, and a light variant of
   this page would be a different design rather than the same one inverted.
   Every colour is therefore explicit and nothing depends on a media query.
--------------------------------------------------------------------------- */

:root {
    /* Neutrals carry a slight blue-green bias so they read as chosen
       against the amber rather than as default grey. */
    --ink: #0e1113;
    --graphite: #15191c;
    --steel: #1d2327;
    --raised: #22292e;
    --line: #2b3238;
    --line-soft: #1f2529;
    --dim: #5c666c;
    --mute: #8b969d;
    --paper: #d9dedf;
    --bright: #f4f6f6;

    --accent: #e0912d;
    --accent-deep: #a5661a;
    --accent-wash: rgba(224, 145, 45, 0.09);

    --live: #4a9e78;
    --warn: #c4563d;

    --sans: "Archivo", "Helvetica Neue", Arial, sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

    --gutter: 24px;
    --measure: 1240px;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--ink);
    color: var(--paper);
    font-family: var(--sans);
    font-size: 16px;
    line-height: 1.6;
    font-synthesis-weight: none;
    -webkit-font-smoothing: antialiased;
}

/* Keep the footer down even on a short page. */
body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

main {
    flex: 1 0 auto;
}

img {
    max-width: 100%;
    display: block;
}

a {
    color: inherit;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* --- type scale ------------------------------------------------------- */

h1,
h2,
h3,
h4 {
    margin: 0;
    color: var(--bright);
    font-weight: 600;
    line-height: 1.1;
    text-wrap: balance;
    letter-spacing: -0.015em;
}

h1 {
    font-size: clamp(2.1rem, 5vw, 3.4rem);
    font-stretch: 96%;
}

h2 {
    font-size: clamp(1.5rem, 3vw, 2.1rem);
}

h3 {
    font-size: 1.15rem;
}

p {
    margin: 0 0 1rem;
    max-width: 66ch;
}

p:last-child {
    margin-bottom: 0;
}

/* The uppercase mono label is the site's recurring structural device. It
   marks every section and every spec row, which is what ties the marketing
   pages to the spec sheets. */
.eyebrow {
    font-family: var(--mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent);
    margin: 0 0 0.9rem;
}

.eyebrow--mute {
    color: var(--dim);
}

.lede {
    font-size: clamp(1rem, 1.6vw, 1.15rem);
    color: var(--mute);
}

.num {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

/* --- shell ------------------------------------------------------------ */

.wrap {
    width: 100%;
    max-width: var(--measure);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

.band {
    padding: clamp(3rem, 7vw, 5.5rem) 0;
    border-top: 1px solid var(--line-soft);
}

.band--flush {
    border-top: 0;
}

.band--raised {
    background: var(--graphite);
}

.section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 2.25rem;
}

.section-head p {
    color: var(--mute);
    margin: 0.6rem 0 0;
}

/* --- header ----------------------------------------------------------- */

.site-head {
    position: sticky;
    top: 0;
    z-index: 60;
    background: rgba(14, 17, 19, 0.92);
    backdrop-filter: saturate(140%) blur(8px);
    border-bottom: 1px solid var(--line-soft);
}

.site-head__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    height: 68px;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    flex: 0 0 auto;
}

.brand__mark {
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
}

.brand__name {
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--bright);
}

.brand__name span {
    color: var(--dim);
    font-weight: 400;
}

.nav {
    display: flex;
    align-items: center;
    gap: 1.6rem;
}

.nav a {
    text-decoration: none;
    font-size: 0.925rem;
    color: var(--mute);
    transition: color 0.15s;
    white-space: nowrap;
}

.nav a:hover {
    color: var(--bright);
}

.nav a[aria-current="page"] {
    color: var(--bright);
}

/* The call-to-action in the navigation is a button that happens to be an
   anchor, and ".nav a" (one class + one type) outranks ".btn--primary"
   (one class), so the amber button inherited the navigation's muted text
   colour and rendered orange on orange. Re-assert it at a specificity that
   wins, including on hover. */
.nav .btn--primary,
.nav .btn--primary:hover {
    color: #1a1205;
}

.nav .btn--ghost,
.nav .btn--ghost:hover {
    color: var(--bright);
}

.nav-toggle {
    display: none;
    background: none;
    border: 1px solid var(--line);
    color: var(--paper);
    width: 40px;
    height: 36px;
    border-radius: 2px;
    cursor: pointer;
    align-items: center;
    justify-content: center;
}

.nav-toggle svg {
    width: 18px;
    height: 18px;
}

/* --- buttons ---------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.7rem 1.25rem;
    font-family: var(--sans);
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: 2px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.btn--primary {
    background: var(--accent);
    color: #1a1205;
}

.btn--primary:hover {
    background: #eda03a;
}

.btn--ghost {
    border-color: var(--line);
    color: var(--bright);
    background: transparent;
}

.btn--ghost:hover {
    border-color: var(--dim);
    background: var(--steel);
}

.btn--sm {
    padding: 0.45rem 0.8rem;
    font-size: 0.8rem;
}

.btn[aria-disabled="true"] {
    opacity: 0.45;
    pointer-events: none;
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 2rem;
}

/* --- hero ------------------------------------------------------------- */

.hero {
    padding: clamp(3rem, 8vw, 6rem) 0 clamp(2.5rem, 5vw, 4rem);
    position: relative;
}

.hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: start;
}

.hero h1 {
    margin-bottom: 1.4rem;
}

.hero__rule {
    width: 48px;
    height: 3px;
    background: var(--accent);
    margin-bottom: 1.6rem;
}

/* The spec panel beside the hero headline. Leading with what the platform
   actually is, rather than an adjective about it, is the whole idea. */
.spec-panel {
    border: 1px solid var(--line);
    background: var(--graphite);
}

.spec-panel__head {
    padding: 0.85rem 1.15rem;
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.spec-panel__head .eyebrow {
    margin: 0;
}

.spec-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1.25rem;
    padding: 0.7rem 1.15rem;
    border-bottom: 1px solid var(--line-soft);
}

.spec-row:last-child {
    border-bottom: 0;
}

.spec-row dt,
.spec-row__k {
    color: var(--mute);
    font-size: 0.85rem;
    flex: 0 0 auto;
}

.spec-row dd,
.spec-row__v {
    margin: 0;
    color: var(--bright);
    font-family: var(--mono);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.spec-panel dl {
    margin: 0;
}

/* A value with no break points -- a hostname -- is put on its own line
   instead of being hyphen-free chopped mid-word by word-break: break-all,
   which rendered "junosolutions.i / o". */
.spec-row--stack {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
}

.spec-row--stack dd {
    text-align: left;
    overflow-wrap: anywhere;
}

/* --- game grid -------------------------------------------------------- */

/* The grid reads as one continuous ruled sheet rather than a set of
   floating cards. It gets there with a 1px gap and a hairline drawn on each
   card with box-shadow, so neighbouring rules land in the same gap and look
   like a single line.

   Drawing those rules on the grid's own background instead -- the usual
   trick -- was the first attempt and it was wrong: a last row with fewer
   cards than columns left the background showing through as phantom empty
   cells, which looked like the page had failed to load. A border carried by
   the card means a row that is not full simply ends. */
.game-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
    gap: 1px;
    background: transparent;
}

.game-card {
    display: flex;
    flex-direction: column;
    background: var(--graphite);
    box-shadow: 0 0 0 1px var(--line-soft);
    text-decoration: none;
    transition: background 0.15s;
    position: relative;
}

.game-card:hover {
    background: var(--steel);
}

/* Square, because the catalogue artwork is square and carries the game's
   name baked into the image. A 16:10 tile cropped roughly a fifth off the
   top and bottom, which took the title with it. Square is also how an
   operator's own lobby renders a game tile, so this is what the art will
   look like in the place it actually ends up. */
.game-card__art {
    aspect-ratio: 1 / 1;
    background: var(--steel);
    position: relative;
    overflow: hidden;
}

.game-card__art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: saturate(92%);
}

/* Games without artwork yet get a typed placeholder rather than an empty
   box: the game code set in mono over a fine diagonal hatch. It reads as a
   deliberate holding tile instead of a missing image. */
.game-card__art--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--steel);
    background-image: repeating-linear-gradient(135deg,
            rgba(255, 255, 255, 0.022) 0 1px,
            transparent 1px 7px);
}

.game-card__art--empty span {
    font-family: var(--mono);
    font-size: 0.78rem;
    letter-spacing: 0.1em;
    color: var(--dim);
    text-transform: uppercase;
}

.game-card__body {
    padding: 1.1rem 1.15rem 1.25rem;
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    gap: 0.5rem;
}

.game-card__title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
}

.game-card__title h3 {
    font-size: 1.05rem;
}

.game-card__kicker {
    color: var(--mute);
    font-size: 0.875rem;
    line-height: 1.45;
    margin: 0;
    flex: 1 0 auto;
}

.game-card__foot {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.4rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--line-soft);
    font-family: var(--mono);
    font-size: 0.75rem;
    color: var(--dim);
}

.game-card__foot .sep {
    color: var(--line);
}

/* --- chips and tags --------------------------------------------------- */

.game-card[hidden] {
    display: none;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.18rem 0.45rem;
    border: 1px solid var(--line);
    border-radius: 2px;
    font-family: var(--mono);
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mute);
    white-space: nowrap;
}

.chip--accent {
    border-color: var(--accent-deep);
    color: var(--accent);
    background: var(--accent-wash);
}

.chip--live {
    border-color: rgba(74, 158, 120, 0.4);
    color: var(--live);
}

.chip--soon {
    border-color: var(--line);
    color: var(--dim);
}

.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* --- generic card columns -------------------------------------------- */

/* Same hairline technique, same reason -- see .game-grid. */
.cols {
    display: grid;
    gap: 1px;
    background: transparent;
}

/* Explicit counts rather than auto-fit. auto-fit with a minmax floor packs
   as many columns as will fit, so a "two-up" group silently became four
   narrow columns at desktop width and a six-item group broke 4 + 2. The
   number in the class name should be the number you get. */
.cols--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.cols--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 980px) {
    .cols--3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 680px) {

    .cols--2,
    .cols--3 {
        grid-template-columns: minmax(0, 1fr);
    }
}

.cell {
    background: var(--graphite);
    box-shadow: 0 0 0 1px var(--line-soft);
    padding: 1.5rem 1.4rem;
}

/* On a raised band the cell and the band are the same tone, so lift the
   cell a step to keep the grouping readable. */
.band--raised .cell {
    background: var(--steel);
}

.cell h3 {
    margin-bottom: 0.6rem;
}

.cell p {
    color: var(--mute);
    font-size: 0.925rem;
    margin: 0;
}

/* --- plain lists ------------------------------------------------------ */

.ticks {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.ticks li {
    position: relative;
    padding-left: 1.1rem;
    color: var(--paper);
    font-size: 0.925rem;
    line-height: 1.5;
}

.ticks li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.6em;
    width: 5px;
    height: 1px;
    background: var(--accent);
}

/* --- integration steps ------------------------------------------------
   Numbered because the calls genuinely happen in this order; an operator
   cannot launch a session before fetching the catalogue. Numbering
   something unordered would be decoration.                              */

.steps {
    counter-reset: step;
    display: flex;
    flex-direction: column;
    gap: 0;
}

.step {
    counter-increment: step;
    display: grid;
    grid-template-columns: 3.25rem minmax(0, 1fr);
    gap: 1.5rem;
    padding: 2rem 0;
    border-top: 1px solid var(--line-soft);
}

.step:last-child {
    border-bottom: 1px solid var(--line-soft);
}

.step::before {
    content: counter(step, decimal-leading-zero);
    font-family: var(--mono);
    font-size: 0.85rem;
    color: var(--accent);
    padding-top: 0.2rem;
}

.step h3 {
    margin-bottom: 0.65rem;
}

.step p {
    color: var(--mute);
    font-size: 0.95rem;
}

/* --- code ------------------------------------------------------------- */

.code {
    margin: 1rem 0 0;
    padding: 1rem 1.1rem;
    background: var(--ink);
    border: 1px solid var(--line);
    overflow-x: auto;
    font-family: var(--mono);
    font-size: 0.82rem;
    line-height: 1.65;
    color: var(--paper);
    white-space: pre;
    tab-size: 2;
}

.code b {
    color: var(--accent);
    font-weight: 500;
}

.code i {
    color: var(--dim);
    font-style: normal;
}

/* --- spec sheet (game detail) ---------------------------------------- */

.sheet {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
}

/* Square, like the grid tiles and for the same reason: the art is square
   and carries the game's name in the lower third. Any wide crop of it loses
   the title. Capped in width so the sheet stays a document rather than
   becoming a poster. */
.sheet__art {
    border: 1px solid var(--line);
    aspect-ratio: 1 / 1;
    max-width: 420px;
    background: var(--steel);
    margin-bottom: 1.75rem;
    overflow: hidden;
}

.sheet__art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.crumb {
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--dim);
    margin-bottom: 1.25rem;
}

.crumb a {
    color: var(--mute);
    text-decoration: none;
}

.crumb a:hover {
    color: var(--bright);
}

/* --- filter bar ------------------------------------------------------- */

.filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.75rem;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid var(--line-soft);
}

.filter {
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: 0.4rem 0.8rem;
    font-family: var(--mono);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mute);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.filter:hover {
    color: var(--bright);
    border-color: var(--dim);
}

.filter[aria-pressed="true"] {
    color: var(--accent);
    border-color: var(--accent-deep);
    background: var(--accent-wash);
}

/* --- forms ------------------------------------------------------------ */

.field {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-bottom: 1.1rem;
}

.field label {
    font-size: 0.85rem;
    color: var(--mute);
}

.field input,
.field textarea,
.field select {
    font-family: var(--sans);
    font-size: 0.95rem;
    color: var(--bright);
    background: var(--ink);
    border: 1px solid var(--line);
    border-radius: 2px;
    padding: 0.65rem 0.8rem;
    width: 100%;
}

.field input:focus,
.field textarea:focus {
    border-color: var(--accent-deep);
    outline: none;
}

.field textarea {
    resize: vertical;
    min-height: 140px;
}

.form-panel {
    border: 1px solid var(--line);
    background: var(--graphite);
    padding: clamp(1.4rem, 3vw, 2rem);
}

.note {
    font-size: 0.85rem;
    color: var(--dim);
}

/* --- callout ---------------------------------------------------------- */

.callout {
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    background: var(--graphite);
    padding: 1.25rem 1.4rem;
}

.callout p {
    color: var(--mute);
    font-size: 0.925rem;
}

/* --- footer ----------------------------------------------------------- */

.site-foot {
    background: var(--graphite);
    border-top: 1px solid var(--line-soft);
    padding: 3rem 0 2rem;
    margin-top: 0;
}

.site-foot__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) repeat(auto-fit, minmax(140px, 1fr));
    gap: 2rem;
    padding-bottom: 2.25rem;
    border-bottom: 1px solid var(--line-soft);
}

.site-foot h4 {
    font-family: var(--mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--dim);
    margin-bottom: 0.9rem;
}

.site-foot ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.site-foot a {
    color: var(--mute);
    text-decoration: none;
    font-size: 0.9rem;
}

.site-foot a:hover {
    color: var(--bright);
}

.site-foot__blurb {
    color: var(--dim);
    font-size: 0.875rem;
    max-width: 40ch;
    margin: 0.9rem 0 0;
}

.site-foot__base {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: space-between;
    align-items: center;
    padding-top: 1.5rem;
    font-size: 0.8rem;
    color: var(--dim);
}

.age {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid var(--dim);
    border-radius: 50%;
    font-family: var(--mono);
    font-size: 0.7rem;
    color: var(--mute);
    flex: 0 0 auto;
}

/* --- responsive ------------------------------------------------------- */

@media (max-width: 900px) {
    .hero__grid,
    .sheet {
        grid-template-columns: minmax(0, 1fr);
    }

    .site-foot__grid {
        grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    }
}

@media (max-width: 720px) {
    .nav-toggle {
        display: inline-flex;
    }

    .nav {
        position: absolute;
        top: 68px;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background: var(--graphite);
        border-bottom: 1px solid var(--line);
        padding: 0.5rem 0;
        display: none;
    }

    .nav[data-open="true"] {
        display: flex;
    }

    .nav a {
        padding: 0.75rem var(--gutter);
        font-size: 1rem;
    }

    .nav .btn {
        margin: 0.5rem var(--gutter);
        justify-content: center;
    }

    .step {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.75rem;
    }

    .spec-row {
        flex-direction: column;
        gap: 0.2rem;
    }

    .spec-row dd,
    .spec-row__v {
        text-align: left;
    }
}
