:root { --offwhite: #f7f3ec; --black: #171512; --burgundy: #880015; --burgundy-lift: #edb0ba; --ink-muted: #55504a; --paper-grain: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='180'%20height='180'%3E%3Cfilter%20id='g'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.9'%20numOctaves='3'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='saturate'%20values='0'/%3E%3C/filter%3E%3Crect%20width='180'%20height='180'%20filter='url(%23g)'%20opacity='0.055'/%3E%3C/svg%3E"); }
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body { margin: 0; background-color: var(--offwhite); background-image: var(--paper-grain); color: var(--black); font-family: 'DM Sans', Arial, sans-serif; font-size: 16px; line-height: 1.5; -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; }
img { max-width: 100%; }
a { color: inherit; }
a, .button, .link-button, input { transition: color .18s cubic-bezier(.2,.6,.3,1), background-color .18s cubic-bezier(.2,.6,.3,1), border-color .18s cubic-bezier(.2,.6,.3,1); }
.skip, .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; padding: 0; }
/* Above every fixed layer this sheet creates (the phone thumb bar is 20), so the
   skip target can never be covered no matter where a future bar is anchored. */
.skip { z-index: 40; }
.skip:focus { background: var(--black); color: var(--offwhite); clip-path: none; width: auto; height: auto; left: 10px; top: 10px; padding: 10px 14px; }
.skip:focus-visible { outline-color: var(--offwhite); }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid var(--burgundy); outline-offset: 4px; }
/* Focus on dark controls. The outline is offset 4px, so it lands on the PARENT's
   offwhite ground and reads at 9.23:1 there; keeping it burgundy is what makes it
   visible. The inset ring is the second edge, measured against the control's own
   black or burgundy fill at 16.47:1 and 9.23:1, so the indicator clears the 3:1 UI
   floor against whichever neighbour you measure. Swapping the outline itself to
   offwhite would put an offwhite ring on the offwhite header at 1:1. */
.header-cta:focus-visible, .button-dark:focus-visible { box-shadow: inset 0 0 0 2px var(--offwhite); }
.site-header { align-items: center; border-bottom: 1px solid var(--black); display: flex; justify-content: space-between; padding: 19px 5vw; }
.wordmark { align-items: center; display: flex; font-family: 'Instrument Serif', Georgia, serif; font-size: 28px; letter-spacing: .02em; min-height: 44px; text-decoration: none; }
.wordmark span { font-family: 'DM Sans', Arial, sans-serif; font-size: 10px; letter-spacing: .12em; line-height: 1.1; margin-left: 12px; max-width: 75px; text-transform: uppercase; }
nav { display: flex; gap: clamp(14px, 3vw, 44px); margin-left: auto; margin-right: clamp(14px, 4vw, 64px); }
nav a, .header-cta { align-items: center; display: inline-flex; font-size: 12px; font-weight: 700; letter-spacing: .08em; min-height: 44px; text-decoration: none; text-transform: uppercase; }
nav a:hover, .join-aside a:hover { color: var(--burgundy); }
nav a[aria-current="location"] { color: var(--burgundy); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
/* display:contents keeps the desktop header laying out exactly as it did before
   this wrapper existed. The mobile block turns it into the fixed thumb bar. */
.header-actions { display: contents; }
.header-cta { background: var(--black); border: 1px solid var(--black); color: var(--offwhite); padding: 9px 14px; }
.header-cta:hover, .header-cta[aria-current="location"] { background: var(--burgundy); border-color: var(--burgundy); }
/* Touch feedback. A phone has no hover, so every control needs a pressed state
   of its own or a tap reads as a dead tap. Palette only, no new colours. */
nav a:active, .hero-secondary:active, .join-aside a:active, footer a:active { color: var(--burgundy); }
.header-cta:active, .button-dark:active { background: var(--burgundy); border-color: var(--burgundy); }
.button-light:active { background: var(--burgundy); color: var(--offwhite); }
.link-button:active { color: var(--offwhite); }
.button:active, .header-cta:active { transform: translateY(1px); }

/* Hero: two columns bottom-aligned on one baseline, closed by a full-bleed rule. */
.hero { align-items: end; column-gap: clamp(32px, 6vw, 96px); display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 34%); grid-template-rows: 1fr auto; min-height: min(86vh, 780px); padding: clamp(48px, 7vw, 104px) 5vw 0; }
.hero-copy { grid-column: 1; grid-row: 1; }
.eyebrow, .section-number, .product-status { font-size: 11px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; }
.eyebrow { color: var(--burgundy); margin: 0 0 20px; }
h1, h2, h3, p { margin-top: 0; }
h1, h2, h3 { font-family: 'Instrument Serif', Georgia, serif; font-weight: 400; line-height: .9; overflow-wrap: break-word; }
h1 { font-size: clamp(74px, 11.5vw, 168px); letter-spacing: -.04em; margin-bottom: 28px; }
h1 em, h2 em { color: var(--burgundy); font-style: italic; }
.hero-intro { font-family: 'Instrument Serif', Georgia, serif; font-size: clamp(22px, 2.5vw, 32px); margin-bottom: 30px; }
.hero-actions { align-items: center; display: flex; flex-wrap: wrap; gap: 10px 28px; }
.hero-secondary { align-items: center; display: inline-flex; flex-wrap: wrap; font-size: 12px; font-weight: 700; letter-spacing: .08em; min-height: 44px; text-decoration: underline; text-decoration-color: var(--burgundy); text-decoration-thickness: 1px; text-transform: uppercase; text-underline-offset: 6px; }
.hero-secondary:hover { color: var(--burgundy); }
.hero-secondary span { color: var(--burgundy); font-size: 10px; margin-left: 10px; }
.button { align-items: center; border: 1px solid transparent; cursor: pointer; display: inline-flex; font: 700 12px 'DM Sans', Arial, sans-serif; justify-content: center; letter-spacing: .08em; min-height: 48px; padding: 12px 20px; text-decoration: none; text-transform: uppercase; }
.button-dark { background: var(--black); color: var(--offwhite); }
.button-dark:hover { background: var(--burgundy); }
.crest-lockup { grid-column: 2; grid-row: 1; justify-self: end; text-align: center; width: min(100%, 460px); }
/* The real badge is portrait, 913 x 1064. It is sized by width with its own
   aspect-ratio reserved, so it can never stretch and never shifts the layout. */
