/* ==========================================================================
   Untitled Needleworks
   Hand-written. No framework, no build step, no third-party CSS.
   ========================================================================== */

/* The display face ships twice, under ONE family name, split by unicode-range.

   The first rule is the whole font. The second is a subset: the full Latin
   alphabet in both cases, all ten digits, and standard punctuation — every
   printable ASCII codepoint, plus the typographic punctuation the font carries
   (curly quotes, en and em dash, ellipsis, bullet, guillemets, middle dot).
   111 codepoints, 117 glyphs, 60% of the full font.

   It was briefly narrower than this — exactly the 65 characters the page
   renders today — but that left a cliff: one "z" in a future heading would have
   pulled the whole 67 KB font for a single glyph. This covers ordinary English
   copy outright, so the full face is only needed for genuinely unusual
   characters.

   The ranges are DISJOINT and between them cover every codepoint, so the subset
   serves what it covers and the full font serves everything else — future copy,
   a glyph nobody anticipated. A browser only downloads a face that some
   character on the page maps to, and today none map to the full font, so it is
   never fetched. Verified on a cold cache against the server log.

   unicode-range rather than two families in the stack ('UN Font Subset',
   'UN Font', ...) because it is declarative: the browser can tell from the CSS
   alone which face serves which codepoint and never has to fetch one to find
   out it was not needed. The stack version also measured clean here, but it
   depends on the browser not speculatively loading the next family during the
   first one's swap period, which is an implementation detail rather than a
   guarantee. Disjoint rather than overlapping ranges for the same reason — no
   reliance on the later rule winning the overlap.

   U+00A0 is in the subset's cmap, pointed at the space glyph. The source font
   has no non-breaking space at all — 399 cmap entries, none for U+00A0 — so the
   one &nbsp; on this page has always fallen through to a serif. Adding it keeps
   the subset self-sufficient. */
