/* ============================================================
   SISTER STITCH SOCIETY — v3
   Navy and cream, taken from the client's print collateral. There
   is no accent color and no second hue: hierarchy is carried by
   type weight, scale and letterspacing. Token names still read
   sage/fern/denim from v2 — the values moved first so the color
   diff and the rename diff never mix.
   ============================================================ */
/* ---------- Self-hosted faces (SIL OFL, latin subset) ---------- */
@font-face{
  font-family:'Cormorant Garamond';
  font-style:normal;
  font-weight:300 500;
  font-display:swap;
  src:url('fonts/cormorant-garamond-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Cormorant Garamond';
  font-style:italic;
  font-weight:300 400;
  font-display:swap;
  src:url('fonts/cormorant-garamond-italic-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Dancing Script';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('fonts/dancing-script-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face{
  font-family:'Playfair Display';
  font-style:normal;
  font-weight:400 500;
  font-display:swap;
  src:url('fonts/playfair-display-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* Metric-matched fallback. Georgia sets 15% wider than Cormorant, so the
   hero re-wrapped when the real face arrived — measured at 0.11 CLS on a
   phone. size-adjust makes the substitute occupy the same space, so the
   swap is invisible.

   Cormorant now sets the body as well as the headings, which is what
   makes these numbers load-bearing: on a heading they affect one line
   box, on a paragraph they multiply down every line.

   Re-derived 2026-08-16 against a paragraph of the site's own running
   copy rather than a headline, because that is the job the fallback now
   does. Cormorant/Georgia set width is 88.2% over running copy and 87.9%
   over a headline — the 87.1% here was fitted to the display role alone.
   Cormorant's own descent is 29% of em, not the 26% previously
   overridden; at one line the difference is invisible and at fifteen it
   is a fifth of a line of drift. */
/* Measured 2026-08-16 against the strings each face actually sets.
   Dancing Script at 400 runs 80.9% of Georgia with a deeper descent
   (28 vs 22); Playfair runs 95.4% with a notably taller ascent (108 vs
   92), which is the Didone's high cap and long ascenders. Both are
   needed because both faces appear in the hero headline.

   The earlier version of this note explained why Allura needed one.
   DESIGN.md justified having no fallback on the grounds that the script
   is never above the fold and never in a paragraph — weaving it into the
   hero h1 made both false, and the swap re-wrapped the heading for 0.0073
   CLS on a phone. Measured: Allura sets 74.5% of Georgia's width, with a
   much shallower ascent (80 vs 92) and a far deeper descent (45 vs 22),
   which is simply what a script face looks like. */
@font-face{
  font-family:'Script Fallback';
  src:local('Georgia'),local('Times New Roman'),local('Times');
  size-adjust:80.9%;
  ascent-override:92%;
  descent-override:28%;
}
@font-face{
  font-family:'Didone Fallback';
  src:local('Georgia'),local('Times New Roman'),local('Times');
  size-adjust:95.4%;
  ascent-override:108%;
  descent-override:25%;
}
@font-face{
  font-family:'Cormorant Fallback';
  src:local('Georgia'),local('Times New Roman'),local('Times');
  size-adjust:88.2%;
  ascent-override:92%;
  descent-override:29%;
}

:root{
  /* Grounds — all cream now. --oyster is the deeper ground, --stone the
     hairline neutral. */
  --ivory:#F6F2EA;
  --oyster:#EDE7DB;
  --stone:#D6CFC1;
  --shadow:rgba(28,43,79,.13);

  /* Ink. Measured 2026-08-16, not carried over: --ink on --ivory is
     12.47:1 and --ink-soft on --ivory is 7.86:1 — which passes AAA at
     any size. The 5.6:1 previously recorded here, and the "fails below
     14px" warning built on it, were the OLD palette's numbers copied
     across unrecomputed. */
  --ink:#1C2B4F;
  --ink-soft:#3A4A70;

  /* House. The sage/fern side of the old palette is retired; the
     denim/indigo side survives, retuned toward the new navy.
     --sage is now a TINT OF NAVY, not a hue of its own. It is
     decorative only — 1.89:1 measured, not the 2.6:1 previously
     claimed. It can never carry text, and by a wider margin than the
     guardrail assumed. */
  --sage:#A8B3C7;
  --fern:#1C2B4F;
  --denim:#3A4A70;
  --denim-ink:#1C2B4F;
  --indigo:#16223C;

  /* Washes. Two grounds, no new hue: --sage-wash is cream lifted,
     --chambray-wash is navy at very low saturation over cream.
     Measured 2026-08-16 (the figures here before were estimates
     inherited from the patch file, each low by 0.5-1.6):
       --fern on --sage-wash          11.92:1
       --denim-ink on --chambray-wash 11.77:1
       --chambray-lift on --indigo     8.71:1 */
  --sage-wash:#F1EDE4;
  --sage-rule:#DED7C9;
  --chambray:#8A96AE;
  --chambray-wash:#E9ECF2;
  --chambray-wash-deep:#F3F5F8;
  --chambray-rule:#D3D8E1;
  --chambray-lift:#B6C1D4;

  /* DELETED: --blush, --blush-ink, --marigold, --marigold-ink, and
     --chambray-ink. Zero call sites in site.css or any HTML page —
     verified by grep. The first four were introduced for the 2026-08-04
     repositioning and never used. Do not port them forward. */

  /* Thread. --thread stays decorative, --thread-ink carries type.
     The old comment held that sage at 2.5:1 can never carry text and
     fern at 6.6:1 can; that contract is preserved, at higher contrast. */
  --thread:#A8B3C7;
  --thread-ink:#1C2B4F;
  --thread-veil:rgba(28,43,79,.10);

  /* Type. There is no sans-serif in this identity, so --sans is now the
     same old-style serif as --display and the name is a leftover, kept
     only so this commit stays a value change. Jost and its metric-matched
     fallback are gone in the same commit, by necessity: tuning a
     size-adjust for a face nobody loads is worse than not tuning one. */
  --display:'Cormorant Garamond','Cormorant Fallback',Georgia,serif;
  --sans:'Cormorant Garamond','Cormorant Fallback',Georgia,serif;
  --script:'Dancing Script','Script Fallback',Georgia,cursive;
  /* The Didone. BRAND-SPEC gives it one job: the page title. */
  --didone:'Playfair Display','Didone Fallback',Georgia,serif;

  /* Signature devices. The utility classes that consume these arrive in
     Phase 3; the values are palette, so they land with the palette. */
  --stitch-dash:6px;
  --stitch-gap:5px;
  --stitch-weight:1.5px;
  --stitch:rgba(28,43,79,.70);

  /* The one value outside navy and cream. Form error text only — see the
     Alert Exception Rule in DESIGN.md. Hierarchy by scale, weight and
     ground cannot say "this went wrong", and an error set in cream on
     the navy panel reads as ordinary copy. 8.9:1 on --indigo — and
     1.6:1 on --ivory, so it can only ever appear on the dark panel. */
  --alert:#F0B4A8;

  --gutter:clamp(20px,5vw,80px);
  --ease:cubic-bezier(.22,1,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
/* Cormorant sets small: its x-height is 0.386 per px against Jost's
   0.518, so like-for-like it loses a third of its reading size. Every
   step therefore moved up in size and weight — see the Weight
   Compensation Rule in DESIGN.md, which names each one. The root stays
   at the browser default: the compensation is per step, so a global
   multiplier on top of it would apply the correction twice. */
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--ivory);color:var(--ink);
  font-family:var(--sans);font-size:18px;font-weight:400;line-height:1.62;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
/* Page grain. The color matrix was a warm brown (.25 .24 .20) tuned to the
   sage-and-cream palette — the last warm value left in the system, and it
   multiplied a faint mud over every cream surface. Now cool: the same
   luminance, with the channels ordered the way navy orders them, so the
   grain sits in the palette instead of fighting it. */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.42;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix values='0 0 0 0 .18 0 0 0 0 .21 0 0 0 0 .28 0 0 0 .045 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:multiply;
}
main,header,footer{position:relative;z-index:1}

/* ---------- Focus ----------
   The form fields set outline:none and signalled focus by moving a 1px
   underline from 30% cream to solid cream. That was thin when the
   palette had an accent to lean on and invisible without one — a
   keyboard user had no way to tell which of fifteen controls they were
   in. Every check on this site passed while that was true, because no
   automated check tabs through an inert panel.

   One ring, both grounds, drawn outside the element so it never shifts
   layout. :focus-visible so a mouse click does not draw it. */
:where(a,button,input,select,textarea,summary,[tabindex]:not([tabindex="-1"])):focus-visible{
  outline:2px solid var(--ink);
  outline-offset:3px;
  border-radius:2px
}
.on-dark :where(a,button,input,select,textarea,summary,[tabindex]:not([tabindex="-1"])):focus-visible,
.enq :where(a,button,input,select,textarea,summary):focus-visible{
  outline-color:var(--oyster)
}

/* ---------- Type ---------- */
h1,h2,h3,h4{margin:0;font-family:var(--display);font-weight:300;line-height:1.06;letter-spacing:-.012em}

/* Headings set their own line breaks badly when they are left to fill and
   spill: "Bring your own, or choose from / ours." puts one word on the
   second line. balance evens the lines instead of filling greedily. The
   lede takes pretty, which only prevents the last-line orphan — balance
   on a paragraph would be wrong, and above a few lines browsers ignore
   it anyway. */
h1,h2,h3,h4{text-wrap:balance}
.lede,.work-cap,.step p{text-wrap:pretty}

/* Headings and the copy under them ran together once the type went
   serif: h* carries no bottom margin and p carries no top one, so the
   only separation was the heading's own 1.06 leading. */
h2+p,h3+p,h4+p,h2+.lede,h3+.lede{margin-top:.75em}

/* The page title needed this too. Only .hero h1 carries a bottom margin,
   so on /pricing and /faq the lede ran straight into the heading — and
   the script's descenders made it look like a collision rather than a
   tight gap. The hero keeps its own spacing; it already had some. */
h1+.lede{margin-top:.75em}
.hero h1+.lede{margin-top:0}

/* The page title is the display role from BRAND-SPEC: uppercase,
   letterspaced .06em, the site's equivalent of CUSTOM EMBROIDERY across
   the top of the sheet. Only h1 takes it. Section headings are sentences
   here, not sheet titles, and they carry the navy banner label instead.

   Caps set much wider than mixed case and letterspacing widens them
   again, so the size comes down and the leading opens up: at the old
   7rem a capitalised sentence ran off a phone. */
/* BRAND-SPEC gives the Didone exactly one job — the page title — and
   the old-style serif everything else. Cormorant carried the h1 until
   the client saw it beside their sheet and said the headings looked
   wrong; they are right, Cormorant is old-style and their display face
   is a Didone. HANDOFF anticipated this exact escalation and called it
   "a contained follow-up": one face, headings only.

   Playfair is darker and narrower than Cormorant at the same size, so
   the tracking opens slightly and the weight drops to 400. */
h1{font-family:var(--didone);text-transform:uppercase;letter-spacing:.07em;line-height:1.18;font-weight:400}
.h-xl{font-size:clamp(1.9rem,3.6vw,2.9rem);letter-spacing:.06em}
.h-lg{font-size:clamp(2rem,4.4vw,3.4rem);letter-spacing:-.02em}
.h-md{font-size:clamp(1.5rem,2.3vw,2.05rem)}
p{margin:0 0 1.1em}
a{color:inherit}
em{font-style:italic}

/* The script inside a headline, rather than parked on a line of its own
   underneath it. The standalone subhead repeated whatever the banner
   label above had just said — "CUSTOM ORDERS" over a heading over
   "Custom orders." — so the face now falls on the words in the sentence
   that carry the warmth, which is where a signature actually goes.

   It has to opt out of the h1's uppercase: the script's letterforms stop
   connecting in caps, which is the only reason to use the face at all.
   1.18em because Allura sets small against Cormorant at the same
   nominal size, and a slightly tighter line-height because its
   descenders are long. */
.scr{
  font-family:var(--script);font-style:normal;text-transform:none;
  font-size:1.18em;line-height:.95;letter-spacing:.01em;
  padding-right:.06em
}

/* ---------- Signature devices (BRAND-SPEC) ----------
   Three devices carry the identity: the running-stitch border, the navy
   banner label, and the flower divider. All three are used sparingly on
   the printed sheets — the stitch frames the page and one card, the
   divider appears between blocks, the script signs once. Applied to
   everything, they read as a coupon. */

/* Running stitch. On a dark ground the dash has to invert or it
   disappears into the panel. */
.u-stitch-border{border:var(--stitch-weight) dashed var(--stitch);border-radius:2px}
.on-dark .u-stitch-border{border-color:rgba(246,242,234,.45)}

/* Dotted rule with the four-petal ornament centred. Both take Navy Tint,
   the system's one decorative-only value. The symbol's petals occupy
   only the middle 53% of its 64-unit box, so the ornament renders at
   roughly half the font-size it is given — and the 1.5 stroke scales
   down with it, to well under a pixel. Hence the larger size and the
   heavier stroke here: at 26px/1.5 this read as a faint cross. */
.u-divider{display:flex;align-items:center;gap:1.15rem;color:var(--sage);margin-block:clamp(38px,5vw,64px)}
.u-divider::before,.u-divider::after{content:"";flex:1;border-top:1px dotted currentColor}
.u-divider .u-icon{flex:none;stroke-width:2}

/* Script subhead. Never uppercase, never below 24px, never body copy. */
/* Weight 400, not 500. The first cut shipped the 500 instance and the
   client called it fat — correctly: their sample is a lighter, more
   delicate line, and at display sizes a script's weight reads far more
   strongly than it does in a specimen.

   Allura, not Pinyon. The client's sheets set their script with rounded,
   fairly even strokes; Pinyon is a steeply slanted, very high-contrast
   face whose hairlines go spidery at reading size, which is what made it
   look wrong on the page. BRAND-SPEC named Allura as the alternative and
   it is visibly the closer match.

   On the printed sheets the script runs at roughly half the display head
   above it. The head is 2.9rem here and section heads 3.4rem, so the
   step lands at 1.75-2.3rem — Allura sets a little smaller than Pinyon
   at the same nominal size, hence the bump. Navy, not muted: on the
   sheets the script is the same ink as everything else. */
.u-script{
  font-family:var(--script);font-weight:400;text-transform:none;letter-spacing:0;
  line-height:1.3;font-size:clamp(1.75rem,2.85vw,2.3rem);color:var(--ink);
  margin:.15em 0 0
}
.on-dark .u-script,.enq .u-script{color:var(--chambray-lift)}
h1+.u-script,h2+.u-script{margin-top:.2em}
.u-script+p,.u-script+.lede{margin-top:.7em}

/* Sprite defaults. Sized with font-size so every symbol matches
   optically at any scale, and currentColor so it inherits navy. */
.u-icon{
  width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round
}

/* The eyebrow is the Label step. It used to carry each section's accent
   thread, which is how a section announced its register; there is no
   accent now, so it is navy everywhere and the ground does that job
   instead. It remains the one label that repeats down the whole page. */
.eyebrow{
  display:inline-block;background:var(--ink);color:var(--ivory);
  font-size:.8125rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;
  line-height:1;border-radius:3px;margin:0 0 1.5rem;
  /* Letter-spacing is applied after every character including the last,
     so a tracked label carries .14em of empty space on its right that
     the left does not have. Inside a box that reads as text sitting off
     centre. The right padding gives that .14em back. */
  padding:.6em calc(1.4em - .14em) .6em 1.4em
}

/* On a dark ground the filled banner has nothing to sit against — there
   is no navy-on-navy banner in the collateral, because the device is
   navy ink printed on cream. The first answer was a short rule leading
   into tracked caps, which the client rightly called awful: a stray dash
   floating beside a label, belonging to nothing.

   This is the same banner in outline. Same size, same tracking, same
   padding and radius as the navy block — drawn rather than filled, which
   is exactly what happens when you print a box on dark stock. */
.on-dark .eyebrow,.enq .eyebrow{
  background:transparent;color:rgba(246,242,234,.92);
  border:1px solid rgba(246,242,234,.32)
}
.lede{font-size:clamp(1.12rem,1.45vw,1.3rem);line-height:1.62;color:var(--ink-soft);max-width:48ch;font-weight:400}
.small{font-size:.92rem;font-weight:500;color:var(--ink-soft);letter-spacing:.04em}

/* ---------- Layout ---------- */
.wrap{width:min(1280px,100% - var(--gutter)*2);margin-inline:auto}
section{padding-block:clamp(76px,12vw,168px);scroll-margin-top:86px}

/* ---------- Thread spine ----------
   Sits in the page's real left margin, measured from the content column
   rather than the viewport edge, and only appears once that margin is
   genuinely wide enough. Below this it overlapped the catalog. */
.spine{
  --margin:max(0px,calc((100vw - 1280px) / 2));
  position:fixed;left:calc(var(--margin) / 2 - 22px);top:0;
  width:44px;height:100vh;z-index:2;pointer-events:none;display:none
}
@media(min-width:1560px){.spine{display:block}}
.spine svg{width:100%;height:100%}
.spine .track{stroke:var(--stone);stroke-width:1}
.spine .live{stroke:var(--thread);stroke-width:2;stroke-linecap:round;transition:stroke .55s var(--ease)}
.spine .knot{fill:var(--thread);transition:fill .55s var(--ease)}

/* ---------- Header ---------- */
/* The header now sits on Indigo across every page: events are the front of
   the house, and the dark chrome is what makes the sage sections read as a
   change of register rather than the whole page. */
header{
  position:sticky;top:0;z-index:40;background:var(--indigo);color:var(--oyster);
  border-bottom:1px solid transparent;transition:border-color .35s
}
header.stuck{border-bottom-color:rgba(246,242,234,.22)}
header .mark b{color:var(--oyster)}
header .mark span{color:rgba(246,242,234,.66)}
header nav a{color:rgba(246,242,234,.9)}
header nav a::after{background:var(--chambray)}
header .btn{background:var(--oyster);border-color:var(--oyster);color:var(--indigo);padding:14px 28px}
.bar{display:flex;align-items:center;justify-content:space-between;gap:24px;padding-block:15px}
.mark{display:flex;align-items:center;gap:12px;text-decoration:none}
.mark img{width:40px;height:40px;object-fit:contain}
.mark b{font-family:var(--display);font-weight:400;font-size:1.12rem;letter-spacing:.005em;line-height:1.05;white-space:nowrap}
.mark span{display:block;font-family:var(--sans);font-size:.55rem;font-weight:400;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-soft);margin-top:2px}
/* ---------- Navigation ----------
   Below 920px the nav used to be display:none with nothing in its place:
   on a phone the site had no navigation at all, only the wordmark and
   one button. It is now a disclosure panel behind a labelled button —
   the links are always in the DOM and always reachable, they just fold
   into a panel when there is no room for a row. */
nav{
  display:flex;gap:34px;align-items:center
}
.nav-toggle{display:none}
.nav-cta{display:none}

@media(max-width:919px){
  .nav-toggle{
    display:inline-flex;align-items:center;justify-content:center;
    width:44px;height:44px;padding:0;margin-left:auto;margin-right:14px;
    background:transparent;border:1px solid rgba(246,242,234,.32);
    border-radius:2px;cursor:pointer;color:inherit
  }
  /* Three hairlines drawn from one element: the bar itself plus a
     pseudo-element above and below. Rotating to a cross on open. */
  .nav-toggle span,.nav-toggle span::before,.nav-toggle span::after{
    content:"";display:block;width:18px;height:1px;background:currentColor;
    transition:transform .28s var(--ease),opacity .2s
  }
  .nav-toggle span{position:relative}
  .nav-toggle span::before{position:absolute;top:-6px}
  .nav-toggle span::after{position:absolute;top:6px}
  .nav-toggle[aria-expanded="true"] span{background:transparent}
  .nav-toggle[aria-expanded="true"] span::before{transform:translateY(6px) rotate(45deg)}
  .nav-toggle[aria-expanded="true"] span::after{transform:translateY(-6px) rotate(-45deg)}

  nav{
    position:absolute;left:0;right:0;top:100%;
    display:grid;gap:0;align-items:stretch;
    background:var(--indigo);border-top:1px solid rgba(246,242,234,.18);
    /* The panel is the same navy as the hero it opens over, so it
       dissolved into the page. A hairline under it and a shadow give it
       an edge without introducing a colour the system does not have. */
    border-bottom:1px solid rgba(246,242,234,.28);
    box-shadow:0 18px 40px -18px rgba(10,16,30,.85);
    /* Padding and border cannot shrink below themselves under
       max-height:0, so a closed panel left a 21px navy sliver under the
       header. Zeroed while closed instead. */
    padding:0 var(--gutter);border-top-width:0;
    /* Collapsed by height rather than display:none, so the links stay in
       the accessibility tree and the panel can animate. inert on the
       header's wrapper is what removes them from the tab order. */
    max-height:0;overflow:hidden;visibility:hidden;
    transition:max-height .34s var(--ease),visibility .34s
  }
  nav[data-open]{max-height:60vh;visibility:visible;overflow:auto;padding:6px var(--gutter) 14px;border-top-width:1px}
  nav a{padding:13px 0;border-bottom:1px solid rgba(246,242,234,.12)}
  nav a:last-child{border-bottom:0}

  /* The header CTA moves into the panel. Left in the bar it squeezed the
     wordmark onto two lines and wrapped its own label, on the one screen
     size with the least room to spare. */
  header .btn{display:none}
  .nav-cta{
    display:block;margin-top:14px;padding:14px 28px;text-align:center;
    background:var(--oyster);color:var(--indigo);text-decoration:none;
    border-radius:2px;font-size:.84rem;font-weight:500;letter-spacing:.14em;
    text-transform:uppercase;border-bottom:0
  }
}
nav a{text-decoration:none;font-size:.92rem;font-weight:500;letter-spacing:.04em;padding-bottom:5px;position:relative}
nav a::after{
  content:"";position:absolute;left:0;bottom:0;height:1px;width:100%;background:var(--thread);
  transform:scaleX(0);transform-origin:left;transition:transform .45s var(--ease)
}
nav a:hover::after,nav a:focus-visible::after{transform:scaleX(1)}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:.65em;font-size:.84rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;padding:15px 30px;border-radius:2px;
  text-decoration:none;cursor:pointer;border:1px solid var(--thread-ink);
  background:var(--thread-ink);color:var(--ivory);
  transition:transform .35s var(--ease),background .5s var(--ease),border-color .5s var(--ease),color .35s
}
.btn:hover{transform:translateY(-2px)}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--stone)}
.btn.ghost:hover{border-color:var(--thread-ink);background:var(--thread-veil)}

/* ---------- Hero ---------- */
.hero{padding-top:clamp(40px,6vw,80px);padding-bottom:clamp(56px,8vw,120px)}
.hero-grid{display:grid;gap:clamp(40px,6vw,80px);align-items:center}
@media(min-width:1000px){.hero-grid{grid-template-columns:1.02fr .98fr}}
.hero h1{margin-bottom:.36em}
.hero h1 em{color:var(--thread-ink);transition:color .55s var(--ease)}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:2.2rem}
/* The two paths are equally weighted, so they are the same box — not merely
   the same height. Without a shared minimum they size to their own labels and
   "Custom orders" reads as the lesser option, especially stacked on a phone. */