.crest-lockup img { aspect-ratio: 913 / 1064; display: block; height: auto; margin: 0 auto 22px; max-width: 100%; object-fit: contain; width: 344px; }
.crest-caption { border-top: 1px solid var(--burgundy); color: var(--burgundy); display: inline-block; font-size: 11px; letter-spacing: .1em; line-height: 1.5; padding-top: 10px; text-transform: uppercase; }
.hero-foot { border-top: 1px solid var(--black); display: flex; flex-wrap: wrap; font-size: 11px; font-weight: 700; gap: 6px 24px; grid-column: 1 / -1; grid-row: 2; justify-content: space-between; letter-spacing: .13em; margin: clamp(38px, 5vw, 64px) -5vw 0; padding: 15px 5vw 17px; text-transform: uppercase; }

.section-grid { display: grid; grid-template-columns: minmax(100px, 18%) minmax(0, 1fr) minmax(240px, 30%); gap: 4vw; padding: clamp(70px, 10vw, 150px) 5vw; }
.section-number { color: var(--burgundy); margin: 4px 0 0; }
.manifesto-main { max-width: 680px; }
h2 { font-size: clamp(54px, 7vw, 100px); letter-spacing: -.035em; margin-bottom: 36px; }
.lead { font-family: 'Instrument Serif', Georgia, serif; font-size: clamp(24px, 3vw, 37px); line-height: 1.12; }
.manifesto-main > p:not(.eyebrow):last-child { max-width: 530px; }
.house-rules { border-top: 2px solid var(--burgundy); padding-top: 15px; }
.house-rules ol { list-style: none; margin: 35px 0 0; padding: 0; }
.house-rules li { border-bottom: 1px solid var(--black); font-family: 'Instrument Serif', Georgia, serif; font-size: 24px; padding: 13px 0; }
.house-rules li span { color: var(--burgundy); display: inline-block; font: 700 10px 'DM Sans', Arial, sans-serif; margin-right: 12px; vertical-align: middle; }
.rules-caption { font-size: 13px; line-height: 1.55; margin: 18px 0 0; max-width: 300px; }

/* The drop: no eyebrow, no italic device. The product names carry the section. */
.drop { background: var(--burgundy); color: var(--offwhite); display: grid; grid-template-columns: minmax(230px, 31%) minmax(0, 1fr); gap: 6vw; padding: clamp(70px, 9vw, 130px) 5vw; }
.drop .section-number { color: var(--offwhite); margin-bottom: clamp(40px, 6vw, 78px); }
.drop-heading { max-width: 360px; }
.drop h2 { font-size: clamp(52px, 5.4vw, 80px); margin-bottom: 25px; }
.drop-heading > p:last-of-type { max-width: 300px; }
.drop-note { border-top: 1px solid var(--offwhite); margin-top: 40px; max-width: 360px; padding-top: 14px; }
.drop-note h3 { font-size: 26px; margin: 0 0 10px; }
.drop-note p { font-size: 14px; line-height: 1.6; margin: 0; }
.product-list { border-top: 1px solid var(--offwhite); }
/* Round 13: the plate is the hero of the row, so the art column grew from 34%
   to 40% and the plate cap from 250px to 340px. The button is capped to the
   plate rather than the column, which makes it the positioning context for the
   corner cue and keeps the "View front and back" rule the width of the garment. */
