/* =========================================================================
   CS-THEME-02 — the shell: header, navigation, search, account, mobile
   menu, footer. Nothing else. No game cards, no home sections, no game
   page — those are later phases.

   LOGICAL PROPERTIES ONLY. margin-inline, padding-inline, inset-inline,
   border-inline-*, text-align:start. No margin-left, no right:, no
   padding-right. The audit found rtl.css at 3.9 KB patching bootstrap.css
   at 129 KB of physical directions — a correction layer over a layout
   that was never written for Arabic. This is written RTL-first instead,
   and the same file serves LTR untouched.

   The two documented exceptions are marked EXCEPTION and explained where
   they appear.
   ========================================================================= */

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

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

body {
    margin: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-ui);
    font-size: var(--text-base);
    line-height: var(--leading);
    /* The audit measured 560px of horizontal overflow on the game page at
       1280. Nothing in the shell may reintroduce it — and this is a
       backstop, not the fix. Hiding an overflow only hides the evidence,
       so the browser suite asserts scrollWidth <= clientWidth as well. */
    overflow-x: hidden;
}

img, svg { max-width: 100%; }

/* Icons take their size from CSS, never from an attribute, and their
   colour from the text around them. */
.i {
    inline-size: 1.25em;
    block-size: 1.25em;
    flex: none;
    color: inherit;
    vertical-align: -0.18em;
}
.i-defs { position: absolute; inline-size: 0; block-size: 0; overflow: hidden; }

/* In RTL the chevron must point the other way. One transform, not a
   second icon. */
[dir="rtl"] .i-flip { transform: scaleX(-1); }

/* ---- focus -------------------------------------------------------------
   Visible on every interactive element, in a colour that is not the
   accent so it stays visible on accent-coloured buttons. */
:where(a, button, input, [tabindex]):focus-visible {
    outline: 3px solid var(--color-focus);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* ---- skip link ---------------------------------------------------------
   Off-screen until focused. The audit found no skip link anywhere. */
.skip-link {
    position: absolute;
    inset-block-start: -100%;
    inset-inline-start: var(--space-4);
    z-index: 100;
    background: var(--color-accent);
    color: var(--color-accent-ink);
    padding: var(--space-3) var(--space-4);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    text-decoration: none;
    font-weight: 700;
}
.skip-link:focus { inset-block-start: 0; }

/* A label that exists for assistive tech only. Not display:none — that
   would remove it from the accessibility tree, which is the opposite of
   the point. */
.visually-hidden-label {
    position: absolute;
    inline-size: 1px; block-size: 1px;
    margin: -1px; padding: 0; border: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

.container {
    max-inline-size: var(--container);
    margin-inline: auto;
    padding-inline: var(--space-4);
}

/* =======================================================================
   HEADER
   ======================================================================= */

.site-header {
    position: sticky;
    inset-block-start: 0;
    z-index: 40;
    background: var(--color-surface);
    border-block-end: 1px solid var(--color-border);
    box-shadow: var(--shadow-1);
}

.site-header__bar {
    min-block-size: var(--header-height);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    /* Phone: the brand, the drawer button and the theme toggle share the
       first line; the search takes a full second line. Crushing all four
       onto one row measured a 4px-wide input and 575px of overflow on a
       360px screen. A search box nobody can hit is the defect the audit
       found in the old theme, arrived at from the other direction. */
    flex-wrap: wrap;
    padding-block: var(--space-2);
}

.brand {
    display: inline-flex;
    min-inline-size: 0;
    /* AN INLINE-FLEX BOX SIZES TO ITS CONTENT UNLESS SOMETHING CAPS IT.
       Measured at 360: the grid item resolved to 328px, but .brand computed
       374px with max-width:none — exactly its children, 34 + 8 gap + 332.
       With no upper bound nothing ever pressured .brand__text to shrink, so
       its min-inline-size:0 and text-overflow:ellipsis could not engage and
       the brand sat 30px past the reading edge.
       Capping it at the container is the constraint that was missing; the
       flex child then shrinks and ellipsises as it was always written to.
       Logical property, so RTL is unaffected, and it is inert wherever the
       brand already fits. */
    max-inline-size: 100%;
    align-items: center;
    gap: var(--space-2);
    text-decoration: none;
    color: var(--color-text);
    font-weight: 800;
    font-size: var(--text-lg);
    min-block-size: var(--tap-min);
}
/* the brand may shorten before anything else is allowed to overflow */
.brand__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* THE ELLIPSIS COULD NEVER FIRE WITHOUT THIS. As a flex item this span
       defaults to min-width:auto, i.e. its min-content width, so a long site
       name kept it at its full 332px and pushed .brand 30px past the reading
       edge at 360. The three declarations above describe what should happen
       when it runs out of room; this is what allows it to run out of room.
       Logical property, so RTL is unaffected. */
    min-inline-size: 0;
}
.brand__mark {
    inline-size: 34px; block-size: 34px;
    display: grid; place-items: center;
    border-radius: var(--radius-sm);
    background: var(--color-accent);
    color: var(--color-accent-ink);
}
.brand__mark .i { inline-size: 20px; block-size: 20px; }

/* ---- primary navigation ----------------------------------------------- */
.site-nav { display: none; }                 /* mobile-first: menu instead */
.site-nav__list {
    list-style: none;
    margin: 0; padding: 0;
    display: flex;
    align-items: center;
    gap: var(--space-1);
}
.site-nav__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-block-size: var(--tap-min);
    padding-inline: var(--space-3);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--color-muted);
    font-size: var(--text-sm);
    font-weight: 600;
    white-space: nowrap;
}
.site-nav__link:hover { background: var(--color-surface-2); color: var(--color-text); }
.site-nav__link[aria-current="page"] { color: var(--color-accent); background: var(--color-surface-2); }