/* Full width below 560px. A 216px minimum on a 350px column leaves a
   button floating in a third of the row, which reads as an accident
   rather than a choice — and a full-width target is easier to hit. */
.hero-cta .btn{min-width:216px;justify-content:center}
@media(max-width:559px){
  .hero-cta{flex-direction:column;align-items:stretch}
  .hero-cta .btn{width:100%;min-width:0}
}
/* ---------- Hero: three registers ----------
   Real work rather than a rendering — a wedding handkerchief, a personal gift,
   and a company's polo shirt. One glance should say the studio does all three.
   The offsets are deliberately small: a stagger, not a scrapbook. Flat-at-rest
   still holds, so separation comes from an ivory mat and the Stone hairline
   rather than a shadow. */
/* The overlapping collage needs room to read as deliberate. Below 700px
   there is none: three photos at 46-52% of a 350px column overlap into a
   pile that looks like a layout accident. There, they become a plain
   stack — full width, in order, no overlap. */
.stack{display:grid;grid-template-columns:1fr 1fr;gap:12px}
/* One lead image across the top, the other two beside each other. Three
   full-width photos read fine but push the hero copy most of a screen
   down on a phone, which is the wrong trade for the first thing anyone
   sees. */
.stack .s1{grid-column:1/-1}
@media(min-width:700px){
  .stack{display:block;position:relative;width:100%;max-width:560px;margin-inline:auto;aspect-ratio:1/1.2}
}
.stack figure{
  position:static;margin:0;padding:7px;background:var(--ivory);
  border:1px solid var(--stone);border-radius:2px
}
@media(min-width:700px){.stack figure{position:absolute}}
.stack img,.stack video{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block;border-radius:1px}
/* The video occupies a figure the same shape as the photographs, so the stack
   geometry is unchanged and the width/height attributes still reserve the box
   before the first frame arrives. */