.product { border-bottom: 1px solid var(--offwhite); display: grid; grid-template-columns: minmax(190px, 40%) minmax(0, 1fr); gap: 5%; padding: 32px 0; }
.product-art { align-items: center; display: flex; justify-content: center; min-height: 220px; }
.product-open { -webkit-tap-highlight-color: transparent; background: none; border: 0; color: inherit; cursor: zoom-in; display: block; font: inherit; margin: 0 auto; max-width: 340px; padding: 0; position: relative; text-align: center; width: 100%; }
/* The outline the rest of the site uses is burgundy, which is invisible on the
   burgundy band. This is the only focusable control down here, so it takes the
   offwhite ring instead, at 9.23:1 against the band. */
.product-open:focus-visible { outline-color: var(--offwhite); }
.product-art img { aspect-ratio: 1 / 1; display: block; height: auto; transition: transform .3s cubic-bezier(.2,.7,.25,1); width: 100%; }
.product-open:hover img { transform: scale(1.035); }
.product-open:active img { transform: scale(1.01); }
.product-open-cue { border: 1px solid var(--burgundy-lift); color: var(--burgundy-lift); height: 36px; position: absolute; right: 0; top: 0; transition: background-color .22s cubic-bezier(.2,.6,.3,1), color .22s cubic-bezier(.2,.6,.3,1); width: 36px; }
.product-open-cue::before, .product-open-cue::after { background: currentColor; content: ""; left: 50%; position: absolute; top: 50%; transform: translate(-50%, -50%); }
.product-open-cue::before { height: 1px; width: 14px; }
.product-open-cue::after { height: 14px; width: 1px; }
.product-open:hover .product-open-cue, .product-open:focus-visible .product-open-cue { background: var(--offwhite); color: var(--burgundy); }
.product-open-label { align-items: center; border-top: 1px solid var(--burgundy-lift); color: var(--burgundy-lift); display: flex; font-size: 11px; font-weight: 700; justify-content: center; letter-spacing: .13em; margin-top: 12px; min-height: 44px; text-transform: uppercase; transition: color .22s cubic-bezier(.2,.6,.3,1); }
.product-open:hover .product-open-label, .product-open:focus-visible .product-open-label { color: var(--offwhite); }
.product-meta { align-self: center; }
.product-no { color: var(--burgundy-lift); display: block; font-family: 'Instrument Serif', Georgia, serif; font-size: 30px; letter-spacing: 0; line-height: 1; }
.product h3 { font-size: clamp(32px, 3.4vw, 52px); margin: 6px 0 13px; }
.product-meta p { max-width: 310px; }
.product-meta .product-spec { color: var(--burgundy-lift); font-size: 12px; line-height: 1.55; margin: 10px 0 0; max-width: 340px; }
.product-status { border: 1px solid var(--burgundy-lift); color: var(--burgundy-lift); display: inline-block; font-size: 10px; margin-top: 12px; padding: 5px 7px; }