/* ---- search ------------------------------------------------------------
   The audit found the old search input rendered 0x0 and its icon absent
   on every route. This one is a real, visible, always-present form. */
/* own row on phones, inline from the tablet breakpoint up */
.site-search { flex: 1 0 100%; min-inline-size: 0; order: 3; }
.site-search__field {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding-inline: var(--space-3);
    /* min, not fixed: the input inside sets the real height. A fixed 44px
       field left the input at 42px once its 1px borders were taken off,
       so the thing being tapped was two pixels under the minimum while
       the thing being looked at was exactly on it. */
    min-block-size: var(--tap-min);
}
.site-search__field:focus-within {
    border-color: var(--color-accent);
    outline: 3px solid var(--color-focus);
    outline-offset: 1px;
}
.site-search__icon { color: var(--color-muted); }
.site-search__input {
    flex: 1 1 auto;
    min-inline-size: 0;
    /* fill the field, so the thing that is tappable is the thing that
       looks tappable — it measured 23px inside a 44px field */
    align-self: stretch;
    min-block-size: var(--tap-min);
    border: 0; background: transparent;
    color: var(--color-text);
    font: inherit;
    font-size: var(--text-sm);
    padding-block: 0;
    text-align: start;
}
.site-search__input:focus { outline: none; }   /* the field owns the ring */
.site-search__input::placeholder { color: var(--color-muted); opacity: 1; }
.site-search__submit {
    border: 0; background: transparent; cursor: pointer;
    color: var(--color-accent);
    font: inherit; font-weight: 700; font-size: var(--text-sm);
    min-block-size: var(--tap-min);
    min-inline-size: var(--tap-min);
    padding-inline: var(--space-2);
    border-radius: var(--radius-sm);
}

/* ---- account area ------------------------------------------------------
   PLACEHOLDERS. Nothing here talks to the player API; see the markup. */
.account { display: flex; align-items: center; gap: var(--space-2); }
.account__btn {
    display: none;                               /* desktop/tablet only */
    align-items: center;
    gap: var(--space-2);
    min-block-size: var(--tap-min);
    padding-inline: var(--space-3);
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit; font-size: var(--text-sm); font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}
.account__btn--primary {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-accent-ink);
}
.account__btn:hover { filter: brightness(.96); }

/* icon-only controls: still a full tap target, and still labelled */
.icon-btn {
    display: inline-grid;
    place-items: center;
    min-inline-size: var(--tap-min);
    min-block-size: var(--tap-min);
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
}
.icon-btn:hover { background: var(--color-surface-2); }
.icon-btn .i { inline-size: 20px; block-size: 20px; }

/* =======================================================================
   MOBILE MENU
   ======================================================================= */

.menu-toggle { display: inline-grid; }        /* shown below the tablet bp */

.menu-overlay {
    position: fixed;
    inset: 0;
    background: var(--color-overlay);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--speed) ease, visibility var(--speed) ease;
    z-index: 50;
}
.menu-panel {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;               /* opens from the reading edge */
    inline-size: min(320px, 86vw);
    background: var(--color-surface);
    border-inline-end: 1px solid var(--color-border);
    box-shadow: var(--shadow-2);
    z-index: 60;
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    transform: translateX(-100%);
    transition: transform var(--speed) ease;
    overflow-y: auto;
}
/* EXCEPTION 1 — translateX is inherently physical: there is no
   translate-inline. In RTL the panel is anchored to the right edge by
   inset-inline-start, so it must slide the other way. This single rule is
   the only direction-aware declaration in the file, and it is a transform,
   not layout. */
[dir="rtl"] .menu-panel { transform: translateX(100%); }

.menu-panel[data-open="true"] { transform: translateX(0); }
.menu-overlay[data-open="true"] { opacity: 1; visibility: visible; }