.stack video{background:var(--stone)}
@media(min-width:700px){
  .stack .s1{left:38%;top:0;width:52%;z-index:1}
/* When the lead card is the stitching clip it takes the top of the stack. It
   is the thing the page is selling; the photographs tuck behind it. */
.stack .s1:has(video){z-index:4}
  .stack .s2{left:0;top:20%;width:48%;z-index:2}
  .stack .s3{left:44%;top:48%;width:46%;z-index:3}
}
.stack-tag{
  position:absolute;left:2px;bottom:-30px;font-size:.68rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--denim)
}
@media(max-width:520px){.stack-tag{bottom:-38px}}


/* ---------- Ticker ---------- */
.ticker{border-block:1px solid var(--stone);overflow:hidden;padding-block:17px;background:var(--oyster)}
.ticker-in{display:flex;width:max-content;animation:slide 54s linear infinite}
@keyframes slide{to{transform:translateX(-50%)}}
/* The band between hero and catalog reads as shirting — the one place denim
   gets real width rather than a hairline. */
.ticker span{
  font-family:var(--display);font-size:1.12rem;font-style:italic;font-weight:300;color:var(--denim-ink);
  padding-inline:30px;white-space:nowrap;display:flex;align-items:center;gap:30px
}
.ticker span::after{content:"";width:4px;height:4px;border-radius:50%;background:var(--denim);transition:background .55s}