/* The list: a printed card object, not a fourth headline. */
.membership-card { background: var(--black); color: var(--offwhite); grid-column: 2 / 4; max-width: 880px; padding: 15px; position: relative; }
.membership-card::before { border: 1px solid var(--burgundy-lift); content: ""; inset: 7px; pointer-events: none; position: absolute; }
.membership-card input:focus-visible, .membership-card button:focus-visible { outline-color: var(--offwhite); }
.card-top, .card-bottom { color: var(--burgundy-lift); display: flex; font-size: 10px; font-weight: 700; gap: 12px; justify-content: space-between; letter-spacing: .16em; padding: 0 clamp(10px, 2vw, 30px); text-transform: uppercase; }
.card-top { border-bottom: 1px solid var(--burgundy-lift); padding-bottom: 15px; padding-top: 7px; }
.card-bottom { border-top: 1px solid var(--burgundy-lift); padding-bottom: 7px; padding-top: 15px; }
.card-body { padding: clamp(34px, 4.5vw, 62px) clamp(10px, 2vw, 30px); }
.card-body h2 { font-size: clamp(30px, 3.4vw, 46px); letter-spacing: -.02em; line-height: 1.04; margin-bottom: 22px; }
.card-body > p { max-width: 440px; }
form { margin-top: 34px; max-width: 550px; }
label { display: block; font-size: 11px; font-weight: 700; letter-spacing: .1em; margin-bottom: 6px; text-transform: uppercase; }
.form-hint { color: var(--burgundy-lift); font-size: 12px; line-height: 1.55; margin: 0 0 14px; max-width: 430px; }
.form-row { display: flex; }
input { background: var(--offwhite); border: 1px solid var(--offwhite); border-radius: 0; color: var(--black); font: 16px 'DM Sans', Arial, sans-serif; min-height: 48px; min-width: 0; padding: 10px 13px; width: 100%; }
input::placeholder { color: var(--ink-muted); opacity: 1; }
input[readonly] { background: transparent; border-color: var(--burgundy-lift); color: var(--offwhite); }
.button-light { background: var(--offwhite); color: var(--black); white-space: nowrap; }
.button-light:hover { background: var(--burgundy); color: var(--offwhite); }
.button-light[disabled] { background: var(--burgundy); border-color: var(--burgundy); color: var(--offwhite); cursor: default; }
.form-error { color: var(--burgundy-lift); font-size: 13px; margin: 12px 0 0; }
.form-success { margin-top: 30px; }
.form-success p { font-family: 'Instrument Serif', Georgia, serif; font-size: 24px; margin: 0 0 6px; max-width: 440px; }
.link-button { align-items: center; background: none; border: 0; color: var(--burgundy-lift); cursor: pointer; display: inline-flex; font: 700 11px 'DM Sans', Arial, sans-serif; letter-spacing: .1em; min-height: 44px; padding: 0; text-decoration: underline; text-transform: uppercase; text-underline-offset: 5px; }
.link-button:hover { color: var(--offwhite); }
.join-aside { align-self: end; grid-column: 2 / 4; margin-top: -2vw; }
.join-aside p { margin-bottom: 7px; }
.join-aside a { align-items: center; color: var(--burgundy); display: inline-flex; font-family: 'Instrument Serif', Georgia, serif; font-size: 25px; min-height: 44px; text-decoration: none; }
footer { border-top: 1px solid var(--black); display: flex; font-size: 11px; justify-content: space-between; letter-spacing: .08em; padding: 22px 5vw; text-transform: uppercase; }
footer a { align-items: center; display: inline-flex; min-height: 44px; }

/* ---------------------------------------------------------------------------
   Round 13: the merch gallery.

   A native <dialog>. The scrim is the black token at 88%, but the panel behind
   the garment is PAPER, not another dark layer: the crew neck is black and the
   plates are transparent PNGs, so a dark stage would swallow one of the three
   products. Paper also means every colour in here is a pair the site already
   ships, which is why tools/contrast.py needed no new rows.

   `display: grid` is scoped to `[open]`, because an author display value on a
   bare `dialog` selector beats the UA's `dialog:not([open]) { display: none }`
   and would leave the gallery painted over the page at rest.
   --------------------------------------------------------------------------- */
/* The pair is deliberate: 100% first for a browser that has never heard of dvh,
   then the dynamic viewport unit so the full-bleed phone panel is measured
   against the space that is actually visible rather than the space the URL bar
   is sitting in. */
.lightbox { background: transparent; border: 0; color: var(--black); height: 100%; height: 100dvh; inset: 0; margin: 0; max-height: none; max-width: none; overflow: hidden; padding: 0; width: 100%; }
.lightbox[open] { display: grid; place-items: center; }
/* Stated rather than inherited from the UA sheet, because in a browser with no
   dialog support `dialog` is an unknown element and `dialog:not([open])` never
   applied to it, so the closed gallery would paint over the page. */
.lightbox:not([open]) { display: none; }
/* Only reached when showModal() is missing: no top layer and no ::backdrop, so
   the scrim and the stacking are drawn by hand. */
.lightbox.is-fallback { background-color: rgb(23 21 18 / .88); position: fixed; z-index: 60; }
.lightbox::backdrop { background-color: rgb(23 21 18 / .88); }
.lightbox[open]::backdrop { animation: lb-veil .3s cubic-bezier(.2,.7,.25,1) both; }
.lightbox[open] .lightbox-inner { animation: lb-rise .34s cubic-bezier(.2,.7,.25,1) both; }
/* Deliberately different keyframe NAMES rather than the same two played
   backwards. An animation whose name does not change is never restarted, so
   flipping the direction of lb-rise would hand the exit a finished clock and
   snap the panel away with no animation at all. */
.lightbox.is-closing::backdrop { animation: lb-veil-out .24s cubic-bezier(.4,0,.7,.3) both; }
.lightbox.is-closing .lightbox-inner { animation: lb-fall .24s cubic-bezier(.4,0,.7,.3) both; }
body.lb-open { overflow: hidden; }