/*
 * CS-RELEASE-01.4 — THE CLOSED DRAWER MUST NOT WIDEN THE PAGE.
 *
 * The panel is position:fixed and parked off-canvas with translateX(100%).
 * A fixed element pushed past the edge still contributes to the viewport's
 * scrollable overflow in Chromium: on the real CMS game page at 360px,
 * #site-menu sat at left:360 with a 310px box and the document measured
 * 390px wide, so the whole page scrolled sideways. It only showed at 360
 * because that is the one width where the drawer's 86vw fallback lands
 * outside the viewport.
 *
 * `overflow-x: clip` removes the overflow without creating a scroll
 * container, so position:fixed still resolves against the viewport and the
 * drawer still slides in. `hidden` is the older spelling and goes first for
 * engines without `clip`.
 */
html,
body { overflow-x: hidden; overflow-x: clip; }

.menu-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding-block-end: var(--space-3);
    border-block-end: 1px solid var(--color-border);
    margin-block-end: var(--space-2);
}
.menu-panel__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }
.menu-panel__link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-block-size: var(--tap-min);
    padding-inline: var(--space-3);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--color-text);
    font-weight: 600;
}
.menu-panel__link:hover { background: var(--color-surface-2); }
.menu-panel__link .i-chevron-wrap { margin-inline-start: auto; color: var(--color-muted); }

.menu-panel__account {
    margin-block-start: auto;
    padding-block-start: var(--space-4);
    border-block-start: 1px solid var(--color-border);
    display: grid;
    gap: var(--space-2);
}
.menu-panel__account .account__btn { display: flex; justify-content: center; }

/* A note the reader can see, so nobody mistakes a placeholder for a
   feature. Removed when the account area is really wired. */
.placeholder-note {
    font-size: var(--text-xs);
    color: var(--color-muted);
    background: var(--color-surface-2);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
    text-align: start;
}

body[data-menu-open="true"] { overflow: hidden; }

/* =======================================================================
   MAIN + FOOTER
   ======================================================================= */

.site-main { min-block-size: 50vh; padding-block: var(--space-5); }

.site-footer {
    background: var(--color-surface);
    border-block-start: 1px solid var(--color-border);
    margin-block-start: var(--space-6);
    padding-block: var(--space-5);
}
.site-footer__grid {
    display: grid;
    gap: var(--space-5);
    grid-template-columns: 1fr;
}
/* A GRID ITEM DEFAULTS TO min-width:auto, WHICH IS min-content, NOT ZERO.
   The first footer item holds the brand and the legal line; at 360px its
   min-content width is 374px, so the column refused to shrink and the item
   sat 30px past the reading edge. It never showed as a scrollbar because
   html,body carry overflow-x: clip for the off-canvas drawer — the content
   was being quietly cut off instead.

   Letting the items shrink below min-content is the standard correction and
   is all that is needed: the text then wraps as it already does at 390px.
   Logical property, so RTL is unaffected. */
.site-footer__grid > * { min-inline-size: 0; }
.site-footer__nav { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }
.site-footer__link {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--tap-min);
    padding-inline: var(--space-2);
    border-radius: var(--radius-sm);
    color: var(--color-muted);
    text-decoration: none;
    font-size: var(--text-sm);
}
.site-footer__link:hover { color: var(--color-text); background: var(--color-surface-2); }
.site-footer__legal { color: var(--color-muted); font-size: var(--text-sm); }

/* =======================================================================
   BREAKPOINTS

   Three states, not two. The audit called 768–1023 out as a middle state
   the old theme handled by stretching the desktop layout.

   phone   <768   drawer menu, search fills the bar, no inline nav
   tablet  768–1023  nav becomes a compact icon+label row, account
                     collapses to a single icon button, drawer is gone
   desktop ≥1024  full nav labels, both account buttons in text
   ======================================================================= */

@media (min-width: 768px) {
    :root { --header-height: 64px; }

    .menu-toggle { display: none; }
    .menu-panel, .menu-overlay { display: none; }   /* no drawer on tablet */

    .site-nav { display: block; }
    .site-nav__link { padding-inline: var(--space-2); font-size: var(--text-xs); }
    /* Tablet shows the icon and the label, but tightly. It is its own
       layout, not a squeezed desktop. */
    .site-search { flex: 0 1 260px; order: 0; }
    .account__btn { display: inline-flex; }
    .account__btn--secondary { display: none; }     /* one action, not two */

    .site-footer__grid { grid-template-columns: 1fr 1fr; }
    .site-footer__nav { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 1024px) {
    :root { --header-height: 68px; }

    .site-nav__link { padding-inline: var(--space-3); font-size: var(--text-sm); }
    .site-search { flex: 0 1 380px; }
    .account__btn--secondary { display: inline-flex; }

    .site-footer__grid { grid-template-columns: 1.2fr 2fr; }
}

/* Respect a reader who asked for less motion. */
@media (prefers-reduced-motion: reduce) {
    .menu-panel, .menu-overlay { transition: none; }
}
