/* brand.css — RRRz, the brand surface (rrjjbb.com).
   One design system with ricrios.com: every size, space, weight and
   tracking value here is a PLATFORM token (css/platform/), and the type
   ROLES are the platform's own — the serif divergence was retired
   (2026-08-24) because two faces made two platforms, and the whole
   point is one. If a value in this file is a literal, it is a defect. */

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

body {
    margin: 0;
    background: var(--surface);
    color: var(--text);
    font-family: var(--font-ui);
    font-size: var(--text-base);
    font-weight: var(--weight-regular);
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    line-height: var(--leading-body);
    -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent); color: var(--text-inverse); }

a { color: var(--text); text-decoration: none; transition: var(--transition-color); }
a:hover { color: var(--accent); }
a:focus-visible,
button:focus-visible,
input:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
}

.wrap {
    /* ONE RAIL. The page ran three: masthead/footer on 860, the showcase
       on 1400, other rooms on 1200 — the mark sat at x=330 while the
       showcase eyebrow sat at x=60, and nothing shared an edge. A brand
       whose word is tailoring gets exactly one container; prose sections
       narrow their own text, never their rail. */
    max-width: 1200px;
    margin: 0 auto;
    padding-inline: var(--safe-inline);
}

.grain {
    position: fixed;
    inset: 0;
    z-index: var(--layer-raised);
    pointer-events: none;
    opacity: 0.05;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.hidden-field { display: none; }

/* ── The label voice ──────────────────────────
   One treatment for every small caption on both domains: mono, xs,
   tracked wide, uppercase. This is the platform's label language. */
.masthead-loc, .eyebrow, .spec dt,
.footer-line, .footer-links a, .registry {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}

/* ── Masthead ─────────────────────────────── */
/* Floats over the full-viewport field rather than pushing it down. */

.masthead {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 0;
    z-index: var(--layer-sticky);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding-block: var(--space-lg);
}

/* HAND SCALE: the way home measured 72x14 — the smallest door on the
   site is the one every visitor uses twice. The block padding gives it
   a 44px field; the negative margin hands the height back to the
   masthead so the rule beneath it does not move. */
.masthead .monogram {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    letter-spacing: 0.04em;
    padding-block: 0.95rem;
    margin-block: -0.95rem;
}

.masthead-loc { color: var(--text-muted); }

.eyebrow { color: var(--accent); margin: 0 0 var(--space-lg); }

/* ── Hero ─────────────────────────────────── */

.hero { padding-block: 0 var(--band); }

/* Cinematic: the carapace owns the first full viewport on every channel —
   edge to edge, out of the column, painting with the platform surface so
   light and dark stay seamless. svh first so mobile URL bars can't
   shrink the moment. */
.hero rr-hero {
    display: block;
    inline-size: 100vw;
    margin-inline: calc(50% - 50vw);
    /* svh only — dvh resizes with the URL bar and flashes the canvas. */
    block-size: 100svh;
}

/* No JS: the first viewport must not be a black void. The component
   never defines, so its light DOM shows — the mark, still, centered.
   html.no-js gates it so a defined component never flashes it. */
.hero-fallback { display: none; }
html.no-js .hero-fallback {
    display: grid;
    place-items: center;
    block-size: 100%;
}
html.no-js .hero-fallback svg {
    inline-size: min(320px, 60vw);
    block-size: auto;
    color: var(--text);
}

/* The registry — silent until the mark is first touched. */
.registry {
    position: absolute;
    inset-block-start: calc(100svh - 6rem);
    inset-inline: 0;
    margin: 0;
    color: var(--text-muted);
    text-align: center;
    min-height: 1.2em;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.registry b { color: var(--accent); font-weight: var(--weight-bold); }

.lede {
    font-size: var(--text-lg);
    color: var(--text-muted);
    max-width: var(--measure-narrow);
    margin: 0;
}

/* The old manifesto's rules lived here for `.creed-item`, a class that
   appears in no HTML on this site — the section was removed and its
   stylesheet was not. Dead rules are not free: they collide with the
   next thing to want the name, which is exactly what happened when the
   signal above claimed `.creed`. Deleted, and the name is now the
   signal's. */

/* ── Drop 001 ─────────────────────────────── */

.drop {
    padding-block: var(--band);
    border-top: 1px solid var(--line);
}

/* ── THE SIGNAL ────────────────────────────
   Set at the size of an argument, because it IS the argument and it
   runs before the object. The claim takes the display step the drop
   title used to own alone; the creed is a numbered ledger, because
   four values stated as a paragraph read as copy and four values
   stated as a list read as terms. No adjectives in the headings. */

.signal { padding-block: var(--band) var(--space-3xl); }
/* CENTRED, ON RIC'S CALL. I pushed back with the measurement -- every
   other section below the hero is flush left, so centring this one
   makes it the odd section rather than fixing one -- and he looked
   again and said centre it. His page, his call, and he is right that
   four short lines behave differently from a column of prose: this is
   a statement plate, not a paragraph, and a plate can sit in the
   middle of the room.

   text-align alone is not enough. Three of these carry a 52ch measure
   and the door is a fit-content block, so without auto margins the
   BOXES stay left and only the ink inside them moves -- which is the
   ragged edge again, wearing a third face. */
.signal { text-align: center; }

.signal-claim {
    font-family: var(--font-display);
    font-size: var(--display-2, var(--text-4xl));
    font-weight: var(--weight-display);
    line-height: 0.98;
    letter-spacing: var(--tracking-display);
    color: var(--text);
    text-wrap: balance;
    max-width: 16ch;
    margin: 0 0 var(--space-xl);
}

/* The three verbs on the garment, given their own line and the ink of
   a statement rather than of prose. */



/* The origin. Ric: "the fact that I'm looking to make something after
   10 years of wearing things I liked less… it's still a good value for
   why." It is the best reason on the page and it was not on the page —
   the close stated what the label IS, never why it exists. It also
   names the sport once, in plain words, which is the only visible
   mention on the store: everything else was in a hidden h1 and the
   JSON-LD. ricrios.com stays clear of it deliberately. */
.signal-fine {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: var(--space-md) 0 0;
    /* THE SAME MEASURE AS THE LINES IT SITS BETWEEN. It had none, so it
       ran to the full column -- 1120px between two neighbours that stop
       at 521. Every element in this section is flush left and always
       was; one line reaching 600px past the others is what reads as
       misalignment. Ric saw it and called it centring; it is measure.

       Knifing the section is what exposed it. At fifteen lines the
       ragged edge was buried inside prose. At four, every edge is the
       shape of the block. */
    max-width: 52ch;
}
.signal-close {
    font-family: var(--font-ui);
    font-size: var(--text-lg);
    line-height: 1.55;
    color: var(--text-muted);
    margin: var(--space-3xl) 0 0;
    max-width: 52ch;
}
/* A door is not a clause. It gets its own line at every width — it
   was wrapping onto the end of the sentence on a phone. */
.signal-close + .signal-fine + .signal-close { margin-block-start: var(--space-lg); }
.signal-close a {
    display: block;
    inline-size: fit-content;
    color: var(--accent);
    text-decoration: none;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    /* HAND SCALE — this is the door from the signal to the object. */
    padding-block: 0.95rem;
    margin-block: -0.6rem;
}
.signal-close a:hover { color: var(--text); }
/* AFTER the rules above, not before them. Each of those sets `margin`
   as a shorthand -- `margin: var(--space-3xl) 0 0` -- which resets the
   inline margins to zero. Declared earlier, auto lost the cascade at
   equal specificity and the boxes stayed left while only their ink
   moved. Same edge, third face. */
.signal-claim, .signal-close, .signal-fine { margin-inline: auto; }
.signal-close a { margin-inline: auto; }

@media (max-width: 40rem) {
    .signal-claim { max-width: 14ch; }
}

.drop-title {
    font-family: var(--font-display);
    font-weight: var(--weight-display);
    letter-spacing: var(--tracking-display);
    font-size: var(--text-4xl);
    line-height: var(--leading-tight);
    margin: 0 0 var(--space-2xl);
}
.drop-title em { display: block; font-style: italic; font-weight: var(--weight-regular); color: var(--text-muted); font-size: var(--text-xl); margin-block-start: var(--space-md); }

/* The title in the mark's own hand: boot-brand swaps the borrowed
   words for lockup.js's CATCH / ZZZS — the same 11×7 box as the
   splayed R, the z's falling asleep down the line. Without JS the
   span keeps its text and this rule never applies. */
.drop-lockup svg {
    display: block;
    inline-size: min(340px, 72%);
    block-size: auto;
    color: var(--text);
}

/* Deadpan spec plate — care-label voice, written straight. */
.spec {
    margin: 0;
    max-width: 34rem;
    border: 1px solid var(--line);
    font-variant-numeric: tabular-nums;
}

.spec > div {
    display: grid;
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-md);
}
.spec > div + div { border-top: 1px solid var(--line); }

.spec dt { color: var(--text-muted); padding-top: 0.25em; }

.spec dd {
    margin: 0;
    font-size: var(--text-sm);
    letter-spacing: 0.02em;
}

@media (max-width: 480px) {
    .spec > div { grid-template-columns: 1fr; gap: 0; }
}

/* ── The list ─────────────────────────────── */

.list {
    padding-block: var(--band);
    border-top: 1px solid var(--line);
}

.field-row {
    display: flex;
    max-width: 26rem;
    border-bottom: 1px solid var(--text-muted);
    transition: var(--transition-color);
}
.field-row:focus-within { border-bottom-color: var(--accent); }

.field-row input[type="email"] {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: 0;
    color: var(--text);
    font-family: var(--font-ui);
    font-size: var(--text-lg);
    font-weight: var(--weight-regular);
    padding: var(--space-sm) 0;
}
.field-row input[type="email"]::placeholder { color: var(--text-muted); opacity: 0.7; }
.field-row input[type="email"]:focus:not(:focus-visible) { outline: none; }

.field-row button {
    background: transparent;
    border: 0;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    padding: var(--space-sm) 0 var(--space-sm) var(--space-lg);
    cursor: pointer;
    transition: var(--transition-color);
}
.field-row button:hover { color: var(--accent); }

/* ── Footer ───────────────────────────────── */

.site-footer {
    border-top: 1px solid var(--line);
    padding-block: var(--space-2xl) var(--space-3xl);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md) var(--space-2xl);
    justify-content: space-between;
    align-items: baseline;
}