/* ---------- Craft ---------- */
.steps{display:grid}
.step{display:grid;gap:10px 40px;padding-block:clamp(28px,3.6vw,46px);border-top:1px solid var(--stone)}
@media(min-width:840px){.step{grid-template-columns:76px minmax(0,24ch) 1fr;align-items:baseline}}
.step:last-child{border-bottom:1px solid var(--stone)}
.step-n{font-family:var(--display);font-size:1.05rem;font-style:italic;color:var(--denim);transition:color .45s var(--ease),transform .45s var(--ease)}
.step:hover .step-n{color:var(--denim-ink);transform:translateX(6px)}
.step p{margin:0;color:var(--ink-soft);font-size:1.02rem}

/* ---------- The work ----------
   Real photographs, so the page stops being a promise. One ratio for
   everything: the pieces arrive in whatever shape they arrive in, but a
   ragged grid reads as an accident rather than a decision. Crops are cut
   into the files at 4:5 so the browser is never asked to guess. */
/* Two house colors, two jobs. Sage/Fern is the studio's own register and
   holds the craft and custom-order surfaces. Denim/Denim-ink carries the
   events business — it reads as shirting, and events are now the front of
   the house. Blush, marigold and chambray are retired from section duty and
   survive only as thread the customer can choose. One pair per section,
   never split. */