.lightbox-inner { background-color: var(--offwhite); background-image: var(--paper-grain); border: 1px solid var(--burgundy); display: grid; grid-template-rows: auto minmax(0, 1fr) auto; height: min(88vh, 800px); margin: auto; max-height: 100%; padding: clamp(16px, 2.2vw, 24px) clamp(18px, 3vw, 34px) clamp(14px, 2vw, 20px); position: relative; width: min(1040px, 92vw); }
.lb-eyebrow { color: var(--burgundy); font-size: 11px; font-weight: 700; letter-spacing: .13em; margin: 0; text-transform: uppercase; }
.lb-close { align-items: center; background: var(--black); border: 1px solid var(--black); color: var(--offwhite); cursor: pointer; display: inline-flex; font: 700 11px 'DM Sans', Arial, sans-serif; gap: 10px; letter-spacing: .13em; min-height: 44px; padding: 0 15px; position: absolute; right: clamp(12px, 2vw, 20px); text-transform: uppercase; top: clamp(12px, 2vw, 20px); transition: background-color .2s cubic-bezier(.2,.6,.3,1), border-color .2s cubic-bezier(.2,.6,.3,1); z-index: 3; }
.lb-close:hover, .lb-close:active { background: var(--burgundy); border-color: var(--burgundy); }
.lb-close:focus-visible { box-shadow: inset 0 0 0 2px var(--offwhite); }
.lb-x { display: block; height: 12px; position: relative; width: 12px; }
.lb-x::before, .lb-x::after { background: currentColor; content: ""; height: 2px; left: 0; position: absolute; top: calc(50% - 1px); width: 12px; }
.lb-x::before { transform: rotate(45deg); }
.lb-x::after { transform: rotate(-45deg); }

/* Horizontal only. The JS owns left/right, and the browser keeps the two
   gestures a "see the merch better" viewer actually wants: pinch to zoom into
   the print, and a vertical drag that is not eaten by the slideshow. */
.lb-stage { overflow: hidden; position: relative; touch-action: pan-y pinch-zoom; -webkit-user-select: none; user-select: none; }
.lb-track { display: flex; height: 100%; transition: transform .34s cubic-bezier(.2,.7,.25,1); will-change: transform; }
/* Dragging follows the finger, and the first paint of a freshly opened gallery
   must not slide in from wherever the last one left off. */
.lb-track.is-dragging, .lb-track.is-instant { transition: none; }
.lb-slide { align-items: center; display: flex; flex: 0 0 100%; justify-content: center; margin: 0; min-width: 0; padding: clamp(8px, 1.6vw, 20px) clamp(34px, 6vw, 76px); }
.lb-slide img { display: block; height: auto; max-height: 100%; max-width: 100%; -webkit-user-drag: none; width: auto; }

.lb-arrow { align-items: center; background: var(--offwhite); border: 1px solid var(--burgundy); color: var(--burgundy); cursor: pointer; display: flex; height: 52px; justify-content: center; position: absolute; top: 50%; transform: translateY(-50%); transition: background-color .2s cubic-bezier(.2,.6,.3,1), color .2s cubic-bezier(.2,.6,.3,1); width: 52px; z-index: 2; }
.lb-arrow:hover, .lb-arrow:active { background: var(--burgundy); color: var(--offwhite); }
/* Dimmed rather than hidden, so the two controls never move under the thumb. */
/* aria-disabled, not disabled: the button stays focusable and simply does
   nothing at the ends, so keyboard focus is never dropped into the dialog. */
.lb-arrow[aria-disabled="true"] { cursor: default; opacity: .28; }
.lb-arrow[aria-disabled="true"]:hover { background: var(--offwhite); color: var(--burgundy); }
.lb-prev { left: clamp(6px, 1.4vw, 16px); }
.lb-next { right: clamp(6px, 1.4vw, 16px); }
.lb-arrow span { border-bottom: 2px solid currentColor; border-right: 2px solid currentColor; display: block; height: 13px; width: 13px; }
.lb-prev span { margin-left: 4px; transform: rotate(135deg); }
.lb-next span { margin-right: 4px; transform: rotate(-45deg); }

.lb-foot { align-items: center; border-top: 1px solid var(--burgundy); display: grid; gap: 8px 16px; grid-template-columns: 1fr auto 1fr; margin-top: clamp(10px, 1.6vw, 16px); padding-top: clamp(10px, 1.4vw, 14px); }
.lb-caption { font-family: 'Instrument Serif', Georgia, serif; font-size: clamp(22px, 2.6vw, 32px); line-height: 1; margin: 0; }
.lb-caption.is-in { animation: lb-caption-in .28s cubic-bezier(.2,.7,.25,1) both; }
.lb-dots { display: flex; gap: 6px; justify-content: center; }
/* 34 x 20 with a 2px mark inside it: the target is a finger, the mark is a hair.
   The pairs sit apart so six pictures still read as three products. */