.footer-line { margin: 0; color: var(--text-muted); font-weight: var(--weight-regular); text-wrap: balance; }
.footer-links { margin: 0; }
/* HAND SCALE: the one outbound link in the footer was 86x14. */
.footer-links a { color: var(--text-muted); display: inline-block; padding-block: 0.95rem; margin-block: -0.7rem; }
.footer-links a:hover { color: var(--accent); }

/* ── Sense toggle ─────────────────────────── */

.sense-toggle {
    position: fixed;
    inset-block-end: var(--space-md);
    inset-inline-end: var(--space-md);
    z-index: var(--layer-sticky);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    /* HAND SCALE: 120x32. */
    padding: 0.95rem var(--space-md);
    cursor: pointer;
    transition: var(--transition-color);
    inset-block-end: calc(1rem + env(safe-area-inset-bottom, 0px));
}
.sense-toggle:hover { color: var(--accent); border-color: currentColor; }
.sense-toggle:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.sense-toggle[aria-pressed="true"] { color: var(--accent); }

/* ── Motion ───────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {
    .rise {
        opacity: 0;
        transform: translateY(1.1em);
        animation: rise var(--dur-reveal) var(--ease-entrance) forwards;
    }
    .rise.d2 { animation-delay: 0.18s; }
    .rise.d3 { animation-delay: 0.36s; }

    @keyframes rise {
        to { opacity: 1; transform: none; }
    }
}

/* ── The mock — a garment that sheds ───────
   The exterior is plain because that is the argument; the interaction
   is the brand's concealment principle made touchable. Press, and the
   shell lifts away exactly like the hero's molt — the inside is where
   the identity lives. Reduced motion swaps clean. */