@font-face {
    font-family: 'UN Font';
    src: url('./fonts/UN-Font.woff2') format('woff2'),
         url('./fonts/UN-Font.woff')  format('woff'),
         url('./fonts/UN-Font.ttf')   format('truetype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    /* Exactly the complement of the subset below, so the two never overlap. */
    unicode-range:
        U+0-1F, U+7F-9F, U+A1-AA, U+AC-B6, U+B8-BA, U+BC-2012,
        U+2015-2017, U+201B, U+201F-2021, U+2023-2025, U+2027-2038,
        U+203B-10FFFF;
}

@font-face {
    font-family: 'UN Font';
    src: url('./fonts/UN-Font.subset.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    unicode-range:
        U+20-7E, U+A0, U+AB, U+B7, U+BB, U+2013-2014, U+2018-201A,
        U+201C-201E, U+2022, U+2026, U+2039-203A;
}

/* ============================== TOKENS ============================== */
:root {
    /* Ground */
    --cream-00: #F7F4ED;
    --cream-10: #EFE9DC;
    --cream-20: #E2D9C8;

    /* Type + structure */
    --brown-90: #241B12;
    --brown-70: #4A3728;
    --brown-50: #6F5945;
    --brown-20: #C4B49E;

    /* The stage's deep ground. The hero shares it so the 3D canvas has no
       edge to give itself away — on mobile the stage is a band inside the hero,
       and the vignette fades to exactly this. */
    --stage-ground: #0B0704;

    /* Accent — used sparingly, at most one per viewport */
    --orange-60: #C2571C;   /* >=24px text, rules, dots, active states */
    --orange-70: #A8460F;   /* small text only — 5.4:1 on cream */
    --orange-40: #E08A4B;   /* on the dark stage only */

    --font-display: 'UN Font', 'Didot', 'Bodoni MT', Georgia, 'Times New Roman', serif;
    --font-text: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
                 Helvetica, Arial, sans-serif;

    /* Spacing — base 4 */
    --s1: 4px;   --s2: 8px;   --s3: 12px;  --s4: 16px;
    --s5: 24px;  --s6: 32px;  --s7: 48px;  --s8: 64px;
    --s9: 96px;  --s10: 128px; --s11: 160px; --s12: 224px;

    --shell: 1280px;
    /* Sized in rem, not ch: `ch` is the advance of "0", which in this face is
       11.85px against a mean prose advance of ~7.3px, so 68ch rendered at about
       110 characters. Measured empirically — 29.5rem fits 64. */
    --measure: 29.5rem;

    --ease: cubic-bezier(0.22, 1, 0.36, 1);
    --t-micro: 240ms;
    --t-reveal: 720ms;

    --gutter: var(--s5);
    --band-pad: var(--s9);
}

@media (min-width: 760px) {
    :root { --gutter: var(--s7); --band-pad: var(--s11); }
}
@media (min-width: 1100px) {
    :root { --gutter: var(--s8); --band-pad: var(--s12); }
}

/* ============================== RESET ============================== */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, p, figure, blockquote, dl, dd, ol, ul {
    margin: 0; padding: 0;
}
ul, ol { list-style: none; }
img { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; }
a { color: inherit; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    background: var(--cream-00);
}

body {
    font-family: var(--font-text);
    font-size: 1.0625rem;          /* 17px — UN-Font's low x-height needs room */
    line-height: 1.75;
    color: var(--brown-70);
    /* Deliberately no background: a background box on <body> paints over
       negative-z children, which would hide the cloth. <html> carries the
       ground colour instead. */
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

.skip {
    position: absolute; left: -9999px; top: 0;
    background: var(--brown-90); color: var(--cream-00);
    padding: var(--s3) var(--s5); z-index: 100;
}
.skip:focus { left: 0; }

/* Visually hidden, still announced. Not display:none, which removes it from
   the accessibility tree, and not text-indent, which some screen readers skip. */
.vh {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

:focus-visible {
    outline: 2px solid var(--orange-60);
    outline-offset: 3px;
}

/* ============================== LAYOUT ============================== */
.shell {
    width: 100%;
    max-width: var(--shell);
    margin: 0 auto;
    padding-inline: var(--gutter);
}

/* Each section carries its own translucent ground. The cloth reads through as
   faint texture rather than competing with the copy — the hero is the only
   place it plays at full strength. */
.band {
    padding-block: var(--band-pad);
    background-color: rgba(247, 244, 237, 0.62);
}
.band--alt { background-color: rgba(239, 233, 220, 0.80); }

/* ============================== TYPE ============================== */
.title {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(2rem, 6vw, 4rem);
    line-height: 1.05;
    letter-spacing: 0.01em;
    color: var(--brown-90);
    margin-bottom: var(--s6);
}

.sub {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.375rem, 3.2vw, 2rem);
    line-height: 1.2;
    color: var(--brown-90);
    margin-top: var(--s9);
    margin-bottom: var(--s6);
}

.lead {
    font-size: clamp(1.125rem, 2.2vw, 1.375rem);
    line-height: 1.6;
    color: var(--brown-90);
    max-width: 34rem;
}

/* Section index — the one place orange appears in these bands */
.index {
    font-size: 0.75rem;
    line-height: 1.4;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--brown-50);
    margin-bottom: var(--s7);
}
.index span {
    color: var(--orange-70);
    margin-right: var(--s3);
}

/* ============================== CLOTH ============================== */
/* The identity element, and the ground for the whole page: fixed, viewport
   sized, beneath every section. Procedural, so it costs no download. */
.cloth {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
    z-index: -1;
}

/* =============================== NAV =============================== */
/* Fixed from the top. Gains a ground only once the page has moved, so it
   reads as part of the composition rather than a bar bolted on. */
.nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 50;
    border-bottom: 1px solid transparent;
    transition: background-color var(--t-micro) var(--ease),
                border-color var(--t-micro) var(--ease);
}
.nav.is-stuck {
    background-color: rgba(247, 244, 237, 0.88);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom-color: var(--cream-20);
}

.nav__inner {
    max-width: var(--shell);
    margin-inline: auto;
    padding: var(--s4) var(--gutter);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s5);
}

.nav__mark {
    font-family: var(--font-display);
    font-size: 0.9375rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--brown-90);
    text-decoration: none;
    white-space: nowrap;
}
/* Narrow screens get the monogram — the brand is "UN" as well as the full name. */
.nav__mark-full { display: none; }
.nav__mark-short { display: inline; }

.nav__links { display: flex; gap: var(--s4); }
.nav__links a {
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--brown-50);
    text-decoration: none;
    white-space: nowrap;
    border-bottom: 1px solid transparent;
    padding-bottom: 2px;
    transition: color var(--t-micro) var(--ease),
                border-color var(--t-micro) var(--ease);
}
.nav__links a:hover { color: var(--orange-70); border-bottom-color: var(--orange-70); }