#work{--thread:var(--denim);--thread-ink:var(--denim-ink)}
.work-grid{display:grid;grid-template-columns:1fr;gap:clamp(18px,2.2vw,32px)}
@media(min-width:660px){.work-grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.work-grid{grid-template-columns:repeat(3,1fr)}}
.work-item{margin:0;display:flex;flex-direction:column}
.work-item img{
  width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block;
  border-radius:2px;border:1px solid var(--stone);background:var(--oyster)
}
.work-cap{
  margin:11px 0 0;font-size:.84rem;line-height:1.55;color:var(--ink-soft);
  display:flex;gap:9px;align-items:baseline
}
.work-cap::before{
  content:"";width:14px;height:1px;flex:none;background:var(--thread);
  transform:translateY(-4px)
}

/* ---------- Inquire ---------- */
.enq{background:var(--indigo);color:var(--oyster);border-radius:2px;padding:clamp(26px,3.4vw,48px)}
.enq h2{color:var(--oyster)}
.enq .eyebrow{color:rgba(246,242,234,.92)}
.enq .lede{color:rgba(246,242,234,.8)}
.form{display:grid;gap:14px;margin-top:1.5rem}
@media(min-width:760px){.form{grid-template-columns:1fr 1fr}}
.form .full{grid-column:1/-1}
/* No outline:none here. It used to suppress the ring in favour of the
   underline, and it outranked the global :focus-visible rule on
   specificity, so adding that rule alone left fourteen of fifteen
   controls with no ring at all. Browsers only draw the default ring for
   :focus-visible now, so there is nothing left to suppress.
   Weight is 400: 300 is Cormorant's display weight and these are the
   fields someone types their own name into. */
/* Horizontal padding matches .path span and .pick span (1.1rem), so every
   control in the form starts its text on the same left edge. At the old 2px
   the underlined fields sat flush left while the bordered choices above them
   were inset, and the form read as two columns that did not line up. */
.form input,.form textarea,.form select{
  width:100%;font-family:var(--sans);font-size:1.02rem;font-weight:400;padding:13px 1.1rem;border:0;
  border-bottom:1px solid rgba(246,242,234,.3);background:transparent;color:var(--oyster);
  transition:border-color .35s
}
.form input::placeholder,.form textarea::placeholder{color:rgba(246,242,234,.48)}
.form input:focus,.form textarea:focus,.form select:focus{border-bottom-color:var(--oyster)}
.form select option{color:var(--ink)}
.form button,.enq-open{
  justify-self:start;border:1px solid var(--oyster);background:var(--oyster);color:var(--indigo);
  padding:15px 34px;border-radius:2px;font-family:var(--sans);font-size:.84rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;cursor:pointer;transition:transform .35s var(--ease)
}
.form button:hover,.enq-open:hover{transform:translateY(-2px)}
.sent{display:none;align-items:center;gap:10px;font-family:var(--display);font-style:italic;font-size:1.1rem}
.sent.on{display:flex}

/* The two paths are a question, not a dropdown: the page has already asked
   it once in the hero, and the form should not hide it in a menu. */