.mock {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-lg);
    padding-block: var(--band);
}

.mock-figure {
    position: relative;
    inline-size: min(72vw, 380px);
    aspect-ratio: 200 / 240;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}
.mock-figure:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 6px;
    border-radius: var(--radius-base);
}

.mock-skin { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; }

.mock-body {
    fill: var(--surface-raised);
    stroke: var(--line-strong);
    stroke-width: 1.6;
    stroke-linejoin: round;
}
.mock-body--in { fill: var(--surface-sunken); stroke: var(--line); }

.mock-collar { fill: none; stroke: var(--line-strong); stroke-width: 3; }
.mock-seam {
    fill: none;
    stroke: var(--line);
    stroke-width: 1;
    stroke-dasharray: 3 3;
}
.mock-seam--in { stroke: var(--text-muted); }

.mock-tape-ground { fill: none; stroke: var(--accent); stroke-width: 1; }
.mock-tape-mark rect { fill: var(--accent); }
.mock-tab rect { fill: none; stroke: var(--accent-secondary); stroke-width: 1.2; }

/* The shed: the exterior lifts up and away — the molt's own gesture. */
.mock-skin--in { opacity: 0; }
.mock-skin--out,
.mock-skin--in {
    transition: opacity 380ms ease, transform 380ms ease;
}
.mock-figure.shed .mock-skin--out {
    opacity: 0;
    transform: translateY(-9%);
    pointer-events: none;
}
.mock-figure.shed .mock-skin--in { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
    .mock-skin--out, .mock-skin--in { transition: none; }
    .mock-figure.shed .mock-skin--out { transform: none; }
}