/* Over the dark hero the nav has to invert; once it gains its cream ground on
   scroll it goes back to brown. */
.nav:not(.is-stuck) .nav__mark { color: var(--cream-00); }
.nav:not(.is-stuck) .nav__links a { color: var(--brown-20); }
.nav:not(.is-stuck) .nav__links a:hover {
    color: var(--orange-40);
    border-bottom-color: var(--orange-40);
}

/* Pages without the dark hero open on cream, where the inverted nav above is
   cream-on-cream. They carry .page--light on <body> and keep the ordinary
   brown nav until it gains its ground. The hero's own nav is untouched. */
.page--light .nav:not(.is-stuck) .nav__mark { color: var(--brown-90); }
.page--light .nav:not(.is-stuck) .nav__links a { color: var(--brown-50); }
.page--light .nav:not(.is-stuck) .nav__links a:hover {
    color: var(--orange-70);
    border-bottom-color: var(--orange-70);
}

/* Phones only: no navigation bar. The footer is the navigation there, and it
   carries every page plus the policies. Tablets in portrait keep the bar.
   639.98 not 639: at exactly 639px Chrome evaluates the integer boundary as
   false on a sub-pixel viewport, which left the bar showing on the last phone
   size. */
@media (max-width: 639.98px) {
    .nav { display: none; }
}

/* Small phones: the four links have to fit beside the monogram, so the label
   type steps down rather than the links being dropped. */
@media (max-width: 479px) {
    .nav__inner { gap: var(--s3); }
    .nav__links { gap: 10px; }
    .nav__links a { font-size: 0.625rem; letter-spacing: 0.08em; }
    .nav__mark { font-size: 0.875rem; letter-spacing: 0.10em; }
}

@media (min-width: 860px) {
    .nav__links { gap: var(--s5); }
    .nav__links a { font-size: 0.75rem; letter-spacing: 0.16em; }
}
/* The full wordmark used to wait until 1040px, because five links plus 198px
   of wordmark overflowed at 767. The bar now carries the five homepage section
   labels, which are longer than the page names they replaced, but the links
   still step down below 1040 — so the pair fits from about 700px. 820 is the
   threshold rather than 700 because at 700 there are twelve pixels of slack and
   at 820 there are eighty-four; measured, not guessed. */
@media (min-width: 820px) {
    .nav__mark-full { display: inline; }
    .nav__mark-short { display: none; }
}
/* The wider link gap stays at 1040. Moving it down with the wordmark cost 64px
   and cut the slack at 820 from 84 to 20 — the bar fits, but only just. */
@media (min-width: 1040px) {
    .nav__links { gap: var(--s6); }
}

/* ============================== SECTION GRID ==============================
   Below the hero the page was one narrow column pinned left, with the right
   half of a desktop screen empty. The fix is NOT a wider measure — the text
   stays at 62-68 characters — it is using the space beside it.

   Three parts, always in this DOM order so the phone reads label, then text,
   then whatever supports it:

     .sec__meta   numeral and label
     .sec__main   the reading column, capped
     .sec__side   supporting material: a quote, a figure, a list, an image

   On desktop the meta moves into the margin and the side takes the rest of the
   width. `.sec--mirror` flips the axis so consecutive sections do not share a
   shape. Placement is by grid-column, never `order`, so the source order — and
   therefore the mobile reading order — is the same on every layout.
   ========================================================================== */
.sec { display: grid; row-gap: var(--s6); }
.sec__main { max-width: var(--measure); }
.sec__main > * + * { margin-top: var(--s5); }
.sec__side > * + * { margin-top: var(--s6); }

@media (min-width: 1040px) {
    .sec {
        grid-template-columns: minmax(0, var(--measure)) minmax(0, 1fr);
        column-gap: var(--s9);
        align-items: start;
    }
    .sec__meta { grid-column: 2; grid-row: 1; margin-bottom: 0; padding-top: 0.5rem; }
    .sec__main { grid-column: 1; grid-row: 1 / span 2; }
    .sec__side { grid-column: 2; grid-row: 2; }

    .sec--mirror .sec__meta { grid-column: 1; }
    .sec--mirror .sec__main { grid-column: 2; }
    .sec--mirror .sec__side { grid-column: 1; }
}

/* Full width of the shell, for the sections that should fill rather than
   breathe — a product grid, a horizontal timeline, a row of figures. */
.sec--wide { display: block; }
.sec--wide .sec__main { max-width: var(--measure); }