.paths{border:0;padding:0;margin:0 0 .4rem;display:flex;flex-wrap:wrap;gap:12px}
.paths legend{padding:0;margin-bottom:.7rem;font-size:.84rem;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(246,242,234,.62)}
.path{flex:1 1 180px;position:relative}
.path input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.path span{display:block;padding:.85rem 1.1rem;text-align:center;cursor:pointer;
  border:1px solid rgba(246,242,234,.28);color:rgba(246,242,234,.78);
  font-size:1.02rem;letter-spacing:.04em;transition:background .18s,border-color .18s,color .18s}
.path input:checked + span{background:var(--oyster);border-color:var(--oyster);color:var(--indigo)}
.path input:focus-visible + span{outline:2px solid var(--oyster);outline-offset:3px}

.path-set{display:contents}
.path-set[hidden]{display:none}

/* Off-screen rather than hidden: a bot reading the DOM fills it, a human
   never sees it. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.form-error{grid-column:1/-1;margin:.2rem 0 0;color:var(--alert);font-size:.92rem}
.form-error[hidden]{display:none}

/* The form opens on request — the panel states its offer first. */
/* No trailing rule. Two of the site's buttons grew a dash after the
   label — a line pointing at nothing, on a control that is already
   obviously a control. Every other button on the site is just its
   words, and now these are too. */
.enq-open{display:inline-flex;align-items:center;margin-top:1.5rem}
.enq-open[hidden]{display:none}
.enq-form{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .55s var(--ease),opacity .4s var(--ease)}
.enq-form>div{overflow:hidden}
.enq-form.open{grid-template-rows:1fr;opacity:1}

/* ---------- Footer ---------- */
/* Ivory, not Oyster — Oyster is now the 'Easy to host' card ground, and two
   Oyster surfaces near each other flattened the page. */
footer{border-top:1px solid var(--stone);padding-block:clamp(50px,6vw,84px);background:var(--ivory)}
.foot{display:grid;gap:36px;align-items:start}
@media(min-width:820px){.foot{grid-template-columns:190px 1fr auto}}
.foot img{width:126px;display:block}
/* The crest at 126px is most of a phone's width of vertical space
   before a word is read. Smaller, and the gaps come in with it. */
@media(max-width:559px){
  .foot{gap:26px}
  .foot img{width:92px}
  .foot-nav{gap:10px 20px;margin-top:12px}
}
.foot-lede{font-size:1.02rem;max-width:32ch}
/* A flex-wrap row broke into "four then two" with the gaps landing
   wherever the words ended. A two-column grid on narrow screens puts
   them on a shared left edge, which is what makes a list read as a list. */
.foot-nav{display:grid;grid-template-columns:1fr 1fr;gap:12px 28px;margin-top:14px}
@media(min-width:560px){.foot-nav{display:flex;flex-wrap:wrap;gap:10px 28px}}
.foot-nav a{font-size:.92rem;font-weight:500;text-decoration:none;color:var(--fern)}
.foot-nav a:hover{text-decoration:underline;text-underline-offset:5px}
.foot-ig{display:inline-flex;align-items:center;gap:9px;margin-top:14px;font-size:.92rem;font-weight:500;text-decoration:none;color:var(--fern)}
.foot-ig svg{flex:none;transition:transform .35s var(--ease)}
.foot-ig:hover{text-decoration:underline;text-underline-offset:5px}
.foot-ig:hover svg{transform:translateY(-1px)}

/* ---------- Reveal ---------- */
.rv{opacity:0;transform:translateY(24px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
.rv.in{opacity:1;transform:none}

/* ---------- Cursor thread ---------- */
#needle{position:fixed;top:0;left:0;width:30px;height:30px;pointer-events:none;z-index:99;opacity:0;transition:opacity .35s}
#trail{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:98}

@media(prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  html{scroll-behavior:auto}
  .rv{opacity:1;transform:none}
  #needle,#trail{display:none}
}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}

/* ---------- How it works (events) ----------
 Denim: the second house color, and the front of the house now that events
 lead. Same paired-token rule as everywhere else. */
#how{--thread:var(--denim);--thread-ink:var(--denim-ink)}
.hw-hero{padding-block:clamp(48px,7vw,104px) clamp(30px,4vw,56px)}
.hw-table{width:100%;border-collapse:collapse;margin-top:1.6rem}
.hw-table caption{text-align:left;font-size:.68rem;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-soft);padding-bottom:12px}
.hw-table th,.hw-table td{text-align:left;padding:12px 16px 12px 0;border-bottom:1px solid var(--stone);font-size:1.02rem;font-weight:300}
.hw-table th{font-family:var(--sans);font-size:.68rem;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-soft)}
.hw-table td:first-child{color:var(--ink)}
.hw-table td+td{white-space:nowrap;color:var(--ink-soft)}
.hw-note{margin-top:1.5rem;max-width:62ch}
.hw-cols{display:grid;gap:clamp(28px,3.4vw,52px)}
@media(min-width:820px){.hw-cols{grid-template-columns:1fr 1fr}}
.hw-list{list-style:none;margin:1rem 0 0;padding:0;display:grid;gap:11px}
.hw-list li{display:flex;gap:11px;align-items:baseline;font-size:1.02rem;color:var(--ink-soft)}
.hw-list li b{font-weight:400;color:var(--ink)}
.hw-list li::before{content:"";width:12px;height:1px;flex:none;background:var(--thread);transform:translateY(-4px)}
.hw-shots{display:grid;grid-template-columns:1fr;gap:clamp(16px,2vw,28px);margin-top:clamp(30px,4vw,52px)}
@media(min-width:660px){.hw-shots{grid-template-columns:1fr 1fr}}
.hw-shots figure{margin:0}
.hw-shots img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block;border-radius:2px;border:1px solid var(--stone);background:var(--oyster)}
.hw-shots figcaption{margin:11px 0 0;font-size:.84rem;line-height:1.55;color:var(--ink-soft)}

/* ============================================================
   REPOSITIONING 2026-08-04 — on-site personalization
   Section alternation is load-bearing: blue, green, blue, green.
   Denim/Indigo carry the selling; Sage/Fern carry the making.
   ============================================================ */