.mock-caption {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: center;
    margin: 0;
}
.mock-caption-in { display: none; }
.mock-caption-out { display: inline; }
.mock-caption.shed .mock-caption-out { display: none; }
.mock-caption.shed .mock-caption-in { display: inline; }

.drop-cta {
    margin-top: var(--space-lg);
}
.drop-cta a {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--accent);
    text-decoration: none;
}
.drop-cta a:hover { text-decoration: underline; text-underline-offset: 4px; }


/* The masthead mid-reveal: the wordmark speaks in the label voice and
   the hour's accent, then returns to RRRz. Width is free to change —
   the masthead row is flex with space-between, nothing reflows. */
/* ── The showcase ──────────────────────────
   The article gets the second full viewport, the way the mark got the
   first. It is the reason anyone scrolled: everything above is a claim,
   this is the evidence. Full bleed so the frame is the page. */
.showcase {
    min-block-size: 100svh;
    display: grid;
    align-content: center;
    padding-block: var(--space-2xl) var(--band);
    border-block-start: 1px solid var(--line);
}
.showcase .eyebrow { margin-block-end: var(--space-lg); }
/* `margin: 0 auto` on the shared .wrap makes it a shrink-to-fit grid
   item here, which collapsed the frame to 186px. Stretch it back; the
   width itself is the shared rail. */
.showcase .wrap { inline-size: 100%; }

/* THE SPEC PLATE. The machine idiom the other two surfaces already run:
   a label in mono at label size, the value in the reading face, a
   hairline between rows. Rows rather than a grid, because five facts
   read down faster than they read across, and because a row can wrap on
   a phone without the columns drifting out of register. */