/* ============================== DEVICES ==============================
   Editorial furniture: a quote that breaks the measure, a rule or an image
   that runs past the gutters, a caption. */

/* Set in the display face and deliberately wider-set than body copy, so it
   reads as a break in the page rather than another paragraph. */
.quote {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.375rem, 2.6vw, 2rem);
    line-height: 1.22;
    letter-spacing: 0.01em;
    color: var(--brown-90);
    max-width: 22ch;
}
.quote--wide { max-width: 30ch; font-size: clamp(1.5rem, 3.4vw, 2.5rem); }
.quote cite { display: block; font-style: normal; margin-top: var(--s4); }

.caption {
    font-family: var(--font-text);
    font-size: 0.8125rem;
    line-height: 1.5;
    letter-spacing: 0.02em;
    color: var(--brown-50);
    max-width: 34ch;
}


/* ============================== QUIET LINKS ==============================
   The hero owns the only solid buttons on the site. Everything below it is a
   rule under a word, or at most one outlined box per page. */
.go {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: 0.8125rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--brown-70);
    border-bottom: 1px solid var(--brown-50);
    transition: color var(--t-micro) var(--ease),
                border-color var(--t-micro) var(--ease);
}
.go:hover { color: var(--orange-70); border-bottom-color: var(--orange-70); }
.go--box {
    border: 1px solid var(--brown-50);
    padding-inline: var(--s5);
}
.go--box:hover { border-color: var(--orange-70); }

.goes { display: flex; flex-wrap: wrap; gap: var(--s4) var(--s7); margin-top: var(--s7); }

/* ============================== PILLARS ============================== */
.pillars { border-top: 1px solid var(--cream-20); }

/* Across the page rather than down it. Four short labels stacked full-width
   leave three quarters of a desktop line empty; in a row they use it. */
.pillars--row { border-top: 0; display: grid; gap: var(--s5); }
@media (min-width: 760px) {
    .pillars--row { grid-template-columns: repeat(4, 1fr); gap: var(--s6); }
}
.pillars--row li {
    border-bottom: 0;
    border-top: 1px solid var(--brown-50);
    padding-block: var(--s4) 0;
    font-size: clamp(1rem, 1.8vw, 1.1875rem);
}
.sec__main > .pillars,
.shell > .pillars { margin-top: var(--s9); }
.pillars li {
    font-family: var(--font-display);
    font-size: clamp(1.125rem, 2.2vw, 1.5rem);
    line-height: 1.3;
    color: var(--brown-90);
    padding-block: var(--s5);
    border-bottom: 1px solid var(--cream-20);
}

/* ============================== CONTACT ============================== */
/* Type on the paragraph, not the anchor — with scripting off there is no
   anchor, only the [at]/[dot] text, and it still has to read as the display
   line it is. */
.mailto {
    margin-top: var(--s9);
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 5vw, 3rem);
    line-height: 1.2;
    color: var(--brown-90);
    overflow-wrap: anywhere;
}
.mailto a {
    font: inherit;
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid var(--cream-20);
    padding-bottom: var(--s2);
    transition: border-color var(--t-micro) var(--ease);
    word-break: break-word;
}
.mailto a:hover { border-color: var(--orange-60); }



/* ============================== FOOTER ============================== */
/* Below 640px the nav bar is hidden, so this IS the site navigation. It has to
   be complete and comfortably tappable, not a row of small print. */
.foot {
    background-color: var(--brown-90);
    color: var(--cream-20);
    padding-block: var(--s8) var(--s6);
}
.foot a { color: var(--cream-20); text-decoration: none; }
.foot a:hover { color: var(--orange-40); }

.foot__grid {
    display: grid;
    gap: var(--s7);
    grid-template-columns: 1fr;
}
/* Two columns from 380: below 640 this footer is the navigation, and four
   blocks in a single stack is a lot of thumb travel to reach the bottom. At
   320 two columns would be 136px each, which is narrower than the brand
   wordmark, so it stays one there. */
@media (min-width: 380px) {
    .foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s5); }
    /* The brand and the Get in touch block each take a full row: the wordmark
       wraps four ways in a half column, and the address is one unbreakable
       31-character token. The two columns exist for the two link lists. */
    .foot__grid > .foot__brand,
    .foot__grid > .foot__touch { grid-column: 1 / -1; }
}
@media (min-width: 620px) { .foot__grid { column-gap: var(--s7); } }