/* --- sections on Indigo --- */
.on-dark{
  background:var(--indigo);color:var(--oyster);
  --thread:var(--chambray);--thread-ink:var(--oyster)
}
.on-dark h1,.on-dark h2,.on-dark h3{color:var(--oyster)}
.on-dark .eyebrow{color:rgba(246,242,234,.92)}
.on-dark .lede{color:rgba(246,242,234,.82)}
.on-dark .hero h1 em{color:var(--chambray-lift)}
.on-dark .btn{background:var(--oyster);border-color:var(--oyster);color:var(--indigo)}
.on-dark .btn.ghost{background:transparent;color:var(--oyster);border-color:rgba(246,242,234,.4)}
.on-dark .btn.ghost:hover{border-color:var(--oyster);background:rgba(246,242,234,.08)}
.on-dark .stack figure{border-color:rgba(246,242,234,.35)}
.on-dark .stack-tag{color:rgba(246,242,234,.66)}

/* --- hero fact band --- */
.facts{
  margin-top:clamp(40px,5vw,72px);padding-top:26px;padding-bottom:clamp(36px,5vw,56px);
  border-top:1px solid rgba(246,242,234,.22);
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:clamp(24px,4vw,56px);align-items:baseline
}
.facts div{display:flex;align-items:baseline;gap:.5em}
/* Below 720px the value and its label cannot share a line: "Two to three
   weeks" wraps to two lines and the label floats beside the second,
   pointing at nothing. Stacked, each fact reads as one thing. */
@media(max-width:719px){
  .facts{display:grid;gap:26px;justify-content:stretch}
  .facts div{flex-direction:column;align-items:flex-start;gap:.35em}
  .facts span{line-height:1.4}
}
.facts b{font-family:var(--display);font-weight:300;font-size:1.5rem;color:var(--oyster)}
.facts span{font-size:.68rem;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:rgba(246,242,234,.66)}

/* --- "A gift that cannot be given twice" --- */
#event{background:var(--sage-wash);border-bottom:1px solid var(--stone);--thread:var(--sage);--thread-ink:var(--fern)}
.gift-grid{display:grid;gap:clamp(34px,5vw,72px);align-items:start}
@media(min-width:920px){.gift-grid{grid-template-columns:.8fr 1.2fr}}
.gift-row{
  padding-block:28px;border-top:1px solid var(--sage-rule);
  display:grid;gap:clamp(12px,2.4vw,32px);align-items:baseline
}
@media(min-width:760px){.gift-row{grid-template-columns:minmax(0,22ch) 1fr}}
.gift-row:last-child{border-bottom:1px solid var(--sage-rule)}
.gift-row h3{font-size:1.5rem}
.gift-row p{margin:0;font-size:1.02rem;color:var(--ink-soft)}

/* --- Occasions --- */
#occasions{--thread:var(--denim);--thread-ink:var(--denim-ink)}
.occ{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:660px){.occ{grid-template-columns:1fr 1fr}}
@media(min-width:1080px){.occ{grid-template-columns:repeat(4,1fr)}}
.occ article{background:var(--chambray-wash);border-radius:2px;padding:30px}
.occ .no{display:block;font-size:.68rem;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--denim)}
.occ h3{font-size:1.42rem;margin:.4rem 0 .55rem}
.occ p{margin:0;font-size:1.02rem;color:var(--ink-soft);line-height:1.6}
.occ-note{
  margin-top:clamp(34px,4vw,52px);padding-top:34px;border-top:1px solid var(--stone);
  display:grid;gap:clamp(28px,4vw,56px)
}
@media(min-width:820px){.occ-note{grid-template-columns:1fr 1fr}}
.occ-note h3{font-size:1.6rem;margin:0 0 .5rem}
.occ-note p{margin:0;font-size:1.02rem;color:var(--ink-soft)}

/* --- Easy to host --- */
#host{--thread:var(--sage);--thread-ink:var(--fern)}
.host{display:grid;grid-template-columns:1fr;gap:clamp(24px,3vw,40px)}
@media(min-width:820px){.host{grid-template-columns:repeat(3,1fr)}}
.host article{background:var(--oyster);border-radius:2px;border-top:2px solid var(--sage);padding:32px 34px 34px}
.host .stage{display:block;font-size:.68rem;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--fern)}
.host h3{font-size:1.6rem;margin:.5rem 0 .6rem}
.host p{margin:0;font-size:1.02rem;color:var(--ink-soft)}
.host-cta{margin-top:44px;display:flex;flex-wrap:wrap;gap:24px;align-items:center}
.host-cta .btn{background:var(--fern);border-color:var(--fern);color:var(--ivory)}
.host-cta p{margin:0;font-size:1.02rem;color:var(--ink-soft);max-width:44ch}

/* --- The work, on the chambray wash --- */
#work{
  background:var(--chambray-wash-deep);
  border-top:1px solid var(--stone);border-bottom:1px solid var(--stone);
  --thread:var(--denim);--thread-ink:var(--denim-ink)
}
#work .work-item img{border-color:var(--chambray-rule)}

/* --- Who we are ---
   The sisters are the brand's memorable fact and were previously nowhere on
   the page. Deliberately no portrait: the owners asked to stay private, so the
   band is carried by our own monogram on our own cap. */
.sis{display:grid;gap:clamp(32px,5vw,64px);align-items:center}
@media(min-width:900px){.sis{grid-template-columns:1.15fr .85fr}}
/* :not(.eyebrow) matters. The banner label is a <p>, so this rule used
   to repaint it --ink-soft — invisible once the label gained a navy
   ground (1.6:1). It read as merely muted for as long as the eyebrow was
   plain text, which is why it survived. */
.sis p:not(.eyebrow){font-size:1.02rem;color:var(--ink-soft);max-width:52ch;margin:0 0 1em}
.sis-sign{font-family:var(--display);font-size:1.5rem;color:var(--fern)}
.sis-fig{margin:0}
.sis-fig img{
  width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block;
  border:1px solid var(--stone);border-radius:2px
}
#sisters{--thread:var(--sage);--thread-ink:var(--fern)}

/* --- Custom orders, at event weight ---
   Same full-bleed treatment and photo row as the events sections, because the
   business does two things and the page previously gave this one a button. */