/* The mark is still a 14px rule; the TARGET around it is now 44px square. The
   ::after carries its own width so growing the button does not stretch the
   mark with it. */
.lb-dot { align-items: center; background: none; border: 0; cursor: pointer; display: flex; height: 34px; justify-content: center; min-height: 44px; min-width: 44px; padding: 0 3px; width: 20px; }
.lb-dot.is-first { margin-left: 15px; }
.lb-dot:first-child { margin-left: 0; }
.lb-dot::after { background: var(--ink-muted); content: ""; display: block; height: 2px; transition: background-color .22s cubic-bezier(.2,.6,.3,1), height .22s cubic-bezier(.2,.6,.3,1); width: 14px; }
.lb-dot[aria-pressed="true"]::after { background: var(--burgundy); height: 4px; }
.lb-count { color: var(--burgundy); font-size: 11px; font-weight: 700; justify-self: end; letter-spacing: .13em; margin: 0; white-space: nowrap; }

@keyframes lb-veil { from { opacity: 0; } to { opacity: 1; } }
@keyframes lb-veil-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes lb-rise { from { opacity: 0; transform: translateY(14px) scale(.975); } to { opacity: 1; transform: none; } }
@keyframes lb-fall { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(10px) scale(.985); } }
@keyframes lb-caption-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Tablet and small laptop: the band that squeezed the story column to ~258px. */
@media (max-width: 1200px) {
  .hero { grid-template-columns: minmax(0, 1fr) minmax(230px, 32%); min-height: 0; }
  .crest-lockup img { width: 224px; }
  .section-grid { gap: 34px 4vw; grid-template-columns: minmax(0, 1fr) minmax(210px, 31%); }
  .section-number { grid-column: 1 / -1; margin: 0; }
  .manifesto-main { grid-column: 1; max-width: none; }
  .house-rules { grid-column: 2; }
  h2 { font-size: clamp(46px, 7.4vw, 70px); }
  .drop { gap: 46px; grid-template-columns: minmax(0, 1fr); }
  .drop .section-number { margin-bottom: 26px; }
  .drop-heading { display: grid; gap: 0 4vw; grid-template-columns: minmax(0, 1fr) minmax(240px, 40%); max-width: none; }
  .drop-heading h2 { grid-column: 1; }
  .drop-heading > p:last-of-type { grid-column: 1; max-width: 420px; }
  .drop-note { grid-column: 2; grid-row: 2 / span 2; margin-top: 0; }
  .product h3 { font-size: clamp(30px, 4.4vw, 40px); }
  .membership-card, .join-aside { grid-column: 1 / -1; }
  .join-aside { margin-top: 26px; }
}

/* ---------------------------------------------------------------------------
   Phone: 360 / 390 / 430 CSS px at DPR 3. Three moves. Navigation leaves the
   top of the page and becomes a fixed bar under the thumb, so the header costs
   one line instead of three. Every section becomes a single column with one
   chapter rule and one headline, so one idea fills one screen. The garment
   plates go from a 110px thumbnail to a 320px plate, which is the only size at
   which the mascot on the chest is actually a mascot. Nothing here reaches
   above 700px, so the desktop layout is untouched.
   --------------------------------------------------------------------------- */
/* Growing each dot to a 44px target grew the whole strip: six of them plus the
   two pair gaps is 324px on a wide panel, which starves the caption once the
   panel itself is narrow. Below 900px the strip takes a row of its own and the
   caption pairs off with the count above it. The gaps close to 0 and the pair
   spacing halves, so the strip is 264 + 8 + 8 = 280px, inside the 288px a 320px
   screen leaves after the safe-area padding. Gallery only; nothing here reaches
   any other part of the page. */
@media (max-width: 900px) {
  .lb-foot { grid-template-columns: 1fr auto; }
  .lb-caption { grid-column: 1; }
  .lb-count { grid-column: 2; }
  .lb-dots { gap: 0; grid-column: 1 / -1; justify-content: center; }
  .lb-dot.is-first { margin-left: 8px; }
  .lb-dots .lb-dot:first-child { margin-left: 0; }
}