/* Four across on the desktop: brand, On the homepage, More, Get in touch.
   Column 4 is widest after the brand because it carries the address and the
   closing line. */
@media (min-width: 1000px) {
    .foot__grid {
        grid-template-columns: 1.35fr 0.85fr 0.85fr 1.25fr;
        column-gap: var(--s8);
    }
    .foot__grid > .foot__brand,
    .foot__grid > .foot__touch { grid-column: auto; }
}

.foot__logo {
    display: block;
    /* The patch occupies a band across the middle of a square canvas, so an
       88px box renders it about 88x62. Uncropped, as agreed for the
       favicons — the patch is 3313x2450 inside a 3464 square. */
    width: 88px; height: 88px;
    margin-bottom: var(--s5);
}
.foot__mark {
    font-family: var(--font-display);
    font-size: 1.0625rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cream-00);
}
.foot__line { margin-top: var(--s3); font-size: 0.9375rem; max-width: 30ch; color: var(--brown-20); }

.foot__h {
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--brown-20);
    margin-bottom: var(--s4);
}
.foot__touch { margin-top: 0; }
/* The address block is one line, not a nav column, so it does not need the
   phone-sized targets the section lists carry. */
/* The address is 31 unbreakable characters. At 0.9375rem it needs about 235px
   and its column is 259px — at the list's default size it broke mid-word. */
.foot__list.foot__list--tight a { padding-block: 11px; font-size: 0.875rem; }
.foot__list li + li { margin-top: 2px; }
/* The assembled address is one unbreakable 31-character token. In a single
   column it had a whole line to itself; in the two-column phone layout it is
   wider than its column and pushed 51px of horizontal scroll onto the page. */
.foot__list, .foot__list a { overflow-wrap: anywhere; }
.foot__list a {
    display: block;
    /* Generous target because this is the phone's main navigation. */
    padding-block: 10px;
    font-size: 0.9375rem;
}

.foot__social { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }
.foot__social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;
    border: 1px solid var(--brown-70);
}
.foot__social a:hover { border-color: var(--orange-40); }
.foot__social svg { width: 18px; height: 18px; fill: currentColor; display: block; }

/* The closing statement. It sits at the foot of column 4 now rather than
   running the width of the page, so it is sized to a column and given air
   above it instead of a whole row of its own. */
.foot__creed {
    margin-top: var(--s7);
    font-family: var(--font-display);
    font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
    line-height: 1.4;
    color: var(--cream-00);
}

.foot__bottom {
    margin-top: var(--s8);
    padding-top: var(--s5);
    border-top: 1px solid var(--brown-70);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s4) var(--s5);
}
.foot__legal { display: flex; flex-wrap: wrap; gap: 0 var(--s5); }
.foot__legal a {
    font-size: 0.8125rem;
    /* 44px like every other footer link: below 640px this footer IS the
       navigation, so the legal row cannot be small print you have to aim at. */
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}
.foot__credit { font-size: 0.8125rem; color: var(--brown-20); }
.foot__top-link {
    margin-left: auto;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    border: 1px solid var(--brown-70);
    padding: 10px var(--s4);
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
}
.foot__top-link:hover { border-color: var(--orange-40); }
.foot__top-link svg { width: 12px; height: 12px; fill: currentColor; }

/* ============================== MOTION ============================== */
.reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--t-reveal) var(--ease),
                transform var(--t-reveal) var(--ease);
    transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-in {
    opacity: 1;
    transform: none;
}

/* Nothing has moved yet for people who asked for stillness. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }

    .reveal { opacity: 1; transform: none; transition: none; }

    /* The cloth never starts; hide the canvas so no blank layer remains. */
    .cloth { display: none; }
}

/* ============================== PAGE HEADER ============================== */
/* Sub-pages have no hero and no stage: they open on the cloth. This is just
   enough room to clear the fixed nav and set the page up. */
.phead {
    padding-top: calc(72px + var(--s8));
    padding-bottom: var(--s7);
}
.phead .index { margin-bottom: var(--s5); }
.phead__lead {
    font-size: clamp(1.125rem, 2.2vw, 1.375rem);
    line-height: 1.6;
    color: var(--brown-90);
    max-width: 56ch;
    margin-top: var(--s5);
}

/* ============================== PRODUCTS ============================== */
/* On /universe each product is a full-width alternating section; the homepage
   uses .prods--four for the compact four-across summary. */