#custom{
  background:var(--sage-wash);
  border-top:1px solid var(--stone);border-bottom:1px solid var(--stone);
  padding-block:0;--thread:var(--sage);--thread-ink:var(--fern)
}
.cust-row{display:grid;grid-template-columns:1fr;gap:clamp(18px,2.2vw,32px)}
@media(min-width:660px){.cust-row{grid-template-columns:repeat(3,1fr)}}
.cust-row .work-item img{border-color:var(--sage-rule)}
.cust-cta{margin-top:clamp(32px,4vw,48px);display:flex;flex-wrap:wrap;gap:24px;align-items:center}
.cust-cta .btn{background:var(--fern);border-color:var(--fern);color:var(--ivory)}
.cust-cta p{margin:0;font-size:1.02rem;color:var(--ink-soft);max-width:46ch}

/* --- Inquire price table --- */
/* The one framed card. On the event sheet the running stitch goes round
   the page and round the pricing box — this is the pricing box. */
.price{margin:0;padding:clamp(20px,2.4vw,30px);list-style:none}
.price li:last-child{border-bottom:0}

/* --- custom-order pickers ---
   Thread colors and delivery, styled as the price sheet's boxed choices
   rather than as browser controls: the native checkbox and radio are the
   only sans-serif, square-cornered, blue things that would appear
   anywhere on this site, so they are replaced by their own labels. The
   input stays in the DOM and keeps doing the work — it is moved out of
   sight, not display:none, so it remains focusable and announced. */
.picks{border:0;padding:0;margin:0}
.picks legend{
  padding:0;margin-bottom:.7rem;font-size:.68rem;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:rgba(246,242,234,.66)
}
.picks legend span{letter-spacing:.06em;text-transform:none;opacity:.75}
.swatches{display:flex;flex-wrap:wrap;gap:8px}
.pick{position:relative}
.pick input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;cursor:pointer}
.pick span{
  display:block;padding:9px 15px;border-radius:2px;
  border:1px solid rgba(246,242,234,.28);color:rgba(246,242,234,.8);
  font-size:.92rem;letter-spacing:.02em;transition:background .18s,border-color .18s,color .18s
}
.pick input:checked + span{background:var(--oyster);border-color:var(--oyster);color:var(--indigo)}
.pick input:focus-visible + span{outline:2px solid var(--oyster);outline-offset:3px}
/* A capped-out color reads as unavailable rather than merely unchosen. */
.pick input:disabled + span{opacity:.4}
.pick input:disabled{cursor:default}
.pick-note{margin:.7rem 0 0;font-size:.92rem;color:rgba(246,242,234,.55)}
.pick-chosen{margin:.35rem 0 0;font-size:.92rem;color:rgba(246,242,234,.8);min-height:1.4em}

/* --- thread swatches ---
   Sixty-three real spools, so the control is the colour itself rather
   than sixty-three words. The checkbox is moved out of sight but not
   display:none, so it stays focusable and announced; each carries the
   colour's name as its aria-label, and the chosen names are echoed in
   text underneath, because a colour with no name is unusable to anyone
   who cannot see it and unrepeatable over email for anyone who can. */
.swatches:has(.sw){display:grid;grid-template-columns:repeat(auto-fill,minmax(30px,1fr));gap:7px}
.sw{position:relative;display:block;aspect-ratio:1}
.sw input{position:absolute;inset:0;width:100%;height:100%;opacity:0;margin:0;cursor:pointer}
.sw i{
  display:block;width:100%;height:100%;background:var(--t);border-radius:2px;
  box-shadow:inset 0 0 0 1px rgba(246,242,234,.22);
  transition:transform .16s var(--ease),box-shadow .16s
}
.sw input:checked + i{
  box-shadow:inset 0 0 0 1px rgba(28,43,79,.5), 0 0 0 2px var(--oyster);
  transform:scale(1.12)
}
.sw input:focus-visible + i{outline:2px solid var(--oyster);outline-offset:3px}
/* Barely dimmed, deliberately. At the cap this rule applies to sixty of
   sixty-three swatches, and anything heavier turns the whole colour card
   grey — which reads as broken rather than as full. The note underneath
   carries the explanation; this only has to stop the swatch looking
   clickable. */
.sw input:disabled + i{opacity:.82}
.sw input:disabled{cursor:default}

/* A date input never shows a placeholder — the browser fills it with its
   own mm/dd/yyyy — so this is the one field on the form that needs a
   visible label. color-scheme:dark is what makes the native calendar
   glyph legible on the navy panel; without it the control renders its
   icon in near-black. */
.dated{display:block}
.dated span{
  display:block;margin-bottom:.35rem;font-size:.68rem;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:rgba(246,242,234,.66)
}
.form input[type="date"]{color-scheme:dark}
/* Spinners on a hairline-underlined field sit oddly and invite clicking
   rather than typing; the numeric keyboard on a phone is the part that
   matters and inputmode already does that. */
.form input[type="number"]{appearance:textfield}
.form input[type="number"]::-webkit-outer-spin-button,
.form input[type="number"]::-webkit-inner-spin-button{appearance:none;margin:0}
.price li{
  display:flex;justify-content:space-between;gap:20px;padding-block:16px;
  border-bottom:1px solid rgba(246,242,234,.2);font-size:1.02rem
}
.price li:last-child{border-bottom:0}
.price li span{color:rgba(246,242,234,.72)}
/* The heading sits above the grid, not inside its first column. It used
   to share that column with the form, which put the pricing rail level
   with the eyebrow and left it stranded a screen above the fields it
   describes. Now the rail's top edge is the form's top edge. */
.inq-head{margin-bottom:clamp(28px,3.4vw,44px)}
.inq-grid{display:grid;gap:clamp(34px,5vw,72px);align-items:start}
@media(min-width:920px){.inq-grid{grid-template-columns:1.1fr .9fr}}

/* The hero takes a larger step of the Display role than the other page
   titles — it is the one line the site opens with. Measured against the
   real column rather than scaled by eye: 3.4rem is the last step that
   still holds three lines in the 612px desktop column, and 2.2rem the
   last that holds five at 320px. One step above either, they break to
   five and seven.

   Caps are why the number is so much smaller than it looks like it
   should be: uppercase plus .06em sets about half as wide again as the
   mixed case this replaced. */
.hero h1.h-xl{font-size:clamp(2.2rem,4.2vw,3.4rem)}


/* Full-bleed sections carry their padding on the inner .wrap, so the global
   section{padding-block} would double it — 248px of dead space above the hero
   before this. */
#top,#event,#work,#inquire{padding-block:0}
.hero{padding-top:clamp(40px,6vw,80px);padding-bottom:0}
.enq.on-dark{border-radius:2px}
