/* ==========================================================================
   /getting-started — "The Index"
   --------------------------------------------------------------------------
   An editorial/archive treatment for the anonymous visitor's tour of the
   product. The page argues from the depth of the catalogue, so the figures
   are set as evidence and everything around them is kept quiet.

   Rules this file follows, each with a defect behind it:

   - Every class is prefixed `.gs-`, INCLUDING states (`.gs-is-active`, not
     `.gs-active`). Single-word state classes in a page stylesheet are the
     exact latent shape of the modal.css collision (CLAUDE.md #31).
   - No global `* { margin: 0 }` reset. The previous inline block carried one,
     which leaked out of the page and stripped margins from the shared nav,
     footer, FAB and any Modal/Toast mounted here.
   - No `:root` declarations. `desktop-navigation.ftlh` re-links
     design-tokens.css inside <body>, so a page-level `:root` override is
     dead on arrival (CLAUDE.md #74). Locals are scoped to `.gs-page`.
   - No `nth-child`-keyed accents. Inserting or reordering a step silently
     recoloured everything after it; accent is an explicit class instead.
   - Hero spacing derives from `--chrome-bottom`, which the nav measures at
     runtime (CLAUDE.md #85). Never a hardcoded nav height.
   - One property per line, always (project convention).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Local scale
   Scoped to the page root so nothing here can escape into shared chrome.
   -------------------------------------------------------------------------- */

/* ⚠ The body rule is NOT optional and NOT boilerplate. No shared stylesheet in
   this project sets a body background — every page has always set its own, and
   the page this replaced did it inside the same inline <style> that carried the
   `* { margin: 0 }` reset. Deleting that block wholesale removed the reset
   (correct) and this rule with it (not), so `body` fell back to WHITE and only
   <main> painted dark: a white surround behind a dark page. The lesson is
   CLAUDE.md #82 — a wholesale removal takes its neighbours, and verifying the
   thing you changed does not verify the thing you deleted. */
body {
    background: var(--bg);
    color: var(--text-secondary);
    font-family: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
    line-height: var(--leading-relaxed);
    margin: 0;
}

.gs-page {
    /* The one accent. Blue is the default voice of the page; the community
       act overrides this single property and everything downstream follows. */
    --gs-accent: var(--brand-blue);
    --gs-accent-soft: rgba(52, 152, 219, 0.14);

    /* ⚠ ONE FACE. Poppins carries every word on this page — headings, labels,
       figures, metadata, the lot. There was a serif (Instrument Serif, on the
       big figures) and a mono (on 18 label and count classes); both are gone
       as of 2026-09-09, owner decision. Hierarchy is now carried entirely by
       weight, size, tracking and colour, which is what the rest of the site
       does. Do not reintroduce a second face here: the page sits directly
       under the Poppins nav, and any rival title face reads as two products
       stitched together — which is the exact reason the serif was demoted
       once already before being removed. */

    /* Rhythm. Deliberately few values — a page like this wants a small,
       repeating vertical scale, not a bespoke gap per section. */
    --gs-gap: clamp(1rem, 2.5vw, 1.75rem);
    --gs-section-gap: clamp(3.5rem, 9vw, 7rem);
    --gs-rail-width: 232px;
    --gs-measure: 68ch;

    /* Hairlines carry the structure in place of boxes and shadows. */
    --gs-rule: 1px solid var(--border-subtle);
    --gs-rule-strong: 1px solid var(--border);

    /* Full-bleed with the project's standard 15px gutter. There is no centred
       max-width column: the page uses the screen it is given. */
    --gs-pad: var(--container-pad, 15px);

    color: var(--text-secondary);
    background: var(--bg);
    font-family: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* A page-level horizontal-overflow guard that does NOT create a scroll
   container. `overflow-x: hidden` would make this element the scrollport for
   every descendant, silently killing the sticky rail below and any
   scroll-driven animation (CLAUDE.md #40). `clip` clips identically without
   that side effect. */
.gs-page {
    overflow-x: clip;
}

/* --------------------------------------------------------------------------
   2. Shared type primitives
   -------------------------------------------------------------------------- */

/* Available to assistive technology, absent from the visual design.
   Namespaced deliberately: `.sr-only` and `.visually-hidden` are used across
   this codebase but defined in NO stylesheet — they came from Bootstrap, which
   this page no longer loads, so text marked with them is simply visible. */
.gs-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.gs-kicker {
    display: block;
    font-size: 0.72rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-dim);
}

/* Headings are Poppins, the house voice. Presence comes from weight, a tight
   line-height and negative tracking at display size — not from a second face. */
.gs-display {
    font-family: inherit;
    font-weight: var(--weight-semibold);
    line-height: 1.08;
    letter-spacing: -0.025em;
    color: var(--text);
}

.gs-lede {
    max-width: var(--gs-measure);
    font-size: clamp(1rem, 1.6vw, 1.125rem);
    line-height: 1.65;
    color: var(--text-secondary);
}

/* A figure and its label. The figure is the loudest thing on the page and is
   allowed to be, because nothing else competes. */
/* A small heading introducing a block inside a step (the genre chart, the
   poster strip). Carries its own spacing so the markup does not need inline
   styles to place it. */
.gs-subhead {
    margin: 2.5rem 0 0;
}

.gs-figure {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

/* The loudest thing on the page, and allowed to be, because nothing else
   competes. It used to carry the serif; on Poppins it needs weight and tight
   negative tracking to hold the same authority at display size, the same way
   .gs-display does. tabular-nums keeps multi-digit figures on a column. */
.gs-figure__value {
    font-size: clamp(2.4rem, 5.5vw, 3.75rem);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.03em;
    line-height: var(--leading-none);
    font-variant-numeric: tabular-nums;
    color: var(--gs-accent);
}

.gs-figure__label {
    font-size: 0.7rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-dim);
}

/* --------------------------------------------------------------------------
   3. Hero
   -------------------------------------------------------------------------- */

.gs-hero {
    position: relative;
    /* The nav is fixed and takes no space in flow, so the page clears it
       itself. `--chrome-bottom` is published by desktop-navigation.ftlh from a
       live measurement; the addend is this page's own intended gap and stays
       readable as such. */
    padding-top: calc(var(--chrome-bottom, 80px) + clamp(1.5rem, 4vw, 3rem));
    padding-bottom: clamp(2.5rem, 7vw, 4.5rem);
    padding-inline: var(--gs-pad);
    border-bottom: var(--gs-rule);
    /* Full-bleed art lives inside; clip rather than hidden so no scroll
       container is created for the sticky rail further down (#40). */
    overflow: clip;
    isolation: isolate;
    text-align: center;
}

/* Atmosphere. A brand-tinted glow behind the headline, in the radial-gradient
   idiom the rest of the app uses to lift a hero off pure black. */
.gs-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(80% 60% at 50% 34%, rgba(52, 152, 219, 0.16), transparent 70%),
        radial-gradient(60% 50% at 78% 12%, rgba(155, 89, 182, 0.13), transparent 70%);
    pointer-events: none;
}