.drop-spec {
    margin: var(--space-xl) 0 0;
    max-width: 52ch;
    border-block-start: 1px solid var(--line);
}
.drop-spec > div {
    display: flex;
    gap: var(--space-lg);
    align-items: baseline;
    justify-content: space-between;
    padding-block: var(--space-md);
    border-block-end: 1px solid var(--line);
}
.drop-spec dt {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0;
    flex: none;
}
.drop-spec dd {
    margin: 0;
    text-align: end;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.drop-line {
    font-size: var(--text-lg);
    color: var(--text-muted);
    max-inline-size: 46ch;
    margin: var(--space-sm) 0 var(--space-lg);
}
/* Text narrows itself on the wide rail; the rail never narrows. */
.drop form { max-inline-size: 30rem; }





/* ── The masthead mark ─────────────────────
   The mark was set in Exo 2 up here while every other instance of it on
   this site is drawn geometry — and it is the LOWERCASE cut, which is
   the streamlined one: three squared r's and the z, no splayed feet to
   fur up the silhouette at masthead size. That mismatch is why it never sat
   right: a typeface approximating our own letterform, at the one size
   where the approximation shows. Now it is the mark itself, in rects,
   snapped to whole multiples of its 3px cell. */
.monogram { display: inline-flex; align-items: center; color: var(--text); }
/* 36 cells across at 3 units each: 108px gives 3px plates, 72px gives 2.
   Whole pixels or the mark picks up scan lines at exactly the size where
   nobody would forgive them. */
.monogram-mark { display: block; inline-size: 108px; block-size: auto; }
.monogram:hover .monogram-mark,
.monogram:focus-visible .monogram-mark { color: var(--accent); }
@media (max-width: 640px) { .monogram-mark { inline-size: 72px; } }

/* ── The showcase header ───────────────────
   The section had no header while every other band on the page has one.
   And the line belongs HERE, over the goods, rather than floating in the
   hero: the hero is the mark's, and a tagline reads as a caption when it
   has nothing to caption. */
.showcase-title {
    font-family: var(--font-display);
    font-size: var(--display-2);
    font-weight: var(--weight-bold);
    line-height: 0.98;
    letter-spacing: -0.03em;
    color: var(--text);
    margin: var(--space-xs) 0 var(--space-sm);
}
.showcase-sub {
    color: var(--text-muted);
    max-inline-size: 54ch;
    margin: 0 0 var(--space-xl);
}


/* The ask sits inside the offer now. */
.drop form { margin-block-start: var(--space-lg); }
/* THE BUY PATH, dark today. Styled now so that switching it on is a
   number and a URL rather than a design task. */
.drop-buy { margin-block-start: var(--space-xl); }
.drop-price {
    margin: 0 0 var(--space-md);
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-variant-numeric: tabular-nums;
    color: var(--text);
    display: flex; align-items: baseline; gap: var(--space-sm);
}
.drop-cur {
    font-family: var(--font-mono); font-size: var(--text-xs);
    font-weight: var(--weight-bold); letter-spacing: var(--tracking-label);
    color: var(--text-muted);
}
.drop-cta-buy {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 48px; padding-inline: var(--space-2xl);
    background: var(--text); color: var(--surface);
    border-radius: 0; text-decoration: none;
    font-family: var(--font-mono); font-size: var(--text-xs);
    font-weight: var(--weight-bold); letter-spacing: var(--tracking-label);
    text-transform: uppercase;
}
.drop-cta-buy:hover { background: var(--accent); color: var(--surface); }
.drop-cta-buy:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.drop-terms {
    margin: var(--space-md) 0 0;
    font-family: var(--font-mono); font-size: var(--text-xs);
    letter-spacing: var(--tracking-label); text-transform: uppercase;
    color: var(--text-muted);
}
/* When the shop is open the list is not the ask any more. */
.drop[data-state="open"] form,
.drop[data-state="open"] .drop-note { display: none; }

.drop-note {
    font-family: var(--font-mono);
    font-weight: var(--weight-regular);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: var(--space-md) 0 0;
}


/* ── The invitation ────────────────────────
   A full-svh black screen with a dead-still mark taught a phone visitor
   nothing: no cue that content exists below, no hint the mark answers
   touch. The cue is the portfolio's own pattern; the registry line
   whispers the gesture once, then the real registry takes the slot. */
.hero { position: relative; }
.hero-cue {
    position: absolute;
    /* Anchored to the VIEWPORT, not the section box: the hero box runs
       100svh + the registry line + a band of padding, so an end-anchor
       parked the cue ~110px below the fold it exists to cure — on the
       page whose only conversion sits under it. Top-anchored at
       100svh minus the cue's own footprint, it always rides the first
       screen, whatever grows beneath. */
    inset-block-start: calc(100svh - 3.2rem);
    inset-block-end: auto;
    inset-inline-start: 50%;
    translate: -50% 0;
    z-index: 2;
    color: var(--accent);
    font-size: 1.2rem;
    line-height: 1;
    /* HAND SCALE: 29x38 for the cue that carries the fold. */
    padding: 0.8rem 1.1rem;
    text-decoration: none;
    animation: cue-drift 2.8s ease-in-out infinite;
}
@keyframes cue-drift {
    0%, 100% { transform: translateY(0); opacity: 0.6; }
    50% { transform: translateY(6px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .hero-cue { animation: none; opacity: 0.8; } }

main { flex: 1; }
main > .drop:first-child { border-top: 0; }

@media (min-width: 1024px) {
    .drop { max-width: 60ch; margin-inline: auto; }
}

/* ── The back panel ────────────────────────
   The tease is the panel itself, moving. It sits between the mark and
   the offer because that is the order of the argument: who this is,
   what the thing looks like, then the ask. Capped in width so the
   panel reads as a garment panel and not a hero image — the object has
   a real size and the page should not pretend otherwise. */
/* THE WEAR CONTROL. The canary's fascia buttons, in this page's own
   type: a lamp that lights when the state is on, square corners because
   the radius law is zero on every machine surface, and 44px of reach. */
.wear-toggle {
    display: inline-flex; align-items: center; gap: var(--space-sm);
    margin-block-start: var(--space-lg);
    min-height: 44px; padding-inline: var(--space-lg);
    background: none; border: 1px solid var(--line); border-radius: 0;
    color: var(--text-muted); cursor: pointer;
    font-family: var(--font-mono); font-size: var(--text-xs);
    font-weight: var(--weight-bold); letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    transition: color .18s ease, border-color .18s ease;
}
.wear-toggle:hover { color: var(--text); border-color: var(--text-muted); }
.wear-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.wear-lamp {
    inline-size: 7px; block-size: 7px; flex: none;
    background: var(--text-muted); opacity: .45;
    transition: opacity .18s ease, background-color .18s ease;
}
.wear-toggle[aria-pressed="true"] { color: var(--text); border-color: var(--text-muted); }
.wear-toggle[aria-pressed="true"] .wear-lamp { background: var(--accent); opacity: 1; }

.panel-bay {
    padding-block: var(--band);
    display: grid;
    justify-items: center;
    gap: var(--space-lg);
}
.panel-bay rr-panel {
    width: 100%;
    max-width: 420px;
    /* The frame belongs to the FLAT ART -- it is the edge of a printed
       panel, and a panel has one. A garment does not: worn, this border
       drew a rectangle around the shirt and the illusion became a
       t-shirt inside a picture frame. It fades with the view. */
    border: 1px solid var(--line);
    transition: border-color .5s ease;
}
.panel-bay:has(.wear-toggle[aria-pressed="true"]) rr-panel { border-color: transparent; }