.prods { margin-top: var(--s7); }
.prods > .prod + .prod { margin-top: var(--s9); }
.prods--four {
    display: grid;
    gap: var(--s6);
    grid-template-columns: 1fr;
}
.prods--four > .prod + .prod { margin-top: 0; }
@media (min-width: 620px)  { .prods--four { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1040px) { .prods--four { grid-template-columns: repeat(4, 1fr); } }

.prod { border-top: 1px solid var(--cream-20); padding-top: var(--s5); }
.prod__status {
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--orange-70);
    margin-bottom: var(--s3);
}
.prod__status--soon { color: var(--brown-50); }
.prod__name {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.25rem, 2.6vw, 1.625rem);
    line-height: 1.2;
    color: var(--brown-90);
}
.prod__kind {
    font-size: 0.8125rem;
    letter-spacing: 0.04em;
    color: var(--brown-50);
    margin-top: var(--s2);
}
.prod p { margin-top: var(--s3); }
/* Capped: at full column width the garment shots read as billboards and the
   product copy disappears under them. */
.prod img { width: 100%; max-width: 300px; height: auto; }
.prod__features {
    margin-top: var(--s4);
    display: grid;
    gap: var(--s2) var(--s4);
    grid-template-columns: 1fr 1fr;
}
.prod__features li {
    font-size: 0.875rem;
    line-height: 1.4;
    color: var(--brown-70);
    padding-left: var(--s4);
    position: relative;
}
.prod__features li::before {
    content: "";
    position: absolute;
    left: 0; top: 0.55em;
    width: 6px; height: 1px;
    background: var(--orange-60);
}

/* ============================== TIMELINE ==============================
   Horizontal, spanning the shell. Four dates read across the page in a row
   rather than down a narrow column, which is both the shape of a timeline and
   the one place this page should be at its widest. */
.htl { display: grid; gap: var(--s6); margin-top: var(--s7); }
@media (min-width: 720px) {
    .htl { grid-template-columns: repeat(4, 1fr); gap: var(--s5); }
}
.htl__item { padding-top: var(--s4); border-top: 1px solid var(--brown-50); }
.htl__when {
    font-family: var(--font-display);
    font-size: clamp(1.375rem, 3vw, 2rem);
    line-height: 1;
    color: var(--orange-70);
}
.htl__what {
    font-family: var(--font-display);
    font-size: clamp(1.0625rem, 1.8vw, 1.25rem);
    line-height: 1.25;
    color: var(--brown-90);
    margin-top: var(--s3);
}
.htl__note { margin-top: var(--s3); font-size: 0.9375rem; line-height: 1.55; }

/* ============================== ROLE AREAS ============================== */
.roles {
    display: grid;
    gap: var(--s5);
    margin-top: var(--s7);
    grid-template-columns: 1fr 1fr;
}
@media (min-width: 760px) { .roles { grid-template-columns: repeat(3, 1fr); } }
.role {
    border-top: 1px solid var(--cream-20);
    padding-top: var(--s4);
}
.role img { width: 72px; height: auto; margin-bottom: var(--s3); opacity: 0.9; }
.role__name {
    font-family: var(--font-display);
    font-size: clamp(1rem, 2.2vw, 1.1875rem);
    line-height: 1.25;
    color: var(--brown-90);
}

/* ============================== FIGURES ============================== */
.figures {
    display: grid;
    gap: var(--s5);
    margin-top: var(--s7);
    grid-template-columns: 1fr 1fr;
}
@media (min-width: 700px) { .figures { grid-template-columns: repeat(3, 1fr); } }
.figure__n {
    font-family: var(--font-display);
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1;
    color: var(--brown-90);
}
.figure__l {
    font-size: 0.8125rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--brown-50);
    margin-top: var(--s2);
}

/* ============================== CARDS ============================== */
.cards {
    display: grid;
    gap: var(--s6);
    margin-top: var(--s7);
    grid-template-columns: 1fr;
}
@media (min-width: 700px)  { .cards { grid-template-columns: 1fr 1fr; } }
.card {
    border-top: 1px solid var(--cream-20);
    padding-top: var(--s5);
}
.card__t {
    font-family: var(--font-display);
    font-size: clamp(1.125rem, 2.4vw, 1.375rem);
    color: var(--brown-90);
    margin-bottom: var(--s3);
}
.card p { max-width: 46ch; }