.gs-hero__inner {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.gs-hero__title {
    margin: 0.9rem 0 0;
    font-size: clamp(2.6rem, 8vw, 6rem);
}

/* --- The monogram window -------------------------------------------------
   The MitsuHub mark, with the catalogue moving inside its letterforms: real
   covers are clipped to the glyph and drift continuously, so the identity and
   the thing it stands for are one object rather than a logo pinned above a
   headline. The stroke is the brand gradient, which is the only place the two
   brand colours appear together above the fold. */

/* A BACKDROP, not a badge. The mark is drawn enormous and sits behind the
   headline with the catalogue moving inside its letterforms, so the identity is
   the room the copy stands in rather than a logo stacked above it. Low contrast
   on purpose: it must never compete with the text it sits under. */
/* The mark and the headline share this box, so the backdrop is anchored to the
   TEXT and not to a percentage of a column whose height changes with how much
   the lede wraps. That percentage is what made the mark drift off the headline
   as the screen narrowed. */
.gs-hero__head-wrap {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
}

/* The kicker and headline themselves. Positioned so they reliably paint above
   the negative-z backdrop sharing their box. */
.gs-hero__head {
    position: relative;
    width: 100%;
}

.gs-monogram {
    position: absolute;
    /* Centred on the headline box above — a fixed relationship at every width. */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* Sized so the mark stays READABLE as MH. At 1500px the glyph spanned the
       whole hero and its strokes stopped reading as letterforms at all — the
       rain then looked like a full-screen text field that happened to have
       edges, rather than words falling inside a logo. Big enough to be a
       backdrop, small enough to still be the mark. */
    width: min(780px, 80%);
    z-index: -1;
    line-height: 0;
    opacity: 0.42;
    pointer-events: none;
    /* Dissolves at the edges rather than ending on a hard line. */
    -webkit-mask-image: radial-gradient(68% 64% at 50% 50%, #000 30%, transparent 76%);
    mask-image: radial-gradient(68% 64% at 50% 50%, #000 30%, transparent 76%);
}

.gs-monogram__svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

/* HOLLOW. The mark is an outline, so the word rain behind it reads through the
   counters and the glyph frames the motion instead of hiding it. A filled glyph
   would make the letterforms the subject; hollow makes them a window. */
.gs-monogram__glyph {
    fill: none;
    stroke: url(#gsMonogramEdge);
    stroke-width: 2;
    stroke-linejoin: round;
}

/* Each column falls exactly 200 user units — one viewBox height — while holding
   its eight words twice over 400 units, so the frame it lands on is identical
   to the one it left and the loop has no seam. */
.gs-monogram__col {
    animation-name: gsWordFall;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

/* USER UNITS, not pixels — the viewBox is 320 wide and renders at ~780px, so
   everything here is scaled ~2.4x and 3.6 units lands near 9px on screen.
   Small is the point: these are falling glyphs, and anything large enough to
   read as a word competes with the headline sitting on top of them. */
.gs-monogram__word {
    font-size: 0.225rem;
    letter-spacing: 0;
    fill: var(--brand-blue);
    text-transform: lowercase;
    text-anchor: middle;
}

/* Every third column takes the purple, so the rain carries both brand hues
   without either dominating. */
.gs-monogram__col:nth-child(3n) .gs-monogram__word {
    fill: var(--brand-purple);
}

/* A ticker glitch on roughly one glyph in seven. `steps(1, end)` is what makes
   it read as a dropout rather than a pulse — the value snaps instead of easing,
   so the character blinks out and back the way a bad panel would. Only opacity
   is animated, so each column keeps its own hue. */
.gs-monogram__tick {
    animation: gsGlyphTick 5.5s steps(1, end) infinite;
}

@keyframes gsGlyphTick {
    0%, 38%   { opacity: 1; }
    39%       { opacity: 0.1; }
    41%       { opacity: 1; }
    42%       { opacity: 0.45; }
    44%, 73%  { opacity: 1; }
    74%       { opacity: 0.08; }
    76%       { opacity: 0.6; }
    77%, 100% { opacity: 1; }
}

@keyframes gsWordFall {
    from { transform: translateY(-200px); }
    to   { transform: translateY(0); }
}

/* Motion that runs on its own clock stops when asked. The glyph and its words
   stay — only the falling stops. */
@media (prefers-reduced-motion: reduce) {
    .gs-monogram__col,
    .gs-monogram__tick {
        animation: none;
    }
}

/* --- The ribbons: real covers, drifting in opposite directions ------------
   Anime one way, manga the other, so the two halves of the catalogue are
   present at a glance rather than one standing in for both. Decorative, so the
   markup is aria-hidden and the images carry empty alt. */

.gs-ribbon {
    position: relative;
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    /* clip, not hidden: the track is deliberately wider than the viewport and
       must not become a horizontal scrollport. */
    overflow: clip;
    /* Fade both ends so the strip dissolves rather than being cut off. */
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
    opacity: 0.42;
}

.gs-ribbon--top {
    margin-bottom: clamp(1.5rem, 4vw, 2.75rem);
}

.gs-ribbon--bottom {
    margin-top: clamp(1.75rem, 4.5vw, 3rem);
}

/* Two identical halves sit side by side and the track translates by exactly
   -50%, so the loop closes on itself with no visible seam. */
.gs-ribbon__track {
    display: flex;
    width: max-content;
    gap: 10px;
    animation: gsDriftLeft 90s linear infinite;
}

.gs-ribbon--bottom .gs-ribbon__track {
    animation-name: gsDriftRight;
    animation-duration: 105s;
}

.gs-ribbon__half {
    display: flex;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.gs-ribbon__art {
    display: block;
    width: 92px;
    height: 130px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    /* Desaturated so the covers read as texture behind the headline rather
       than as twelve competing focal points. */
    filter: saturate(0.65) contrast(0.95);
}

@keyframes gsDriftLeft {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}

@keyframes gsDriftRight {
    from { transform: translate3d(-50%, 0, 0); }
    to   { transform: translate3d(0, 0, 0); }
}

/* The one place the brand gradient appears above the fold. `background-clip`
   text has no meaning in forced-colors mode, so the fallback below restores a
   solid colour rather than letting the headline vanish. */
.gs-hero__accent {
    background: var(--brand-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.gs-hero__lede {
    margin: 1.25rem auto 0;
    font-size: clamp(1.05rem, 2vw, 1.3rem);
}

/* --------------------------------------------------------------------------
   4. The search hero — the page's signature
   Real queries against the real catalogue, with no account. Every result is
   a live row; nothing here is illustrative.
   -------------------------------------------------------------------------- */

.gs-search {
    width: 100%;
    max-width: 720px;
    margin: clamp(1.75rem, 4vw, 2.75rem) auto 0;
    text-align: left;
}

.gs-search__form {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 1.1rem;
    background: var(--glass-bg);
    border: var(--gs-rule-strong);
    border-radius: var(--radius-md);
    transition: border-color var(--dur-base) ease, background var(--dur-base) ease;
}

.gs-search__form:focus-within {
    border-color: var(--gs-accent);
}

.gs-search__icon {
    flex-shrink: 0;
    color: var(--text-dim);
}

.gs-search__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
    font-family: inherit;
    font-size: 1.05rem;
    color: var(--text);
    background: transparent;
    border: 0;
    outline: none;
}

.gs-search__input::placeholder {
    color: var(--text-dim);
}

/* Present only for the no-JS path and for keyboard submit. Visually quiet,
   never display:none — it is the fallback that keeps the control honest. */
.gs-search__submit {
    flex-shrink: 0;
    padding: 0.4rem 0.85rem;
    font-size: 0.7rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    background: var(--glass-bg);
    border: var(--gs-rule);
    border-radius: var(--radius-xs);
    cursor: pointer;
    transition: color var(--dur-base) ease, border-color var(--dur-base) ease;
}

.gs-search__submit:hover,
.gs-search__submit:focus-visible {
    color: var(--text);
    border-color: var(--gs-accent);
}

.gs-search__status {
    margin-top: 0.75rem;
    font-size: 0.72rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
    min-height: 1rem;
}

.gs-search__results {
    margin: 0.75rem 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 2px;
}

.gs-result {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.6rem 0.75rem;
    color: inherit;
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: background var(--dur-fast) ease;
}

.gs-result:hover,
.gs-result:focus-visible {
    background: var(--surface-hover);
}

.gs-result__art {
    flex-shrink: 0;
    width: 40px;
    height: 56px;
    object-fit: cover;
    background: var(--surface-3);
    border-radius: var(--radius-xs);
}

.gs-result__body {
    min-width: 0;
}

.gs-result__name {
    display: block;
    font-weight: var(--weight-medium);
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-result__meta {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.72rem;
    color: var(--text-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-result__type {
    flex-shrink: 0;
    margin-left: auto;
    padding: 0.2rem 0.5rem;
    font-size: 0.62rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
    border: var(--gs-rule);
    border-radius: var(--radius-pill);
}

/* The counts caption under the search box. This is the claim the search box
   immediately proves, so the two sit together. */
.gs-census {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.4rem 1.25rem;
    margin: 1.75rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.gs-census__value {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   5. Body layout — sticky rail + one variable content column
   The previous page paired every step with a decorative column, which is what
   forced eight fabricated UIs into existence. One column that changes width
   removes the pressure to invent a visual per step.
   -------------------------------------------------------------------------- */

.gs-body {
    display: grid;
    grid-template-columns: var(--gs-rail-width) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4.5rem);
    padding-inline: var(--gs-pad);
    padding-block: clamp(2.5rem, 6vw, 4.5rem);
}

/* A grid item defaults to `min-width: auto`, which refuses to shrink below its
   content and lets the poster row push the whole column wide. */
.gs-steps {
    min-width: 0;
}

/* --- The rail ---------------------------------------------------------- */

.gs-rail {
    position: sticky;
    /* Clears the measured nav, exactly like the hero. */
    top: calc(var(--chrome-bottom, 80px) + 1.5rem);
    align-self: start;
    max-height: calc(100vh - var(--chrome-bottom, 80px) - 3rem);
    overflow-y: auto;
    overscroll-behavior: contain;
}

.gs-rail__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.gs-rail__act {
    margin: 1.5rem 0 0.6rem;
    padding-top: 0.75rem;
    border-top: var(--gs-rule);
    font-size: 0.65rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.gs-rail__act:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* A real anchor: focusable, keyboard-operable, and carrying aria-current.
   The page this replaces used <div>s with click handlers — its clearest
   accessibility defect. */
.gs-rail__link {
    display: flex;
    align-items: baseline;
    gap: 0.65rem;
    padding: 0.4rem 0.5rem 0.4rem 0;
    font-size: 0.9rem;
    color: var(--text-muted);
    text-decoration: none;
    border-left: 2px solid transparent;
    padding-left: 0.75rem;
    transition: color var(--dur-base) ease, border-color var(--dur-base) ease;
}

.gs-rail__link:hover,
.gs-rail__link:focus-visible {
    color: var(--text);
}

.gs-rail__link[aria-current="true"] {
    color: var(--text);
    border-left-color: var(--gs-accent);
}

.gs-rail__num {
    font-size: 0.7rem;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}

.gs-rail__link[aria-current="true"] .gs-rail__num {
    color: var(--gs-accent);
}

/* --- Steps -------------------------------------------------------------- */

.gs-step {
    padding-block: 0 var(--gs-section-gap);
    scroll-margin-top: calc(var(--chrome-bottom, 80px) + 1.5rem);
}

.gs-step__head {
    padding-bottom: 1.25rem;
    border-bottom: var(--gs-rule);
}

.gs-step__title {
    margin: 0.6rem 0 0;
    font-size: clamp(1.9rem, 4.2vw, 3rem);
}

.gs-step__lede {
    margin: 1.1rem 0 0;
}

/* The accent override. A class, not a position — reordering the steps can
   never recolour the wrong one. */
.gs-act-commons {
    --gs-accent: var(--brand-purple);
    --gs-accent-soft: rgba(155, 89, 182, 0.14);
}

/* --- Highlight bullets --------------------------------------------------- */

.gs-points {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
    gap: 1.5rem 2.5rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.gs-point {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.9rem;
    align-items: start;
}

.gs-point__icon {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    font-size: 0.8rem;
    color: var(--gs-accent);
    background: var(--gs-accent-soft);
    border-radius: var(--radius-xs);
}

.gs-point__title {
    display: block;
    margin: 0 0 0.2rem;
    font-size: 0.95rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
}

.gs-point__text {
    display: block;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
}

/* --- Figure bands -------------------------------------------------------- */

.gs-band {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 1.75rem 2rem;
    margin: 2.25rem 0 0;
    padding: 1.75rem 0 0;
    border-top: var(--gs-rule);
}

.gs-band__note {
    margin: 1rem 0 0;
    font-size: 0.82rem;
    color: var(--text-dim);
}

/* --- Genre chart --------------------------------------------------------- */

/* Bounded on purpose, while the page around it runs full-bleed. A bar chart is
   read by COMPARING lengths, and at 1400px the bars became long thin rules with
   the label and the figure marooned at opposite ends of the screen — the eye
   cannot hold both. Roughly 60rem keeps a genre, its bar and its count in one
   glance. Full-bleed is right for art and wrong for data. */
.gs-genres {
    max-width: 60rem;
    margin: 2.25rem 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.7rem;
}

.gs-genre {
    display: grid;
    grid-template-columns: minmax(0, 7.5rem) minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.9rem;
    font-size: 0.85rem;
}

.gs-genre__name {
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-genre__track {
    height: 6px;
    background: var(--surface-2);
    border-radius: var(--radius-xxs);
    overflow: hidden;
}

/* The width is set inline from a server-derived percentage, never authored
   next to the number. The chart this replaces printed 34/25/19/12/10 over
   bars drawn at 85/62/48/30/25 — it disagreed with its own labels. */
.gs-genre__bar {
    display: block;
    height: 100%;
    /* The one source of truth for this bar's length, set from the server and
       derived from the count printed beside it. */
    width: var(--gs-bar-width, 0);
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--gs-accent) 65%, transparent),
        var(--gs-accent));
    border-radius: inherit;
}

.gs-genre__count {
    font-size: 0.78rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* --- Poster evidence strip ----------------------------------------------- */

/* A labelled strip of real covers. One per medium, so anime never stands in
   for the whole catalogue. */
.gs-shelf {
    margin-top: 2rem;
}

.gs-shelf__label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.85rem;
    font-size: 0.66rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-dim);
}

/* A hairline that runs out to the end of the row, so the label reads as a
   rule rather than as floating text. */
.gs-shelf__label::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--border-subtle);
}

.gs-exhibits {
    display: flex;
    gap: 0.85rem;
    margin: 0;
    padding: 0 0 0.5rem;
    list-style: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.gs-exhibits::-webkit-scrollbar {
    display: none;
}

/* The <li> is the flex item, not the anchor inside it. `flex-shrink: 0` was on
   the anchor, where it does nothing at all — the item that could squash was
   never the one carrying the guard. */
.gs-exhibits > li {
    flex-shrink: 0;
    width: 116px;
    scroll-snap-align: start;
}

/* ⚠ `display: block` is what makes the width real. An <a> is an inline box and
   ignores width outright, so the card sized itself to its longest caption
   instead of to 116px — which is why `text-overflow: ellipsis` on the title
   never fired: nothing was ever overflowing. The truncation rule was correct
   and had nothing to truncate. Second instance of this exact trap on this page,
   after .gs-pair__faces. */
.gs-exhibit {
    display: block;
    width: 116px;
    text-decoration: none;
    color: inherit;
}

.gs-exhibit__art {
    display: block;
    width: 116px;
    height: 164px;
    object-fit: cover;
    background: var(--surface-2);
    border: var(--gs-rule);
    border-radius: var(--radius-sm);
    transition: border-color 0.25s ease,
                transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
                box-shadow 0.35s ease;
}

.gs-exhibit:hover .gs-exhibit__art,
.gs-exhibit:focus-visible .gs-exhibit__art {
    border-color: var(--gs-accent);
    transform: translateY(-5px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.55);
}

/* One line, always. Two-line captions made the shelf ragged because every
   title wrapped at a different point, and the row's baseline moved with it.
   A single clipped line keeps the covers on a common rule. */
.gs-exhibit__name {
    display: block;
    margin-top: 0.5rem;
    font-size: 0.76rem;
    line-height: 1.35;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gs-exhibit__score {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.72rem;
    color: var(--gs-accent);
    font-variant-numeric: tabular-nums;
}

/* --- The cast wall -------------------------------------------------------
   A character and the actor who voices them, as two overlapping portraits.
   Either face on its own is just an avatar; the pair is the whole claim of
   the section, so they are drawn as one object that cannot be read apart. */

.gs-cast {
    display: flex;
    gap: 1.5rem;
    margin: 2rem 0 0;
    padding: 0 0 0.75rem;
    list-style: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.gs-cast::-webkit-scrollbar {
    display: none;
}

.gs-pair {
    flex-shrink: 0;
    width: 168px;
    scroll-snap-align: start;
}

/* ⚠ `display: block` is load-bearing. This is an <a>, and an inline box ignores
   width and height outright — the element computed to 0x0, the absolutely
   positioned portraits inside it escaped, and the section collapsed into the
   text beneath it. The geometry looked correct in the stylesheet the whole
   time. */
.gs-pair__faces {
    display: block;
    position: relative;
    width: 168px;
    height: 116px;
}

.gs-pair__face {
    position: absolute;
    border-radius: var(--radius-circle);
    object-fit: cover;
    background: var(--surface-2);
    /* ⚠ This declaration was CORRUPT and it cost the page ~40% of its CSS.
       Some scripted edit comma-split the value and sorted the fragments, which
       left an unclosed `cubic-bezier(` — and an unclosed paren in CSS swallows
       the closing brace and every rule that follows. Chrome parsed 102 rules
       out of ~208 and silently dropped the company wall, the curated lists,
       the index, the exit CTA and all but one media query. Braces balanced,
       comment markers balanced, every parse/contract test green (CLAUDE.md
       #82). Only counting `document.styleSheets[n].cssRules` found it.
       If you script an edit over this file, re-count the parsed rules after. */
    transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
                filter 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* The character leads: larger, in front, on the left. */
.gs-pair__face--character {
    left: 0;
    top: 0;
    width: 100px;
    height: 100px;
    z-index: 2;
    border: 2px solid var(--gs-accent);
}

/* The actor sits behind and to the right, half-tucked under the character —
   the overlap is what makes the two read as a single fact. */
.gs-pair__face--actor {
    right: 0;
    top: 16px;
    width: 84px;
    height: 84px;
    z-index: 1;
    border: 2px solid var(--border);
    filter: saturate(0.8);
}

/* On hover the pair separates slightly, which is the whole gesture: two people,
   one role. */
.gs-pair:hover .gs-pair__face--character,
.gs-pair:focus-within .gs-pair__face--character {
    transform: translateX(-5px);
}

.gs-pair:hover .gs-pair__face--actor,
.gs-pair:focus-within .gs-pair__face--actor {
    transform: translateX(5px);
    filter: saturate(1);
}

.gs-pair__name {
    display: block;
    margin-top: 0.7rem;
    font-size: 0.88rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* One line, like the character name above it. A wrapped actor name pushed the
   series caption down on that card alone and broke the row's shared baseline. */
.gs-pair__actor {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gs-pair__source {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Music tiles ---------------------------------------------------------
   Each thumbnail is lit by the accent colour extracted from its own artwork.
   That extraction is a thing this product does, so the tiles are built to make
   it the point rather than to show eight rectangles. */

.gs-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 1rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.gs-tile {
    position: relative;
    display: block;
    padding: 0.6rem 0.6rem 0.85rem;
    color: inherit;
    text-decoration: none;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-subtle);
    /* The accent arrives from the server as --gs-tile-accent, validated to a
       strict #rrggbb before it ever reaches the markup. */
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--gs-tile-accent, var(--brand-blue)) 16%, transparent),
            transparent 65%),
        var(--surface-1);
    transition: transform var(--dur-slow) cubic-bezier(0.34, 1.56, 0.64, 1),
                border-color var(--dur-slow) ease,
                box-shadow var(--dur-slow) ease;
}

.gs-tile:hover,
.gs-tile:focus-visible {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--gs-tile-accent, var(--brand-blue)) 55%, transparent);
    box-shadow: 0 12px 32px -8px color-mix(in srgb, var(--gs-tile-accent, var(--brand-blue)) 45%, transparent);
}

.gs-tile__art {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--radius-xs);
    background: var(--surface-2);
}

/* The extracted colour, stated plainly as a swatch rule under the artwork. */
.gs-tile__accent {
    display: block;
    height: 3px;
    margin: 0.55rem 0 0.6rem;
    border-radius: var(--radius-xxs);
    background: var(--gs-tile-accent, var(--brand-blue));
}

.gs-tile__title {
    display: block;
    font-size: 0.86rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-tile__artist {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.76rem;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Company wall ---------------------------------------------------------
   Company logos arrive as square marks on assorted backgrounds, so they are
   dropped into a uniform dark plate rather than shown raw — otherwise the row
   becomes a patchwork of white boxes. */

.gs-companies {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 0.85rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.gs-company {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.45rem;
    padding: 1rem 0.75rem 0.85rem;
    text-align: center;
    text-decoration: none;
    color: inherit;
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1),
                border-color 0.28s ease;
}

.gs-company:hover,
.gs-company:focus-visible {
    transform: translateY(-3px);
    border-color: var(--gs-accent);
}

/* Logos are wordmarks on white as often as not. Desaturated and dimmed at rest
   so the row reads as one material, restored on hover. */
.gs-company__mark {
    width: 54px;
    height: 54px;
    object-fit: contain;
    border-radius: var(--radius-xs);
    filter: grayscale(1) brightness(1.6) contrast(0.85);
    opacity: 0.75;
    transition: filter 0.28s ease, opacity 0.28s ease;
}

.gs-company:hover .gs-company__mark,
.gs-company:focus-visible .gs-company__mark {
    filter: none;
    opacity: 1;
}

.gs-company__name {
    font-size: 0.8rem;
    font-weight: var(--weight-semibold);
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.gs-company__count {
    font-size: 0.66rem;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}

/* --- Curated lists -------------------------------------------------------
   Real public watchlists. A cover beside its title, so the row shows what a
   list IS rather than describing one. */

.gs-lists {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 0.75rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.gs-list {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.6rem;
    text-decoration: none;
    color: inherit;
    background: var(--surface-1);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    transition: background 0.25s ease, border-color 0.25s ease;
}

.gs-list:hover,
.gs-list:focus-visible {
    background: var(--surface-2);
    border-color: var(--gs-accent);
}

.gs-list__cover {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
}

/* min-width: 0 is what lets the ellipsis below actually engage — a flex item
   refuses to shrink past its content otherwise. */
.gs-list__body {
    min-width: 0;
}

.gs-list__title {
    display: block;
    font-size: 0.9rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-list__by {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.7rem;
    color: var(--text-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   6. The index — a dense directory of everything the steps do not cover
   Honest about the size of the product without pretending each item deserves
   a section of its own.
   -------------------------------------------------------------------------- */

.gs-index {
    padding-inline: var(--gs-pad);
    padding-block: clamp(3rem, 7vw, 5rem);
    border-top: var(--gs-rule);
}

.gs-index__title {
    margin: 0.75rem 0 0;
    font-size: clamp(1.75rem, 4vw, 2.5rem);
}

.gs-index__lede {
    margin-top: 1rem;
}

.gs-index__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 2.25rem 2.5rem;
    margin-top: 2.5rem;
}

.gs-index__heading {
    margin: 0 0 0.9rem;
    padding-bottom: 0.6rem;
    border-bottom: var(--gs-rule);
    font-size: 0.68rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.gs-index__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.15rem;
}

.gs-index__link {
    display: block;
    padding: 0.3rem 0;
    font-size: 0.88rem;
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--dur-fast) ease;
}

.gs-index__link:hover,
.gs-index__link:focus-visible {
    color: var(--gs-accent);
}

/* --------------------------------------------------------------------------
   7. Close-out — hand off to the Gateway
   -------------------------------------------------------------------------- */

/* Centred by design. After a long left-aligned scroll the page needs to
   resolve on axis — the close is the one moment that addresses the reader
   head-on rather than continuing the column. */
.gs-close {
    padding-inline: var(--gs-pad);
    padding-block: clamp(4rem, 10vw, 7rem);
    border-top: var(--gs-rule);
    text-align: center;
}

.gs-close__title {
    margin: 0.9rem 0 0;
    font-size: clamp(2rem, 5.5vw, 3.5rem);
}

.gs-close__lede {
    margin: 1.25rem auto 0;
}

.gs-close__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.85rem;
    margin-top: 2.5rem;
}

/* The three exits are not buttons. A button is a control; these are
   destinations, and each deserves enough room to say what it is. They read as
   three cards on a shelf — glass over the page's own ground, a hairline, a
   label, a sentence, and an arrow that travels on hover. */
.gs-exits {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1rem;
    /* Wide enough to breathe on a large screen, bounded so the three panels do
       not stretch into billboards. The page around them is full-bleed. */
    max-width: 1020px;
    margin: 2.5rem auto 0;
    text-align: left;
}

.gs-exit {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    /* Comfortably past the 44px touch minimum in every direction. */
    min-height: 132px;
    padding: 1.35rem 1.4rem 1.25rem;
    color: inherit;
    text-decoration: none;
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur-sm, 8px));
    -webkit-backdrop-filter: blur(var(--glass-blur-sm, 8px));
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1),
                border-color 0.28s ease,
                background 0.28s ease;
}

/* A brand wash that only resolves on hover, so the resting state stays quiet. */
.gs-exit::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(52, 152, 219, 0.13), rgba(155, 89, 182, 0.13));
    opacity: 0;
    transition: opacity 0.28s ease;
    pointer-events: none;
}

.gs-exit:hover,
.gs-exit:focus-visible {
    transform: translateY(-3px);
    border-color: var(--border-strong);
    background: var(--surface-2);
}

.gs-exit:hover::before,
.gs-exit:focus-visible::before {
    opacity: 1;
}

/* The recommended exit carries the brand gradient as a top edge rather than as
   a filled button: present, but not shouting over its two siblings. */
.gs-exit--lead {
    border-color: var(--border);
}

.gs-exit--lead::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--brand-gradient);
}

.gs-exit__label {
    position: relative;
    font-size: 0.64rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.gs-exit--lead .gs-exit__label {
    color: var(--brand-blue);
}

.gs-exit__title {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 1.15rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
}

/* Darts right on hover. Transform only, so nothing around it reflows — the
   same restraint the shared `.mh-viewall` affordance uses. */
.gs-exit__arrow {
    font-size: 0.8rem;
    color: var(--gs-accent);
    transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.gs-exit:hover .gs-exit__arrow,
.gs-exit:focus-visible .gs-exit__arrow {
    transform: translateX(5px);
}

.gs-exit__text {
    position: relative;
    margin: 0;
    font-size: 0.88rem;
    line-height: var(--leading-normal);
    color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   8. Scroll reveal
   The observer ADDS a class to animate; it never removes visibility. A reveal
   that starts at opacity 0 makes the observer firing a precondition for the
   page existing at all, so a backgrounded tab or a thrown error leaves a
   fully-rendered document invisible (CLAUDE.md #58). Here the content is
   visible by default and the animation is pure enhancement.
   -------------------------------------------------------------------------- */

/* Note the `.gs-is-animated` gate: the hidden state applies ONLY once the
   script has arrived and taken responsibility for removing it again. Without
   that gate, a script that 404s, trips a CSP, or throws in an earlier
   init leaves a fully-rendered page at opacity 0 with no error anywhere — the
   reveal becomes a precondition for the page existing at all. Opting in is the
   difference between an enhancement and a single point of failure. */
@media (prefers-reduced-motion: no-preference) {
    .gs-is-animated .gs-reveal {
        opacity: 0;
        transform: translateY(22px);
        transition: opacity 0.6s ease, transform 0.7s var(--ease-out);
        /* Set per element by the observer so a group arrives as a cascade
           rather than as one block. */
        transition-delay: var(--gs-delay, 0ms);
    }

    .gs-is-animated .gs-reveal.gs-is-revealed {
        opacity: 1;
        transform: none;
    }

    /* Bars grow from nothing when their chart comes into view. The markup sets
       only `--gs-bar-width`, never `width`, so CSS owns the property outright
       and no `!important` is needed to beat an inline style. The resting value
       and the animated value are therefore the SAME server-derived number —
       the animation cannot disagree with the figure printed beside it. */
    .gs-is-animated .gs-genre__bar {
        width: 0;
        transition: width 0.9s var(--ease-out);
        transition-delay: var(--gs-delay, 0ms);
    }

    .gs-is-animated .gs-is-revealed .gs-genre__bar {
        width: var(--gs-bar-width);
    }

    /* Covers settle in as the strip arrives. */
    .gs-is-animated .gs-is-revealed .gs-exhibit {
        animation: gsRise 0.6s var(--ease-out) backwards;
        animation-delay: var(--gs-delay, 0ms);
    }

    @keyframes gsRise {
        from {
            opacity: 0;
            transform: translateY(16px) scale(0.97);
        }
    }
}

/* Motion that runs on its own clock stops entirely when asked. The ribbons are
   the only continuous animation on the page. */
@media (prefers-reduced-motion: reduce) {
    .gs-ribbon__track {
        animation: none;
    }
}

/* --------------------------------------------------------------------------
   9. Responsive. 375px is the floor, not 480.
   -------------------------------------------------------------------------- */

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

    /* The rail becomes a horizontal scroller pinned under the nav — WITH its
       labels. The page this replaces hid the labels below 900px, leaving eight
       bare numbers: permanent vertical chrome with no destinations, for the
       majority of traffic. */
    .gs-rail {
        position: sticky;
        top: var(--chrome-bottom, 80px);
        z-index: 5;
        max-height: none;
        margin-inline: calc(var(--gs-pad) * -1);
        padding: 0.6rem var(--gs-pad);
        /* Opaque fallback first: where color-mix is unsupported the whole
           declaration is dropped, and a transparent sticky bar over scrolling
           content is illegible rather than merely unstyled. */
        background: var(--surface-1);
        background: color-mix(in srgb, var(--bg) 88%, transparent);
        backdrop-filter: blur(var(--glass-blur-sm, 8px));
        -webkit-backdrop-filter: blur(var(--glass-blur-sm, 8px));
        border-bottom: var(--gs-rule);
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .gs-rail::-webkit-scrollbar {
        display: none;
    }

    .gs-rail__list {
        display: flex;
        align-items: center;
        gap: 0.35rem;
        width: max-content;
    }

    .gs-rail__act {
        flex-shrink: 0;
        margin: 0 0.5rem 0 0;
        padding: 0 0.75rem 0 0;
        border-top: 0;
        border-right: var(--gs-rule);
    }

    .gs-rail__act:first-child {
        padding-right: 0.75rem;
    }

    .gs-rail__link {
        flex-shrink: 0;
        gap: 0.45rem;
        min-height: 40px;
        padding: 0.4rem 0.8rem;
        white-space: nowrap;
        border-left: 0;
        border-bottom: 2px solid transparent;
        border-radius: var(--radius-xs);
    }

    .gs-rail__link[aria-current="true"] {
        border-left-color: transparent;
        border-bottom-color: var(--gs-accent);
        background: var(--gs-accent-soft);
    }

    .gs-step {
        padding-top: 2.5rem;
        /* Clear both the nav and the now-horizontal rail. */
        scroll-margin-top: calc(var(--chrome-bottom, 80px) + 4.5rem);
    }
}

@media (max-width: 560px) {
    .gs-genre {
        grid-template-columns: minmax(0, 5.5rem) minmax(0, 1fr) auto;
        gap: 0.6rem;
        font-size: 0.8rem;
    }

    .gs-points {
        grid-template-columns: minmax(0, 1fr);
        gap: 1.25rem;
    }

    .gs-search__form {
        padding: 0.75rem 0.85rem;
        gap: 0.5rem;
    }

    /* The submit affordance is redundant on touch once the on-screen keyboard
       offers "Go", and it costs width the input needs at 375px. */
    .gs-search__submit {
        display: none;
    }

    .gs-ribbon__art {
        width: 68px;
        height: 96px;
    }

    .gs-ribbon {
        opacity: 0.34;
    }

    .gs-exit {
        min-height: 0;
        padding: 1.1rem 1.15rem;
    }
}

@media (max-width: 400px) {
    .gs-exhibits > li,
    .gs-exhibit,
    .gs-exhibit__art {
        width: 96px;
    }

    .gs-exhibit__art {
        height: 136px;
    }

    .gs-result__art {
        width: 34px;
        height: 48px;
    }
}

/* --------------------------------------------------------------------------
   10. Forced colors
   Gradient text with a transparent fill has no meaning here and would vanish
   outright, taking the page's headline with it.
   -------------------------------------------------------------------------- */

@media (forced-colors: active) {
    .gs-hero__accent {
        background: none;
        -webkit-background-clip: border-box;
        background-clip: border-box;
        color: CanvasText;
    }

    .gs-genre__bar,
    .gs-point__icon {
        forced-color-adjust: none;
    }

    .gs-rail__link[aria-current="true"] {
        border-left-color: Highlight;
    }
}