@media (max-width: 700px) {
  /* One pair of edge tokens for the whole phone layout, so every band lines up
     on the same margin and landscape notches never clip a word. */
  :root { --edge-l: max(20px, env(safe-area-inset-left)); --edge-r: max(20px, env(safe-area-inset-right)); --bar: 61px; }
  /* Room for the fixed bar so it never covers the footer or the last rule. */
  body { padding-bottom: calc(var(--bar) + env(safe-area-inset-bottom)); }

  .site-header { flex-wrap: nowrap; padding: max(15px, env(safe-area-inset-top)) var(--edge-r) 15px var(--edge-l); }
  .wordmark { font-size: 26px; min-height: 46px; }
  .wordmark span { margin-left: 10px; max-width: 88px; }

  /* The thumb bar. Fixed to the bottom edge, padded past the home indicator,
     opaque (paper ground plus grain) so copy never bleeds through it. */
  /* min-height ties the real bar to the same token body reserves below itself,
     so the two cannot drift apart if the CTA wraps at a large text size. */
  .header-actions { align-items: center; background-color: var(--offwhite); background-image: var(--paper-grain); border-top: 1px solid var(--black); bottom: 0; display: flex; gap: 12px; left: 0; min-height: var(--bar); padding: 0 var(--edge-r) env(safe-area-inset-bottom) var(--edge-l); position: fixed; right: 0; z-index: 20; }
  .header-actions nav { flex-wrap: nowrap; gap: clamp(16px, 5vw, 30px); margin: 0; width: auto; }
  .header-actions nav a { min-height: 60px; }
  .header-cta { margin-left: auto; min-height: 46px; padding: 11px 16px; }

  /* Hero. Badge, then the name, then the one thing to do. align-items is reset
     because the desktop `end` is a cross-axis rule once this becomes a column,
     which would shrink-wrap every child to the right edge. */
  .hero { align-items: start; column-gap: 16px; display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto auto auto; min-height: 0; padding: 28px var(--edge-r) 0 var(--edge-l); }
  /* Luc, round 12: the badge sits to the RIGHT of the headline on phones. hero-copy
     dissolves into the hero grid so the h1 and the badge can share row 1. */
  .hero-copy { display: contents; }
  .hero h1 { grid-column: 1; grid-row: 1; margin-bottom: 0; min-width: 0; }
  .hero-intro { grid-column: 1 / -1; grid-row: 2; margin-top: 22px; }
  .hero-actions { grid-column: 1 / -1; grid-row: 3; }
  .hero-foot { grid-column: 1 / -1; grid-row: 4; }
  /* 40vw keeps the badge growing with the screen: 144px at 360, 156px at 390,
     168px at 430, so it sits inside the 140 to 170px bar across the band. */
  .crest-lockup { align-self: center; grid-column: 2; grid-row: 1; justify-self: end; margin: 0; text-align: left; width: min(32vw, 132px); }
  .crest-lockup img { margin: 0 0 10px; max-width: 100%; width: 100%; }
  .crest-caption { font-size: 9px; letter-spacing: .07em; padding-top: 8px; white-space: nowrap; }
  h1 { font-size: clamp(52px, 14.6vw, 78px); margin-bottom: 18px; }
  .hero-intro { font-size: clamp(19px, 5.2vw, 25px); margin-bottom: 26px; }
  .hero-actions { align-items: stretch; flex-direction: column; gap: 14px; }
  .hero-actions .button-dark { min-height: 54px; width: 100%; }
  /* The secondary link is a control, so it gets the touch scale too, and 1.2
     keeps its two-line wrap at 360 tight instead of loose. */
  .hero-secondary { align-self: flex-start; line-height: 1.2; min-height: 48px; }
  .hero-foot { flex-direction: column; font-size: 10px; gap: 7px; margin: 30px calc(-1 * var(--edge-r)) 0 calc(-1 * var(--edge-l)); padding: 15px var(--edge-r) 17px var(--edge-l); }

  /* Chapters. The section number gets its own rule above it so each band opens
     the way a printed chapter does. currentColor keeps it burgundy on paper and
     offwhite on the burgundy band without adding a token. */
  .section-grid, .drop { display: block; padding: 76px var(--edge-r) 76px var(--edge-l); }
  .section-number { border-top: 2px solid currentColor; display: block; margin: 0 0 40px; padding-top: 12px; }
  h2 { font-size: clamp(42px, 12.4vw, 62px); margin-bottom: 26px; }
  /* Serif display type at 42px on a 320px measure orphans a word per headline
     without this. Unsupported browsers fall back to normal wrapping. */
  h2, .drop h2, .card-body h2, .product h3 { text-wrap: balance; }
  .eyebrow { margin-bottom: 16px; }
  .lead { font-size: clamp(23px, 6.2vw, 30px); margin-bottom: 24px; }
  .manifesto-main > p, .manifesto-main > p:not(.eyebrow):last-child { max-width: none; }
  /* Every desktop measure was released to none above, which is right at 360 and
     390 but runs to about 44ch at 430. 38ch bites only there. */
  .manifesto-main > p:not(.eyebrow):not(.lead) { line-height: 1.62; margin-bottom: 20px; max-width: 38ch; }
  .house-rules { margin-top: 62px; }
  .house-rules ol { margin-top: 26px; }
  .house-rules li { font-size: 26px; padding: 16px 0; }
  .rules-caption { margin-top: 20px; max-width: none; }

  .drop .section-number { color: var(--offwhite); margin-bottom: 34px; }
  .drop-heading { display: block; max-width: none; }
  .drop h2 { font-size: clamp(42px, 12.4vw, 62px); margin-bottom: 20px; }
  .drop-heading > p:last-of-type { max-width: none; }
  .drop-note { margin-top: 38px; max-width: none; padding-top: 16px; }
  .drop-note h3 { font-size: 24px; }
  /* Stated for the phone block so the two dark panels carry an explicit measure
     rhythm next to the manifesto's 1.62. drop-note already computes 1.6 at base. */
  .drop-note p { line-height: 1.6; }

  /* Garments stack. The plate is min(74vw, 320px) so it can never reach the
     edge of a 360px screen, and the srcset `sizes` in the markup matches it. */
  .product-list { margin-top: 46px; }
  .product { display: block; padding: 30px 0 36px; }
  .product-art { display: block; margin: 0 0 20px; min-height: 0; }
  /* Round 13: the plate went from min(74vw, 320px) to min(86vw, 380px), which is
     335px on a 390 screen against a 350px column, so it grows without ever
     touching the edge. The `sizes` attribute in the markup says the same thing. */
  .product-open { max-width: min(86vw, 380px); }
  .product-art img { margin: 0 auto; max-width: none; width: 100%; }
  .product-no { font-size: 22px; }
  .product h3 { font-size: clamp(30px, 8.6vw, 40px); margin: 4px 0 14px; }
  .product-meta p { font-size: 15px; line-height: 1.55; margin-bottom: 14px; max-width: none; }
  .product-meta .product-spec { font-size: 13px; margin: 4px 0 0; max-width: none; }
  .product-status { margin-top: 16px; padding: 7px 10px; }

  /* The card. Fields are 16px so iOS never zooms the viewport on focus, and
     54px tall so the tap target is comfortable rather than merely legal. */
  .membership-card { margin-top: 0; max-width: none; padding: 11px; }
  .membership-card::before { inset: 6px; }
  .card-top, .card-bottom { font-size: 10px; letter-spacing: .09em; padding: 0 14px; }
  .card-body { padding: 34px 14px 30px; }
  .card-body h2 { font-size: clamp(30px, 9vw, 44px); margin-bottom: 18px; }
  .card-body > p { line-height: 1.5; max-width: none; }
  form { margin-top: 30px; max-width: none; }
  .form-hint { max-width: none; }
  .form-row { display: block; }
  input { font-size: 16px; min-height: 54px; width: 100%; }
  .button-light { margin-top: 10px; min-height: 54px; width: 100%; }
  .form-success p { font-size: 22px; max-width: none; }
  .join-aside { margin: 36px 0 0; }
  .join-aside a { font-size: 24px; }
  footer { align-items: flex-start; flex-direction: column; gap: 6px; padding: 26px var(--edge-r) 30px var(--edge-l); }

  /* The gallery goes full bleed and drops its border, because on a phone the
     panel IS the screen. Padding is the safe area on all four sides, so nothing
     lands under a notch, a rounded corner, or the home indicator. */
  .lightbox-inner { border: 0; height: 100%; padding: max(14px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); width: 100%; }
  .lb-close { min-height: 46px; right: max(14px, env(safe-area-inset-right)); top: max(12px, env(safe-area-inset-top)); }
  .lb-slide { padding: 8px 0; }
  /* The arrows leave the middle of the screen and sit just above the caption
     rule, at the bottom corners, where a thumb already is. */
  .lb-arrow { bottom: 104px; height: 54px; top: auto; transform: none; width: 54px; }
  .lb-caption { font-size: clamp(20px, 5.6vw, 27px); }
}

/* Landscape phone. A 61px bar is 16% of a 390px-tall viewport, so the bar and its
   links come down. This block follows the phone block deliberately: at the widths
   where both match, equal specificity means the later --bar wins, and because
   `body { padding-bottom: calc(var(--bar) + env(safe-area-inset-bottom)) }` and
   `.header-actions { min-height: var(--bar) }` both read the token, the reserved
   space and the real bar follow it together with no second number to keep in sync. */
@media (max-width: 900px) and (orientation: landscape) {
  :root { --bar: 52px; }
  .header-actions nav a { min-height: 50px; }
}

/* The universal selector does not reach ::backdrop, so the gallery scrim needs
   its own line here or it would still cross-fade for a reduced-motion visitor. */
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after, .lightbox::backdrop { transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; } }
