/* ==========================================================================
   VIP Charcuterie Co. — design tokens
   Palette is fixed by the brand brief. The ONLY derived value is Deep Sage.
   Everything else is an opacity variant of a brand color.
   ========================================================================== */
:root{
  /* --- Brand palette (exact) --- */
  --ivory:#FAF5ED;        /* page ground. never #FFF */
  --soft-pink:#EBC9CF;    /* primary blush: alt sections, secondary buttons */
  --baby-pink:#F7DDE1;    /* lightest tint wash */
  /* Retuned 2026-09-11. #E7C1C6 sat ΔE 3.1 from Soft Pink — the same colour to the eye,
     so three pink tokens were doing two jobs and no pink section read as its own step.
     This is 12.1 away and still carries cocoa text at 5.05:1. Same hue, a real step. */
  --blush:#CDA7AE;        /* deeper tint: card grounds, the no-red error fill */
  /* Derived, the way Deep Sage was: Soft Pink's own hue pushed until it can carry text.
     AA on all three pink grounds — ivory 6.45:1, baby pink 5.47:1, soft pink 4.60:1.
     This is the brand's pink finally allowed to speak, not just sit behind things. */
  --deep-rose:#844658;
  --sage:#8F9B7A;         /* botanicals, dividers, icons — DECORATIVE ONLY */
  --deep-sage:#5E6A4C;    /* derived. the only green permitted as text, on ivory */
  --cocoa:#4A3934;        /* all text, primary fill, footer. never #000 */
  --champagne:#C8AD8D;    /* hairlines + thin frames only. 1–2 touches a page */

  /* --- Permitted opacity variants --- */
  --cocoa-88:rgba(74,57,52,.88);
  --cocoa-72:rgba(74,57,52,.72);
  --cocoa-60:rgba(74,57,52,.60);
  --cocoa-22:rgba(74,57,52,.22);
  --cocoa-12:rgba(74,57,52,.12);
  --cocoa-08:rgba(74,57,52,.08);

  /* --- Muted text, per ground ---------------------------------------------
     A translucent token cannot be safe everywhere: cocoa at .72 reads 4.54:1 on
     ivory but 3.05:1 on Blush. So the ALPHA varies by ground and the RENDERED
     contrast stays constant. Use these for secondary copy instead of a bare
     opacity, which is what let a 1.55:1 numeral ship.
       --muted  >= 4.6:1  — safe for body copy at any size
       --faint  >= 3.2:1  — large text only (>=24px, or >=18.66px bold)      */
  --muted:rgba(74,57,52,.73);
  --faint:rgba(74,57,52,.59);
  --sage-50:rgba(143,155,122,.50);
  --sage-22:rgba(143,155,122,.22);
  --champagne-55:rgba(200,173,141,.55);
  --ivory-88:rgba(250,245,237,.88);
  --deep-rose-30:rgba(132,70,88,.30);
  --deep-rose-12:rgba(132,70,88,.12);

  /* --- Type families --- */
  --serif:"Playfair Display","Iowan Old Style",Georgia,"Times New Roman",serif;
  --sans:"Montserrat","Avenir Next","Helvetica Neue",Arial,sans-serif;
  /* stand-in for Brittany Signature until the webfont licence is confirmed */
  --script:"Pinyon Script","Snell Roundhand","Apple Chancery",cursive;

  /* --- Type scale: desktop --- */
  --t-display:64px;  --t-h1:52px; --t-h2:40px; --t-h3:26px; --t-h4:20px;
  --t-quote:30px;    --t-script:44px;
  --t-lede:19px;     --t-body:17px; --t-small:15px; --t-micro:13px;

  /* --- Space: 8px base --- */
  --s1:4px;  --s2:8px;  --s3:16px; --s4:24px; --s5:32px; --s6:40px;
  /* Reduced 15 Sep 2026 from 56/72/96/120/160. These five steps — not --sec — are what
     .nm, .cat and every page head space themselves from, so they are what actually set
     the page's vertical rhythm. --s1..--s6 stay put: they are component padding and are
     what hold interactive targets at 44px (WCAG 2.5.8, enforced by finalcheck.py). */
  --s7:44px; --s8:56px; --s9:72px; --s10:88px; --s11:112px;

  /* --- Layout --- */
  /* NB: `ch` is the width of the digit zero, ~1.3x the average Montserrat character.
     52ch renders as ~68 real characters; 68ch would render as ~88. Measured, not assumed. */
  --max:1200px; --measure:52ch; --measure-tight:42ch; --gutter:32px;

  /* --- Shape --- */
  --r-sm:4px; --r-md:8px; --r-pill:999px;
  --hair:1px solid var(--champagne);
  --rule:1px solid var(--cocoa-12);

  /* --- Motion --- */
  --ease:cubic-bezier(.22,.61,.36,1);
  --dur-fast:200ms; --dur:320ms; --dur-slow:520ms;
}
@media (max-width:767px){
  :root{
    --t-display:40px; --t-h1:34px; --t-h2:28px; --t-h3:22px; --t-h4:18px;
    --t-quote:22px;   --t-script:32px;
    --t-lede:17px;    --t-body:16px; --t-small:14px; --t-micro:12px;
    --gutter:20px;
  }
}

/* ==========================================================================
   Base
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ivory); color:var(--cocoa);
  font-family:var(--sans); font-size:var(--t-body); line-height:1.65;
  font-weight:400; -webkit-font-smoothing:antialiased;
  /* inert at normal sizes; only fires when a word genuinely cannot fit its box, which is
     what happens to narrow grid cells under 200% text zoom (WCAG 1.4.4) */
  overflow-wrap:break-word;
}
img{max-width:100%;display:block}
h1,h2,h3,h4{margin:0;font-family:var(--serif);font-weight:400;color:var(--cocoa);overflow-wrap:break-word}
/* break-word alone does not lower min-content sizing, so a flex/grid item still floors at its
   longest word. min-width:0 is what lets text-zoomed display type wrap inside its column. */
.t-display,.t-h1,.t-h2,.t-h3,.t-h4,.t-script,.t-quote{min-width:0;overflow-wrap:break-word}
p{margin:0}
a{color:var(--cocoa)}

/* Focus: cocoa ring on light grounds, ivory ring on cocoa grounds. 10:1 both ways. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--cocoa); outline-offset:3px; border-radius:var(--r-sm);
}
.on-cocoa :where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline-color:var(--ivory);
}

/* the grounds redefine the alpha; nothing that uses --muted has to know */
.sec--baby,.ph--baby,.on-baby{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62)}
.sec--pink,.cta,.on-soft{--muted:rgba(74,57,52,.81);--faint:rgba(74,57,52,.65)}
.ph--blush,.on-blush,.sb{--muted:rgba(74,57,52,.95);--faint:rgba(74,57,52,.75)}
/* cocoa is a ground too — on it the muted colour is ivory, not a paler cocoa */
.on-cocoa,.ft,.lbx{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55)}

.pending{color:inherit;text-decoration:none;cursor:default}
/* every component that toggles visibility does it with the `hidden` attribute, and a
   class like .lbx{display:flex} would otherwise win on specificity */
[hidden]{display:none!important}
.skip{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);position:absolute;left:-9999px;top:0;z-index:99;background:var(--cocoa);color:var(--ivory);
  padding:12px 20px;border-radius:0 0 var(--r-sm) 0;font-size:15px;font-weight:600;text-decoration:none}
.skip:focus{left:0}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* ==========================================================================
   Type roles
   ========================================================================== */
.t-display{font-family:var(--serif);font-size:var(--t-display);font-weight:400;line-height:1.06;letter-spacing:-.02em}
.t-h1{font-family:var(--serif);font-size:var(--t-h1);font-weight:400;line-height:1.12;letter-spacing:-.018em}
.t-h2{font-family:var(--serif);font-size:var(--t-h2);font-weight:400;line-height:1.18;letter-spacing:-.014em}
.t-h3{font-family:var(--serif);font-size:var(--t-h3);font-weight:500;line-height:1.3;letter-spacing:-.006em}
.t-h4{font-family:var(--serif);font-size:var(--t-h4);font-weight:500;line-height:1.35}
.t-quote{font-family:var(--serif);font-size:var(--t-quote);font-weight:400;font-style:italic;line-height:1.45;letter-spacing:-.008em}
/* the script is where the brand speaks in its own colour — the one place Deep Rose
   appears at size, and still once per viewport */
.t-script{font-family:var(--script);font-size:var(--t-script);line-height:1.1;font-weight:400;
  color:var(--deep-rose)}
/* on cocoa grounds the script stays ivory: Deep Rose on cocoa is 1.56:1 */
.on-cocoa .t-script,.ft__script{color:var(--ivory)}
.t-lede{font-size:var(--t-lede);line-height:1.7;color:var(--muted)}
.t-body{font-size:var(--t-body);line-height:1.65}
.t-small{font-size:var(--t-small);line-height:1.6}
.t-micro{font-size:var(--t-micro);line-height:1.5}
.t-label{font-family:var(--sans);font-size:14px;font-weight:600;line-height:1.4;letter-spacing:.02em}
.t-price{font-family:var(--sans);font-size:18px;font-weight:500;font-variant-numeric:tabular-nums;letter-spacing:.01em}
/* Eyebrow: only where it carries real information (a category, a season, a step). */
.t-eyebrow{font-family:var(--sans);font-size:var(--t-micro);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.measure{max-width:var(--measure)}
.measure-tight{max-width:var(--measure-tight)}

/* ==========================================================================
   Buttons  — Primary: cocoa fill / ivory label.  Secondary: soft-pink or outline.
   Min tap target 44px.
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  min-height:48px;padding:0 var(--s5);border:1px solid transparent;border-radius:var(--r-pill);
  font-family:var(--sans);font-size:16px;font-weight:600;letter-spacing:.01em;
  text-decoration:none;cursor:pointer;background:none;
  transition:background-color var(--dur) var(--ease),color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),transform var(--dur) var(--ease);
}
.btn--sm{min-height:44px;padding:0 var(--s4);font-size:15px}
/* a press settles the button 1px rather than bouncing it — the only transform
   any button makes, and it is feedback, not decoration */
.btn:active{transform:translateY(1px)}
@media (prefers-reduced-motion:reduce){.btn:active{transform:none}}
.btn--primary{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);background:var(--cocoa);color:var(--ivory);border-color:var(--cocoa)}
.btn--primary:hover{background:var(--cocoa-88);border-color:transparent}
.btn--secondary{--muted:rgba(74,57,52,.81);--faint:rgba(74,57,52,.65);background:var(--soft-pink);color:var(--cocoa);border-color:var(--soft-pink)}
.btn--secondary:hover{--muted:rgba(74,57,52,.95);--faint:rgba(74,57,52,.75);background:var(--blush);border-color:var(--blush)}
.btn--outline{background:transparent;color:var(--cocoa);border-color:var(--cocoa)}
.btn--outline:hover{background:var(--cocoa-08)}
.btn--text{min-height:44px;padding:0;border-radius:var(--r-sm);color:var(--cocoa);
  border-bottom:1px solid var(--cocoa-22);border-radius:0}
.btn--text:hover{border-bottom-color:var(--cocoa)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.42;cursor:not-allowed;pointer-events:none}
.btn--block{width:100%}

/* ==========================================================================
   Signature motif 1 — the garden-window arch
   A true semicircular top needs vertical radius = (width / 2) / height.
   Wide crops use a deliberately shallow segmental arch instead of a dome.
   ========================================================================== */
.arch{overflow:hidden;border-radius:50% 50% var(--r-md) var(--r-md) /
      var(--arch-v,34%) var(--arch-v,34%) var(--r-md) var(--r-md)}
.arch--portrait{aspect-ratio:3/4;--arch-v:37.5%}
.arch--tall{aspect-ratio:2/3;--arch-v:33.33%}
.arch--square{aspect-ratio:1/1;--arch-v:50%}
.arch--wide{aspect-ratio:3/2;--arch-v:16%}
.arch--transom{aspect-ratio:16/7;--arch-v:11%}
/* the champagne "mullion": a hairline frame set inside the arch */
.arch-frame{position:relative}
.arch-frame::after{
  content:"";position:absolute;inset:10px;pointer-events:none;
  border:1px solid var(--champagne-55);
  border-radius:50% 50% var(--r-sm) var(--r-sm) /
      var(--arch-v,34%) var(--arch-v,34%) var(--r-sm) var(--r-sm);
}

/* ==========================================================================
   Signature motif 3 — champagne hairline + sage botanical divider
   ========================================================================== */
.hairline{height:1px;background:var(--champagne);border:0;margin:0}
.divider{display:flex;align-items:center;gap:var(--s4);color:var(--sage)}
.divider::before,.divider::after{content:"";flex:1;height:1px;background:var(--champagne-55)}
/* for a page that has already spent its one or two champagne touches */
.divider--quiet::before,.divider--quiet::after{background:var(--cocoa-12)}

/* ==========================================================================
   Barely-there linen  — optional. grain + faint weave, both from cocoa.
   ========================================================================== */
.linen{
  background-color:var(--ivory);
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='220'%20height='220'%3E%3Cfilter%20id='h'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.015%200.75'%20numOctaves='2'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='matrix'%20values='0%200%200%200%200.2902%20%200%200%200%200%200.2235%20%200%200%200%200%200.2039%20%200.3%200.3%200.3%200%20-0.18'/%3E%3C/filter%3E%3Cfilter%20id='v'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.75%200.015'%20numOctaves='2'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='matrix'%20values='0%200%200%200%200.2902%20%200%200%200%200%200.2235%20%200%200%200%200%200.2039%20%200.3%200.3%200.3%200%20-0.18'/%3E%3C/filter%3E%3Cfilter%20id='g'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.9'%20numOctaves='3'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='matrix'%20values='0%200%200%200%200.2902%20%200%200%200%200%200.2235%20%200%200%200%200%200.2039%20%200.26%200.26%200.26%200%20-0.17'/%3E%3C/filter%3E%3Crect%20width='220'%20height='220'%20filter='url(%23h)'%20opacity='0.06'/%3E%3Crect%20width='220'%20height='220'%20filter='url(%23v)'%20opacity='0.06'/%3E%3Crect%20width='220'%20height='220'%20filter='url(%23g)'%20opacity='0.05'/%3E%3C/svg%3E");
  background-size:220px 220px;
}


/* ==========================================================================
   Real photography — drops into any existing .ph / .arch box without changing
   its geometry. Add .im to the box and put an <img> inside it.
   ========================================================================== */
.im{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62);position:relative;overflow:hidden;background:var(--baby-pink)}
/* <picture> is display:contents so the <img> behaves as a direct child of .im;
   without this, a `.im>img` rule would silently miss every picture-wrapped image. */
.im picture{display:contents}
.im img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  border-radius:inherit}
/* the <img> is a positioned descendant, so it paints ABOVE in-flow siblings.
   anything meant to sit over the photograph has to be lifted back. */
.im>*:not(picture):not(img){position:relative;z-index:1}
/* while a slot is still empty the tinted box shows through, so an unloaded or
   broken image degrades to the placeholder rather than to a browser icon. */
.im>img[alt]{color:transparent}

/* ==========================================================================
   Image placeholder — every shot the owner still needs to supply
   ========================================================================== */
.ph{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62);position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  background:var(--baby-pink);color:var(--cocoa);padding:var(--s4);
  min-height:120px;
}
.ph--blush{--muted:rgba(74,57,52,.95);--faint:rgba(74,57,52,.75);background:var(--blush)}
.ph__tag{font-size:var(--t-micro);font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);margin-bottom:var(--s1)}
.ph__desc{font-size:var(--t-small);line-height:1.45;max-width:34ch}
.ph__leaf{position:absolute;top:var(--s4);left:var(--s4);color:var(--sage);opacity:.9}

/* ==========================================================================
   Design-system sheet chrome (this preview only — not a website component)
   ========================================================================== */
.ds{padding:0}
.ds-sheet{max-width:1160px;margin:0 auto;padding:var(--s8) var(--gutter) var(--s9)}
.ds-head{margin-bottom:var(--s7);max-width:var(--measure)}
.ds-kicker{font-size:var(--t-micro);font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);margin-bottom:var(--s3)}
.ds-title{font-family:var(--serif);font-size:var(--t-h2);line-height:1.15;letter-spacing:-.014em}
.ds-note{margin-top:var(--s3);font-size:var(--t-small);line-height:1.65;color:var(--muted);max-width:50ch}
.ds-block{margin-top:var(--s8)}
.ds-block:first-of-type{margin-top:0}
.ds-block__title{font-family:var(--sans);font-size:var(--t-micro);font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);padding-bottom:var(--s3);
  border-bottom:1px solid var(--cocoa-12);margin-bottom:var(--s6)}
.ds-grid{display:grid;gap:var(--s5)}
.ds-caption{font-size:var(--t-micro);line-height:1.5;color:var(--muted);margin-top:var(--s3);max-width:54ch}
.ds-flag{display:inline-block;font-size:var(--t-micro);font-weight:600;letter-spacing:.06em;
  padding:3px 10px;border-radius:var(--r-pill);border:1px solid var(--cocoa-22);color:var(--cocoa)}
.ds-flag--no{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);border-color:var(--cocoa);background:var(--cocoa);color:var(--ivory)}
.ds-mono{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:12px;letter-spacing:.02em}

/* ==========================================================================
   PRINT — the menu and the FAQ are plausible print targets, and there were
   no print rules at all. Browsers default to print-color-adjust:economy, so
   backgrounds are dropped but text colours are kept: the cocoa footer loses
   its ground and prints --ivory on white paper (1.05:1). Everything in the
   "Get in touch" block — email, phone, Instagram, service area — vanishes.
   No new colours: paper white comes from `background:none`, not a new hex.
   ========================================================================== */
@media print{
  .ft{background:none;color:var(--cocoa)}
  .ft__script{color:var(--cocoa)}
  .ft a,.ft__l a,.ft__base a{color:var(--cocoa)}
  .ft__h,.ft__place,.ft__base{opacity:1;color:var(--muted)}
  /* 1px rules are painted as backgrounds, so economy mode erases every
     hairline in the system. Force just these to print. */
  .hairline,.lk__r,.vip__r,.pc__rule,.ft__rule,.trun__line,.pkc__r,.nm__r,
  .divider::before,.divider::after{background:var(--cocoa-22);print-color-adjust:exact;-webkit-print-color-adjust:exact}
  /* chrome that means nothing on paper */
  .sticky,.burger,.hd__cta,.ft__news,.sb__x,.jump{display:none}
  /* the horizontal rail would print only the visible slice */
  .trun__rail{overflow:visible;flex-wrap:wrap;padding-left:var(--gutter)}
  .sec{padding-top:var(--s6);padding-bottom:var(--s6)}
  .cat,.fqg{break-inside:avoid-page}
  .pc,.pkc{break-inside:avoid}
}

/* ==========================================================================
   FORCED COLORS (Windows High Contrast). Verified in Chromium with
   forced-colors:active. Every state carried purely by background-color is
   flattened to Canvas: .cal__d--sel, .slot-t--on, .chip[aria-pressed] and
   .ad__box--on all computed IDENTICAL to their unselected siblings, the
   .cal__d--off strike-through and the three .burger bars and the .fqi__ico
   +/- strokes all disappear entirely (they are backgrounds on a Canvas
   ground). States that already use a 2px border — .rc__o--on, .size--on,
   .mode__o--on — survive correctly and are left alone.
   ========================================================================== */
@media (forced-colors:active){
  /* icons drawn as backgrounds must be re-declared in a system colour */
  .burger span,.fqi__ico::before,.fqi__ico::after{background:CanvasText;forced-color-adjust:none}
  /* selection carried by fill must become a border/outline */
  .cal__d--sel,.slot-t--on,.chip[aria-pressed="true"]{
    outline:2px solid Highlight;outline-offset:-4px;border-color:Highlight}
  /* unavailable dates otherwise read as available */
  .cal__d--off{border-style:dashed;opacity:.6}
  .cal__d--off::before{background:CanvasText;forced-color-adjust:none}
  /* the checkmark keeps a hard-coded ivory stroke that forced-colors does not
     override — invisible on a light high-contrast Canvas */
  .ad__box--on{forced-color-adjust:none;background:Highlight;border-color:Highlight}
  .ad__box--on svg{stroke:HighlightText}
}

/* ==========================================================================
   BOUTIQUE LAYER — tokens (Sep 2026). "Same look, sharper": the printed flyers on screen —
   blush grounds, arch-topped frames, double champagne hairlines, Pinyon Script in deep rose.
   Mirrored from dist/tokens.css because the shipped stylesheet is shared.css + this file;
   tokens.css is not linked by the pages, so the values must live here to reach them.
   ========================================================================== */
:root{
  --rose:#844658;          /* 6.4:1 ivory · 5.5:1 baby pink · 5.9:1 petal — text-safe */
  --rose-soft:#B9788A;     /* decorative strokes only, never text on a light ground */
  --petal:#F4E4E2;         /* soft blush section ground */
  --paper:#FDF9F4;         /* card ground */
  --gold-line:1px solid var(--champagne);
  --r-lg:18px;
  --arch:50% 50% 14px 14px / 34% 34% 14px 14px;
  --shadow-soft:0 24px 48px -32px rgba(74,57,52,.38);
  --shadow-lift:0 30px 60px -30px rgba(74,57,52,.45);
  --sprig:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 56 22' fill='none' stroke='%238F9B7A' stroke-width='1.3' stroke-linecap='round'%3E%3Cpath d='M28 22V7'/%3E%3Cpath d='M28 15C24 15 20 12 18 8C22.5 8 26 11 28 15Z'/%3E%3Cpath d='M28 15C32 15 36 12 38 8C33.5 8 30 11 28 15Z'/%3E%3Cpath d='M28 9C25.8 6.5 25.8 3 28 .5C30.2 3 30.2 6.5 28 9Z'/%3E%3C/svg%3E");
}

/* ===== shared boutique classes (usable in any page's markup) ===== */
/* spaced-caps kicker above a heading. Rose on every light ground clears 4.5:1. */
.eyebrow{display:block;font-family:var(--sans);font-size:12px;font-weight:600;line-height:1.5;
  letter-spacing:.28em;text-transform:uppercase;color:var(--rose,#844658)}
@container vp (min-width:768px){.eyebrow{font-size:13px}}
.head>.eyebrow,.hero__t>.eyebrow{margin-bottom:calc(var(--s2) * -1)}
.on-cocoa .eyebrow,.ft .eyebrow{color:var(--champagne,#C8AD8D)}
/* the script line. Standalone it takes the script size; inside a heading it scales with it. */
.script-accent{font-family:var(--script);font-weight:400;font-style:normal;line-height:1.1;
  font-size:var(--t-script);color:var(--rose,#844658);letter-spacing:0}
:is(h1,h2,h3,h4,.t-display,.t-h1,.t-h2,.t-h3) .script-accent{font-size:1.3em;line-height:.9}
/* one emphasised word in a heading */
.em-rose{font-family:var(--serif);font-style:italic;font-weight:inherit;color:var(--rose,#844658)}
/* the flyer frame: a champagne hairline with a second one set 6px inside it */
.gold-frame{position:relative;border:1px solid var(--champagne,#C8AD8D);border-radius:var(--gf-r,2px)}
.gold-frame::after{content:"";position:absolute;inset:6px;pointer-events:none;
  border:1px solid var(--champagne-55,rgba(200,173,141,.55));border-radius:inherit}
/* arch-topped image frame. shared.css already gives .arch-frame its inset champagne mullion;
   on an element that is not already an .arch it also takes the arch shape itself. */
.arch-frame{position:relative}
.arch-frame:not(.arch){overflow:hidden;border-radius:var(--arch,50% 50% 14px 14px / 34% 34% 14px 14px)}
.arch-frame:not(.arch)::after{border-radius:50% 50% 8px 8px / 34% 34% 8px 8px}
/* a small sage sprig between two champagne hairlines. Works empty (the sprig is drawn by CSS)
   or wrapped around an inline <svg><use href="#bot-sprig"/></svg>. */
.sprig-divider{display:flex;align-items:center;justify-content:center;gap:var(--s3);
  color:var(--sage,#8F9B7A);min-height:22px;margin-inline:auto;max-width:360px}
.sprig-divider::before,.sprig-divider::after{content:"";flex:1;height:1px;background:var(--champagne,#C8AD8D);opacity:.8}
.sprig-divider:empty{gap:76px;background:var(--sprig) center/48px 19px no-repeat}
.sprig-divider svg{flex:none;width:48px;height:19px}
/* soft card: paper ground, champagne edge, lifts on hover */
.card-soft{background:var(--paper,#FDF9F4);border:1px solid var(--champagne-55,rgba(200,173,141,.55));
  border-radius:var(--r-lg,18px);box-shadow:var(--shadow-soft);
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
@media (hover:hover){.card-soft:hover{transform:translateY(-3px);box-shadow:var(--shadow-lift)}}
@media (prefers-reduced-motion:reduce){.card-soft{transition:none}.card-soft:hover{transform:none}}
/* script lines on the light grounds are rose, as on the flyers */
.page .t-script{color:var(--rose,#844658)}

/* ===== buttons: crisper pills (base rules in shared.css) ===== */
.btn{min-height:48px;letter-spacing:.02em;
  transition:background-color var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur) var(--ease),
    transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.btn--sm{min-height:44px}
.btn--primary{background:var(--cocoa);border-color:var(--cocoa);color:var(--ivory)}
.btn--primary:hover{background:var(--cocoa);border-color:var(--cocoa);transform:translateY(-1px);
  box-shadow:0 14px 26px -16px rgba(74,57,52,.7)}
.btn--secondary{background:var(--soft-pink);color:var(--cocoa);border-color:var(--champagne)}
.btn--secondary:hover{background:var(--soft-pink);border-color:var(--rose,#844658);transform:translateY(-1px);
  box-shadow:0 14px 26px -18px rgba(132,70,88,.55)}
.btn--outline{border-color:var(--champagne)}
.btn--outline:hover{border-color:var(--cocoa)}
.btn:active{transform:translateY(0);box-shadow:none}
.btn--text{border-bottom:1px solid var(--champagne);transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.btn--text:hover{color:var(--rose,#844658);border-bottom-color:var(--rose,#844658);transform:none;box-shadow:none}
@media (prefers-reduced-motion:reduce){.btn:hover{transform:none}}

/* ===== viewport container: one source, two widths ===== */
.vp{container-type:inline-size;container-name:vp;background:var(--ivory)}
/* Scale reduced 15 Sep 2026. The owner's read was that everything was too big, and the
   measurements agreed: body rendered 20px against a brief that says 16-18, h1 56, h2 44,
   and sections carried 144px of padding top AND bottom. The rule applied here is the
   brief's own — spend boldness in ONE place. --t-display and --t-script come down least
   (about 10-14%) because they carry the brand; h1, h2, h3 and body come down hard — h1 by
   30% — so they stop competing with them. Everything moved; what changed is the ratio. NOTE: --t-display/h1/h2/quote/script/lede/body are re-declared as clamp() in
   the @supports block at the bottom of this file, which WINS. Change both or neither. */
.page{--sec:64px;
  --t-display:34px;--t-h1:28px;--t-h2:24px;--t-h3:20px;--t-h4:17px;--t-quote:20px;--t-script:30px;
  --t-lede:17px;--t-body:16px;--t-small:14px;--t-micro:12px;--gutter:20px;
  color:var(--cocoa);font-size:var(--t-body);line-height:1.65}
@container vp (min-width:768px){
  .page{--sec:72px;--gutter:24px;--t-display:42px;--t-h1:32px;--t-h2:26px;--t-script:34px}}
@container vp (min-width:1100px){
  .page :is(.t-display,.t-h1,.t-h2){letter-spacing:-.01em}}
@container vp (min-width:1100px){
  /* --t-body is not restated here: it is 16px from the base rule and unchanged at 768, so a
     declaration would be a no-op implying a step that no longer happens. */
  .page{--sec:80px;--gutter:32px;--t-display:54px;--t-h1:38px;--t-h2:30px;--t-h3:21px;--t-h4:18px;
    --t-quote:26px;--t-script:38px;--t-lede:18px;--t-small:15px;--t-micro:13px}}

.wrap{max-width:var(--max);margin:0 auto;padding-left:var(--gutter);padding-right:var(--gutter)}
.sec{padding-top:var(--sec);padding-bottom:var(--sec)}
/* petal is lighter than soft pink, so the soft-pink alphas below only gain contrast */
.sec--pink{--muted:rgba(74,57,52,.81);--faint:rgba(74,57,52,.65);background:var(--petal,#F4E4E2)}
.sec--baby{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62);background:var(--baby-pink)}
.lede{font-size:var(--t-lede);line-height:1.7;color:var(--muted)}
.lede--on{color:var(--cocoa);opacity:.8}

/* ===== header ===== */
@container vp (max-width:1099.98px){
  .hd__in{padding-left:12px;padding-right:10px;gap:var(--s2)}
  .hd__cart{margin-left:auto;margin-right:2px}
  .ph-head{padding-top:var(--s5);padding-bottom:var(--s4)}
}
.hd__in{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  padding-top:10px;padding-bottom:10px}
.lk{display:inline-flex;align-items:center;gap:12px;min-height:44px;margin-left:-4px;
  color:var(--cocoa);text-decoration:none}
/* the supplied mark loses its V to the foliage below ~56px, so that is its floor */
.lk__mark{height:58px;width:auto;display:block}
@container vp (min-width:1100px){.lk__mark{height:80px}}
.lk__v{font-family:var(--serif);font-weight:500;font-size:19px;line-height:1;letter-spacing:.2em;text-indent:.2em}
.lk__r{width:100%;height:1px;background:var(--champagne);margin:5px 0 4px}
.lk__c{font-family:var(--sans);font-weight:600;font-size:10.5px;letter-spacing:.2em;text-indent:.2em;
  white-space:nowrap;line-height:1.2;max-width:8ch}
.hd__nav,.hd__cta{display:none}
/* without JS the panel cannot open, so the control is not offered */
.burger{display:none}
html.js .burger{width:44px;height:44px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;background:none;border:0;cursor:pointer;padding:0}
.burger span{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);width:20px;height:1.5px;background:var(--cocoa);border-radius:1px}
@container vp (min-width:1100px){
  .lk__c{font-size:12.5px;letter-spacing:.2em;text-indent:.2em;max-width:none}
  .hd__nav{display:flex;gap:var(--s6);list-style:none;margin:0;padding:0}
  .hd__cta{display:inline-flex}.burger,html.js .burger{display:none}
  .hd__in{padding-top:var(--s4);padding-bottom:var(--s4)}
  /* the chrome spans the screen: the mark sits at the left edge, the order and the inquiry
     button at the right, the nav centred in what is left between them */
  .hd__in{max-width:none;padding-left:clamp(20px,1.8cqw,44px);padding-right:clamp(24px,2.4cqw,56px)}
  .hd__in>nav{flex:1;display:flex;justify-content:center}}
/* one underline behaviour across the whole site: a hairline that grows from the left.
   A border that merely changes colour reads as a state; a rule that draws reads as a
   response — and it is the same gesture as the botanicals drawing themselves. */
.hd__link{position:relative;font-size:15px;font-weight:500;letter-spacing:.02em;color:var(--cocoa);
  text-decoration:none;padding:12px 0;display:inline-block}
.hd__link::after{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);content:"";position:absolute;left:0;right:0;bottom:6px;height:1px;background:var(--rose,#844658);
  transform:scaleX(0);transform-origin:left center;transition:transform var(--dur) var(--ease)}
.hd__link[aria-current="page"]{color:var(--rose,#844658)}
.hd__link:hover::after,.hd__link:focus-visible::after{transform:scaleX(1)}
.hd__link[aria-current="page"]::after{transform:scaleX(1)}
@media (prefers-reduced-motion:reduce){.hd__link::after{transition:none}}
/* the header anchors the panel it opens; it only becomes sticky at desktop, where
   there is no sticky inquiry bar to stack against */
.hd{position:relative;z-index:20;background:var(--ivory)}
.hd__in{position:relative;z-index:2}
/* anything an anchor lands on needs breathing room; at desktop it must also clear the
   sticky masthead, so the override has to come AFTER the base rule — both selectors
   have the same specificity and source order decides. */
[id]{scroll-margin-top:var(--s6)}
@container vp (min-width:1100px){
  .hd{position:sticky;top:0}
  [id]{scroll-margin-top:calc(var(--s6) + 104px)}}
/* a section focused by an anchor is a landing point, not a control */
.cat:focus,.cat:focus-visible{outline:none}
/* once the page has moved under it, the masthead needs an edge — an opaque ivory
   slab floating over a pink section reads as a rendering fault without one */
.hd::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--champagne);
  opacity:0;transition:opacity var(--dur) var(--ease)}
.hd.is-stuck::after{opacity:1}
.hd.is-stuck{background:var(--paper,#FDF9F4);box-shadow:0 12px 26px -24px rgba(74,57,52,.45)}
@media (prefers-reduced-motion:reduce){.hd::after{transition:none}}
.burger span{transition:transform var(--dur) var(--ease),opacity var(--dur-fast) var(--ease)}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

/* ===== mobile menu ===== */
.mnav{position:absolute;left:0;right:0;top:100%;background:var(--ivory);z-index:1;
  border-top:1px solid var(--champagne);box-shadow:0 18px 32px -24px rgba(74,57,52,.45)}
.mnav__in{padding-top:var(--s3);padding-bottom:var(--s5)}
.mnav__l{list-style:none;margin:0 0 var(--s4);padding:0}
.mnav{background:var(--paper,#FDF9F4)}
.mnav__l a{display:flex;align-items:center;justify-content:space-between;min-height:56px;
  font-family:var(--serif);font-size:20px;color:var(--cocoa);
  text-decoration:none;border-bottom:1px solid var(--champagne-55)}
.mnav__l a::after{content:"";width:7px;height:7px;border-top:1px solid var(--rose,#844658);
  border-right:1px solid var(--rose,#844658);transform:rotate(45deg);margin-right:6px}
.mnav__l a[aria-current="page"]{color:var(--rose,#844658);font-style:italic}
.mnav__cta{width:100%}
@container vp (min-width:1100px){.mnav{display:none}}
html.js .mnav{transform:translateY(-8px);opacity:0;
  transition:transform var(--dur) var(--ease),opacity var(--dur-fast) var(--ease)}
html.js .mnav.is-open{transform:none;opacity:1}
@media (prefers-reduced-motion:reduce){
  html.js .mnav{transition:none;transform:none;opacity:1}
  .burger span{transition:none}}

/* ===== hero ===== */
.hero{display:grid;gap:var(--s6);padding-top:var(--s6);padding-bottom:var(--sec)}
.hero__t{display:flex;flex-direction:column;align-items:flex-start;min-width:0}
/* flex-start sizes children to content; cap them so a long word wraps instead of widening */
.hero__t>*{max-width:100%}
.hero__script{display:block;margin-bottom:var(--s3);color:var(--rose,#844658)}
.hero__lede{margin-top:var(--s4);max-width:42ch}
.hero__acts{display:flex;flex-direction:column;gap:var(--s3);margin-top:var(--s6);width:100%}
.hero__acts .btn{width:100%}
.hero__f{position:relative;margin:0;width:100%;max-width:340px;align-self:center}
.hero__sprig{position:absolute;left:-20px;bottom:-28px;color:var(--sage);z-index:2;width:66px;height:66px}
@container vp (max-width:767.98px){.hero__sprig{display:none}}
/* phones get the shorter crop; the tall garden window is a desktop move */
.hero__ph{aspect-ratio:3/4;--arch-v:37.5%;padding-left:52px;box-shadow:var(--shadow-soft)}
/* the flyer's hairline arch, set up and to the right of the photograph and behind it */
.hero__f::before{content:"";position:absolute;top:-12px;left:12px;right:-12px;bottom:12px;pointer-events:none;
  border:1px solid var(--champagne);border-radius:50% 50% var(--r-md) var(--r-md) / 37.5% 37.5% var(--r-md) var(--r-md)}
@container vp (min-width:768px){
  .hero__acts{flex-direction:row;width:auto}.hero__acts .btn{width:auto}
  .hero__f{max-width:400px}
  .hero__sprig{left:-30px;bottom:-16px;width:82px;height:82px}}
@container vp (min-width:1100px){
  .hero{grid-template-columns:minmax(0,1.11fr) minmax(0,.89fr);gap:var(--s8);align-items:center;
    padding-top:var(--s8)}
  .hero__f{max-width:520px;justify-self:end}
  .hero__sprig{left:-58px;bottom:-4px;width:116px;height:116px}
  .hero__ph{aspect-ratio:2/3;--arch-v:33.33%;padding-left:80px}
  .hero__f::before{top:-18px;left:18px;right:-18px;bottom:18px;
    border-radius:50% 50% var(--r-md) var(--r-md) / 33.33% 33.33% var(--r-md) var(--r-md)}}

/* ===== what we make ===== */
.head{display:flex;flex-direction:column;gap:var(--s3);margin-bottom:var(--s7)}
.head__p{max-width:52ch}
.make{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s6) var(--s3)}
@container vp (min-width:768px){.make{gap:var(--s7) var(--s5)}}
@container vp (min-width:1100px){.make{grid-template-columns:repeat(4,1fr);gap:var(--s5)}}
.mk{display:flex;flex-direction:column;min-width:0}
.fld,textarea.fld__in{min-width:0}
.mk__box{display:block;margin-bottom:var(--s4);padding:5px;border:1px solid var(--champagne);
  border-radius:var(--arch);background:var(--paper,#FDF9F4);box-shadow:var(--shadow-soft);
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
@container vp (min-width:768px){.mk__box{padding:8px}}
@media (hover:hover){.mk:hover .mk__box{transform:translateY(-4px);box-shadow:var(--shadow-lift)}}
.mk:focus-within .mk__box{box-shadow:var(--shadow-lift)}
@media (prefers-reduced-motion:reduce){.mk__box{transition:none}.mk:hover .mk__box{transform:none}}
.mk .t-h3{margin-top:var(--s1)}
/* four equal frames on one baseline; the aspect follows the 3:4 crop the renditions are cut to */
.mk__fig{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62);width:100%;aspect-ratio:3/4;background:var(--baby-pink);border-radius:50% 50% 10px 10px / 34% 34% 10px 10px;padding:var(--s3);
  display:flex;flex-direction:column;justify-content:flex-end;gap:2px;overflow:hidden}
.mk__fig img{transition:transform var(--dur-slow) var(--ease)}
.mk:hover .mk__fig img{transform:scale(1.03)}
.mk__tag{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.mk__shot{font-size:var(--t-micro);line-height:1.4;color:var(--cocoa)}
.mk__d{font-size:var(--t-small);line-height:1.6;color:var(--muted);margin-top:var(--s2)}
.mk__l{margin-top:auto;padding-top:var(--s2);font-size:var(--t-small);font-weight:600;color:var(--cocoa);text-decoration:none;
  align-self:flex-start;min-height:44px;display:inline-flex;align-items:center}
.mk__l{letter-spacing:.02em;transition:color var(--dur) var(--ease)}
.mk:hover .mk__l,.mk__l:focus-visible{color:var(--rose,#844658)}
.mk__l span{position:relative;border-bottom:1px solid var(--champagne);padding-bottom:2px}
.mk__l span::after{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--rose,#844658);
  transform:scaleX(0);transform-origin:left center;transition:transform var(--dur) var(--ease)}
.mk:hover .mk__l span::after,.mk__l:focus-visible span::after{transform:scaleX(1)}
@media (prefers-reduced-motion:reduce){.mk__l span::after{transition:none}}

/* ===== pillars ===== */
.pill{display:grid;gap:var(--s6)}
@container vp (min-width:1100px){.pill{grid-template-columns:repeat(3,1fr);gap:0}
  .pill__i{padding:0 var(--s7);border-left:1px solid var(--champagne)}
  .pill__i:first-child{padding-left:0;border-left:0}
  .pill__i:last-child{padding-right:0}}
.pill__d{margin-top:var(--s3);color:var(--muted);font-size:var(--t-body);line-height:1.65;
  max-width:var(--measure)}
.tbd{display:inline-block;font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--cocoa);border:1px solid var(--cocoa-22);border-radius:var(--r-pill);padding:2px 9px;
  vertical-align:2px}

/* ===== story + the V·I·P reveal ===== */
.story{display:grid;gap:var(--s7)}
@container vp (min-width:1100px){.story{grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
  gap:var(--s9);align-items:center}}
.story__f{margin:0;width:100%;max-width:300px}
@container vp (min-width:1100px){.story__f{max-width:100%}}
.vip{max-width:330px;margin-bottom:var(--s6)}
@container vp (min-width:1100px){.vip{max-width:420px}}
.vip__row{display:flex}
.vip__c{flex:1;text-align:center}
.vip__i{font-family:var(--serif);font-size:44px;font-weight:400;line-height:1;letter-spacing:.02em;
  display:block}
@container vp (min-width:1100px){.vip__i{font-size:58px}}
.vip__r{height:1px;background:var(--champagne);border:0;margin:var(--s3) 0}
.vip__w{font-family:var(--sans);font-size:10px;font-weight:600;letter-spacing:.2em;text-indent:.2em;
  text-transform:uppercase;color:var(--muted);display:block}
@container vp (min-width:1100px){.vip__w{font-size:12px}}

/* ===== steps ===== */
.steps{display:grid;gap:var(--s6)}
@container vp (min-width:768px){.steps{grid-template-columns:repeat(3,1fr);gap:var(--s5)}}
@container vp (min-width:1100px){.steps{gap:var(--s7)}}
/* .st is also the About page's story wrapper, so the base rule stays as it was and the
   step cards are scoped to the home list */
.st{border-top:1px solid var(--cocoa-22);padding-top:var(--s4)}
.steps>.st{--muted:rgba(74,57,52,.74);position:relative;background:var(--paper,#FDF9F4);
  border:1px solid var(--champagne-55);border-radius:var(--r-lg,18px);padding:var(--s5) var(--s4);
  box-shadow:var(--shadow-soft)}
@container vp (min-width:1100px){.steps>.st{padding:var(--s6) var(--s5)}}
/* was opacity:.26 — which rendered 1.55:1 on baby pink, i.e. not always visible.
   --faint is defined per ground and never drops below 3.2:1 for large type. */
.st__n{font-family:var(--serif);font-style:italic;font-size:36px;line-height:1;color:var(--rose,#844658);display:block;
  margin-bottom:var(--s3);padding-bottom:var(--s3);border-bottom:1px solid var(--champagne-55);
  font-variant-numeric:tabular-nums}
@container vp (min-width:1100px){.st__n{font-size:46px}}
.st__d{margin-top:var(--s2);font-size:var(--t-small);line-height:1.6;color:var(--muted);}

/* ===== gallery preview ===== */
.gal{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s3)}
.gt{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62);background:var(--baby-pink);border-radius:var(--r-md);padding:var(--s3);display:flex;
  align-items:flex-end;border:0;font:inherit;color:var(--cocoa);cursor:pointer;text-align:left;
  aspect-ratio:4/5;min-height:44px}
.gt span{font-size:11px;line-height:1.4;color:var(--muted)}
.gt:hover span{color:var(--cocoa)}
.gt--w{grid-column:span 2;aspect-ratio:16/9}
@container vp (min-width:1100px){
  .gal{grid-template-columns:repeat(6,1fr);gap:var(--s4)}
  .gt{aspect-ratio:auto}
  .g1{grid-column:span 2;aspect-ratio:4/5}.g2{grid-column:span 4;aspect-ratio:5/3}
  .g3{grid-column:span 4;aspect-ratio:5/3}.g4{grid-column:span 2;aspect-ratio:4/5}
  .g5{grid-column:span 3;aspect-ratio:2/1}.g6{grid-column:span 3;aspect-ratio:2/1}}
.gal__foot{display:flex;flex-wrap:wrap;gap:var(--s4);align-items:center;margin-top:var(--s6)}

/* ===== kind words ===== */
.kw{max-width:660px;margin:0 auto;text-align:center;display:flex;flex-direction:column;
  align-items:center;gap:var(--s4)}
.sample{display:inline-flex;font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--cocoa);border:1px solid var(--cocoa-22);border-radius:var(--r-pill);padding:4px 11px}
.attr{font-size:var(--t-small);color:var(--muted);line-height:1.6}
.attr b{color:var(--cocoa);font-weight:600}

/* ===== closing band ===== */
/* the closing band is a fixed short shape wherever it appears, so it takes its own
   tighter rhythm rather than the rhythm of a section that might be 1200px tall */
.cta{text-align:center;--sec:72px}
@container vp (min-width:1100px){.cta{--sec:88px}}
.cta{background:var(--petal,#F4E4E2)}
.cta__in{position:relative;width:calc(100% - 2 * var(--gutter));max-width:760px;margin:0 auto;
  display:flex;flex-direction:column;align-items:center;gap:var(--s4);
  padding:var(--s7) var(--s4);background:var(--paper,#FDF9F4);border:1px solid var(--champagne);
  border-radius:2px;box-shadow:var(--shadow-soft)}
.cta__in::after{content:"";position:absolute;inset:6px;border:1px solid var(--champagne-55);pointer-events:none}
.cta__in .btn--primary{width:100%}
@container vp (min-width:560px){.cta__in .btn--primary{width:auto;min-width:220px}}
@container vp (min-width:768px){.cta__in{padding:var(--s8) var(--s7)}}
.cta__alt{font-size:var(--t-small);color:var(--muted);}
.cta__alt a{color:var(--cocoa);text-decoration:none;border-bottom:1px solid var(--champagne);
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.cta__alt a:hover{color:var(--rose,#844658);border-bottom-color:var(--rose,#844658)}

/* ===== footer ===== */
.ft{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);position:relative;background:var(--cocoa);color:var(--ivory);padding-top:var(--s7);padding-bottom:var(--s4)}
/* the flyer's double rule across the top edge */
.ft::before{content:"";position:absolute;left:0;right:0;top:8px;height:4px;pointer-events:none;
  border-top:1px solid rgba(200,173,141,.7);border-bottom:1px solid rgba(200,173,141,.35)}
.ft__top{display:grid;gap:var(--s5)}
@container vp (min-width:1100px){.ft__top{grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);gap:var(--s8);
  align-items:start}}
.ft__brand{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3) var(--s4)}
.ft__logo{height:64px;width:auto;display:block}
@container vp (min-width:1100px){.ft__logo{height:72px}}
.ft__script{font-family:var(--script);font-size:34px;line-height:1;color:var(--soft-pink);display:block}
@container vp (min-width:1100px){.ft__script{font-size:38px}}
.ft__place{color:var(--muted);flex-basis:100%;font-size:var(--t-small);line-height:1.5;max-width:34ch}
.ft__col{display:flex;flex-direction:column;gap:var(--s2)}
.ft__l{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;column-gap:var(--s5);row-gap:0}
/* pending (unlinked) items sit on the same 44px row as the live links */
.ft__l li{display:flex;align-items:center;min-height:44px}
.ft__l a,.ft__l .pending{color:var(--ivory);text-decoration:none;font-size:var(--t-small);display:inline-flex;
  align-items:center;min-height:44px;border-bottom:1px solid transparent}
.ft__l a{position:relative}
.ft__l a::after{content:"";position:absolute;left:0;right:0;bottom:10px;height:1px;background:var(--champagne);
  transform:scaleX(0);transform-origin:left center;transition:transform var(--dur) var(--ease)}
.ft__l a:hover::after,.ft__l a:focus-visible::after{transform:scaleX(1)}
@media (prefers-reduced-motion:reduce){.ft__l a::after{transition:none}}
.ft__l--quiet li{opacity:.82}
/* the newsletter input's intrinsic size (default ~size=20) is the grid track's
   min-content floor; without min-width:0 it pushes the whole footer past the
   viewport at 200% text zoom (WCAG 1.4.4). */
.ft__news{min-width:0;margin-top:var(--s2)}
.ft__news label{display:block;font-size:12px;font-weight:600;letter-spacing:.24em;text-transform:uppercase;
  color:var(--champagne);margin-bottom:var(--s2)}
.ft__news p{color:var(--muted);font-size:var(--t-micro);line-height:1.5;margin-top:var(--s2)}
.ft__field{display:flex;flex-direction:column;gap:var(--s3);max-width:440px}
@container vp (min-width:768px){.ft__field{flex-direction:row;gap:var(--s2)}}
.ft__in{flex:1;min-width:0;width:100%;height:48px;min-height:48px;padding:0 var(--s4);border-radius:var(--r-pill);
  border:1px solid rgba(200,173,141,.7);background:transparent;color:var(--ivory);
  font-family:var(--sans);font-size:15px}
.ft__in::placeholder{color:rgba(250,245,237,.55)}
.ft__btn{height:48px;padding:0 var(--s5);border-radius:var(--r-pill);border:1px solid var(--soft-pink);
  background:var(--soft-pink);color:var(--cocoa);font-family:var(--sans);font-size:15px;font-weight:600;letter-spacing:.02em;
  cursor:pointer;transition:background-color var(--dur) var(--ease)}
.ft__btn:hover{background:var(--ivory)}
.ft__rule{height:1px;background:var(--champagne);opacity:.7;margin:var(--s5) 0 var(--s3);border:0}
.ft__base{color:var(--muted);display:flex;flex-direction:column;gap:var(--s1);font-size:var(--t-micro);}
@container vp (min-width:1100px){.ft__base{flex-direction:row;flex-wrap:wrap;justify-content:space-between;
  align-items:center;gap:var(--s2) var(--s5)}}
.ft__base a{color:var(--ivory);text-decoration-color:var(--champagne);text-underline-offset:3px;
  display:inline-flex;align-items:center;min-height:44px}

/* ===== sticky inquiry bar — phones only ===== */
.sticky{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);position:sticky;bottom:0;z-index:9;background:var(--cocoa);color:var(--ivory);
  display:flex;align-items:center;justify-content:center;height:56px;font-size:15px;font-weight:600;
  letter-spacing:.04em;text-decoration:none;border-top:1px solid var(--champagne)}
@container vp (min-width:768px){.sticky{display:none}}

/* ===== the one orchestrated moment: page load ===== */
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes settle{from{opacity:0;transform:scale(1.015)}to{opacity:1;transform:none}}
@keyframes drawin{to{stroke-dashoffset:0}}
.a1{animation:rise 520ms var(--ease) 120ms both}
@keyframes write{from{clip-path:inset(-10% 100% -20% 0)}to{clip-path:inset(-10% -2% -20% 0)}}
.hero__script.a1{animation:write 1100ms var(--ease) 140ms both}
.a2{animation:rise 600ms var(--ease) 260ms both}
.a3{animation:rise 520ms var(--ease) 440ms both}
.a4{animation:settle 640ms var(--ease) 300ms both}
.draw path{stroke-dasharray:1;stroke-dashoffset:1;animation:drawin 820ms var(--ease) both}
.draw path:nth-of-type(1){animation-duration:1150ms;animation-delay:760ms}
.draw path:nth-of-type(2){animation-delay:1300ms}
.draw path:nth-of-type(3){animation-delay:1420ms}
.draw path:nth-of-type(4){animation-delay:1540ms}
.draw path:nth-of-type(5){animation-delay:1660ms}
.draw path:nth-of-type(6){animation-delay:1780ms}
@media (prefers-reduced-motion:reduce){
  .a1,.a2,.a3,.a4,.hero__script.a1{animation:none}
  .draw path{stroke-dashoffset:0;animation:none}}

/* ===== between pages: a short cross-document view transition ===== */
/* the header is named so it holds still while the page beneath it changes */
@view-transition{navigation:auto}
.hd{view-transition-name:hd}
@keyframes vt-out{to{opacity:0;transform:translateY(-8px)}}
@keyframes vt-in{from{opacity:0;transform:translateY(12px)}}
::view-transition-old(root){animation:vt-out 220ms var(--ease) both}
::view-transition-new(root){animation:vt-in 420ms var(--ease) 80ms both}
::view-transition-group(hd){animation-duration:0s}
@media (prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}

/* ===== on the landing page: things arrive as you reach them (once, JS-driven) =====
   Nothing here applies without the .js flag, so the page is whole without JavaScript. */
html.js [data-reveal]{opacity:0;transform:translateY(12px);
  transition:opacity 420ms var(--ease),transform 420ms var(--ease);
  transition-delay:calc(var(--i,0) * 45ms)}
/* the wipe is an ivory curtain drawn up off the frame, not a clip-path: Chromium's
   IntersectionObserver and lazy-loading both honour clip-path, so a fully clipped
   frame would never intersect and its image would never load */
html.js [data-reveal="wipe"]{opacity:1;transform:none}
html.js [data-reveal="wipe"] .arch::after{content:"";position:absolute;inset:-1px;z-index:2;
  background:var(--ivory);transform-origin:top;transition:transform 620ms var(--ease) 40ms}
html.js .is-in[data-reveal="wipe"] .arch::after{transform:scaleY(0)}
html.js [data-reveal="line"]{transform:scaleX(0);transform-origin:left center;opacity:1;
  transition-duration:720ms}
/* the element itself does not move; only its own ::after responds to .is-in */
html.js [data-reveal="line-only"]{opacity:1;transform:none;transition:none}
html.js [data-reveal="drop"]{transform:translateY(22px)}
html.js .is-in[data-reveal]{opacity:1;transform:none}
/* the run tiles keep their own transform hover; lift after they have arrived */
.tr{transition:transform var(--dur) var(--ease),background-color var(--dur) var(--ease)}
.tr:hover{transform:translateY(-4px)}
/* ===== the About page's one orchestrated moment: the signature inks itself in =====
   Her letter builds to this phrase and the paragraph under it is ABOUT the phrase, so the
   line is the subject and earns the motion. A soft-edged gradient mask, 2.6x the width of
   the text, slides across it: the letters arrive left to right in the order a hand would
   write them, rather than fading in as a block. A fine sage sprig draws itself underneath,
   320ms later, so the two read as one gesture instead of two effects.

   Keyed off .is-in and NOT off [data-reveal="ink"], deliberately: the observer strips the
   attribute at the first transitionend (~600ms, the mask), and an attribute-keyed rule
   would drop the sprig's dasharray mid-draw and snap it to full. .is-in is added once and
   never removed, so both finish.

   stroke-dasharray/-dashoffset are INHERITED SVG properties, which is what lets them reach
   the paths inside <use>'s shadow tree — CSS selectors cannot. 44 is comfortably longer
   than the longest path in #bot-sprig (the stem is 15 units, the leaves about 24), so the
   whole sprig is hidden at full offset.

   The mask geometry is load-bearing and was wrong on the first pass. With mask-size 250%
   and the transparent stop at 52%, the mask is 2.5x the text width and its opaque end sits
   at 1.0x — so at mask-position 100% the whole line is genuinely hidden, and at 0% the whole
   line is genuinely opaque. The first attempt used 260%/68%, which put the transparent
   boundary only 0.17x in: 83% of the letters were already partly visible before the sweep
   started, and the whole thing read as a fade rather than as a hand crossing the line.
   Measured frame by frame, not eyeballed. */
html.js [data-reveal="ink"]{opacity:1;transform:none;transition:none}
html.js .st-script .t-script{
  -webkit-mask-image:linear-gradient(90deg,#000 0 40%,rgba(0,0,0,.5) 46%,transparent 52% 100%);
          mask-image:linear-gradient(90deg,#000 0 40%,rgba(0,0,0,.5) 46%,transparent 52% 100%);
  -webkit-mask-size:250% 100%;        mask-size:250% 100%;
  -webkit-mask-repeat:no-repeat;      mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;       mask-position:100% 0;
  transition:-webkit-mask-position 820ms var(--ease), mask-position 820ms var(--ease)}
html.js .st-script.is-in .t-script{-webkit-mask-position:0 0;mask-position:0 0}
html.js .st-script .st-sprig{stroke-dasharray:44;stroke-dashoffset:44;
  transition:stroke-dashoffset 560ms var(--ease) 320ms}
html.js .st-script.is-in .st-sprig{stroke-dashoffset:0}

@media (prefers-reduced-motion:reduce){
  html.js [data-reveal]{opacity:1;transform:none;transition:none}
  html.js [data-reveal="wipe"] .arch::after{content:none}
  html.js .st-script .t-script{-webkit-mask-image:none;mask-image:none;transition:none}
  html.js .st-script .st-sprig{stroke-dasharray:none;stroke-dashoffset:0;transition:none}
  .tr:hover{transform:none}}

/* ===== shared interior-page furniture ===== */
/* ===== page head ===== */
.ph-head{padding-top:var(--s7);padding-bottom:var(--s7)}
@container vp (min-width:1100px){.ph-head{padding-top:var(--s8);padding-bottom:var(--s8)}}
.ph-head__l{max-width:52ch;margin-top:var(--s4)}
.ph-rule{height:1px;background:var(--champagne);border:0;margin-top:var(--s7)}

/* ===== filters ===== */
.fl{display:flex;flex-direction:column;gap:var(--s3);margin-top:var(--s6)}
@container vp (min-width:768px){.fl{flex-direction:row;flex-wrap:wrap;gap:var(--s5)}}
.fl__g{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center}
.fl__lab{font-size:var(--t-small);color:var(--muted);margin-right:var(--s1)}
.chip{min-height:44px;padding:0 var(--s4);border-radius:var(--r-pill);border:1px solid var(--cocoa-22);
  background:none;color:var(--cocoa);font-family:var(--sans);font-size:15px;cursor:pointer;
  display:inline-flex;align-items:center;transition:background-color var(--dur) var(--ease)}
@media (hover:hover){.chip:hover{background:var(--cocoa-08)}}
.chip[aria-pressed="true"]{--muted:rgba(250,245,237,.72);--faint:rgba(250,245,237,.55);background:var(--cocoa);color:var(--ivory);border-color:var(--cocoa)}

/* state-demonstration divider (used on Inquire and Gallery sheets) */

.state{margin-top:var(--s9);padding-top:var(--s7);border-top:1px solid var(--champagne)}
.state__cap{font-size:var(--t-micro);font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);display:block;margin-bottom:var(--s5)}

/* dietary tags — the one place Deep Sage is used as type */
.pc__tags{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s1)}
.diet{font-size:var(--t-micro);font-weight:600;letter-spacing:.03em;color:var(--deep-sage);
  border:1px solid var(--deep-sage);border-radius:var(--r-pill);padding:3px 10px}

/* form field primitives (Inquire, and the ordering concept) */
.fld{display:flex;flex-direction:column;gap:var(--s2);margin-bottom:var(--s5)}
.fld__lab{font-size:14px;font-weight:600;letter-spacing:.02em}
.fld__opt{font-weight:400;color:var(--muted)}
.fld__hint{font-size:var(--t-micro);line-height:1.5;color:var(--muted)}
/* An allergen disclosure is not a hint. It rendered at 12px on --t-micro, the smallest text
   on the page, and it is the one sentence on this form with consequences for a guest. */
.fld__note{font-size:var(--t-body);line-height:1.6;color:var(--cocoa)}
.fld__in{height:52px;min-height:52px;padding:0 var(--s3);border:1px solid var(--cocoa-22);border-radius:var(--r-sm);
  background:var(--ivory);color:var(--cocoa);font-family:var(--sans);font-size:16px;width:100%}
.fld__in::placeholder{color:var(--faint)}
textarea.fld__in{height:auto;min-height:120px;padding:var(--s3);line-height:1.6;resize:vertical}

/* ==========================================================================
   LARGE DISPLAYS — the design was capping at 1200px, so at 2560 more than half
   the screen was empty margin and the hero arch stayed a 473px card. Type,
   space and the arch all step up; the body measure never does.
   ========================================================================== */
@container vp (min-width:1600px){
  .page{--max:1240px;--gutter:40px;--sec:88px;
    --t-display:68px;--t-h1:42px;--t-h2:32px;--t-h3:22px;--t-h4:19px;
    /* --t-lede and --t-small are not restated: both already hold their final value from the
       1100 band. Before the reduction they stepped 19->20 and 15->16; now they do not. */
    --t-quote:28px;--t-script:44px;--t-body:17px;--t-micro:13px}
  /* the hero breaks the grid: the arch runs toward the right edge, so it reads
     as a window in a wall rather than a card on a page */
  .hero{max-width:none;grid-template-columns:minmax(0,1fr) auto;gap:var(--s9);
    padding-left:max(var(--gutter), calc((100cqw - var(--max))/2 + var(--gutter)));
    padding-right:var(--s9)}
  .hero__f{width:clamp(600px, -40px + 40cqi, 760px);max-width:none}
  .hero__sprig{left:-78px;bottom:-6px;width:148px;height:148px}
  /* the chrome frames the hero: same left edge as every section, same right edge as the arch */

  .trun__rail{gap:var(--s5)}
  .vip__i{font-size:70px}
  .st__n{font-size:56px}
  .ft__script{font-size:54px}
}
@container vp (min-width:2000px){
  .page{--max:1280px;--sec:96px;--t-display:74px;--t-h1:46px;--t-h2:34px;--t-script:48px}
  .hero__f{width:760px;max-width:none}
  .hero{gap:var(--s10)}
  .hero__sprig{left:-88px;width:168px;height:168px}
  .vip__i{font-size:78px}
  .ft__script{font-size:60px}
}

/* ==========================================================================
   FLUID TYPE — an ADDITIVE, @supports-guarded layer.
   The stepped px ladder above is the fallback and stays exactly as it is. On an
   engine without container queries, `cqi` is invalid at computed-value time, so
   font-size would fall back to *inherit* (not to the px value) — a display
   headline would render at 16px and the hierarchy would invert. Guarding the
   whole layer means old engines simply never see it and keep today's ladder.
   (A var() fallback does NOT help: it fires on unset, not on invalid-at-
   computed-value.)
   Each tier carries the segment from its own breakpoint to the next:
     anchors (W1,S1)->(W2,S2):  m = (S2-S1)/(W2-W1)
                                clamp(S1, (S1 - m*W1)px + (100*m)cqi, S2)
   so every art-directed anchor is still hit exactly; only the flat stretches
   between them now interpolate. h3/h4/small/micro stay stepped on purpose —
   under 4px of travel across the whole ladder.
   ========================================================================== */
@supports (font-size: clamp(1px, 1cqi, 2px)){
  .page{
    --t-display:clamp(34px, 26.366px + 2.0356cqi, 42px);
    --t-h1:clamp(28px, 24.183px + 1.0178cqi, 32px);
    --t-h2:clamp(24px, 22.092px + 0.5089cqi, 26px);
    --t-script:clamp(30px, 26.183px + 1.0178cqi, 34px)}
  @container vp (min-width:768px){
    .page{
      --t-display:clamp(42px, 14.241px + 3.6145cqi, 54px);
      --t-h1:clamp(32px, 18.12px + 1.8072cqi, 38px);
      --t-h2:clamp(26px, 16.747px + 1.2048cqi, 30px);
      --t-quote:clamp(20px, 6.12px + 1.8072cqi, 26px);
      --t-script:clamp(34px, 24.747px + 1.2048cqi, 38px);
      --t-lede:clamp(17px, 14.687px + 0.3012cqi, 18px)}}
  @container vp (min-width:1100px){
    .page{
      --max:clamp(1200px, 1112px + 8cqi, 1240px);
      --t-display:clamp(54px, 23.2px + 2.8cqi, 68px);
      --t-h1:clamp(38px, 29.2px + 0.8cqi, 42px);
      --t-h2:clamp(30px, 25.6px + 0.4cqi, 32px);
      --t-quote:clamp(26px, 21.6px + 0.4cqi, 28px);
      --t-script:clamp(38px, 24.8px + 1.2cqi, 44px);
      --t-body:clamp(16px, 13.8px + 0.2cqi, 17px)}}
  @container vp (min-width:1600px){
    .page{
      --max:clamp(1240px, 1080px + 10cqi, 1280px);
      --t-display:clamp(68px, 44px + 1.5cqi, 74px);
      --t-h1:clamp(42px, 26px + 1cqi, 46px);
      --t-h2:clamp(32px, 24px + 0.5cqi, 34px);
      --t-script:clamp(44px, 28px + 1cqi, 48px)}}
  @container vp (min-width:2000px){.page{--max:1280px}}
}


/* ==========================================================================
   THE TABLE RUN
   "A long table laid end to end with food ... arranged with greenery and height."
   The brand's own description of a grazing table, rendered as layout: pieces of
   varying height sitting on one champagne line that runs off both edges of the
   screen. Full bleed, swipeable, and it is the site's most distinctive element
   precisely where there is room for it.
   ========================================================================== */
.trun{position:relative;padding-bottom:1px;--tr-w:210px;--tr-h:300px}
@container vp (min-width:768px){.trun{--tr-w:250px;--tr-h:360px}}
@container vp (min-width:1100px){.trun{--tr-w:280px;--tr-h:420px}}
@container vp (min-width:1600px){.trun{--tr-w:330px;--tr-h:500px}}
@container vp (min-width:2000px){.trun{--tr-w:370px;--tr-h:560px}}
.trun__rail{display:flex;align-items:flex-end;gap:var(--s4);overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x proximity;scrollbar-width:thin;
  overscroll-behavior-x:contain;scroll-padding-inline:var(--gutter);
  padding:0 var(--gutter) 0 max(var(--gutter), calc((100cqw - var(--max))/2 + var(--gutter)))}
.trun__rail::-webkit-scrollbar{height:6px}
.trun__rail::-webkit-scrollbar-thumb{background:var(--cocoa-22);border-radius:3px}
.trun__rail:focus-visible{outline:2px solid var(--cocoa);outline-offset:4px;border-radius:var(--r-sm)}
/* the rail has overflow-y:hidden and zero block padding, and .tr sits flush to
   the content-box bottom (align-items:flex-end), so the shared 3px-offset focus
   ring is clipped on the bottom edge — and on the top edge for the tallest tile.
   Draw the ring inside instead. (WCAG 2.4.11 Focus Not Obscured.) */
.tr:focus-visible{outline-offset:-4px}
.tr{--muted:rgba(74,57,52,.77);--faint:rgba(74,57,52,.62);flex:none;margin:0;scroll-snap-align:center;
  width:calc(var(--w,1) * var(--tr-w));height:calc(var(--h,1) * var(--tr-h));
  background:var(--baby-pink);border-radius:var(--r-md) var(--r-md) 0 0;
  padding:var(--s3);display:flex;align-items:flex-end;border:0;font:inherit;color:var(--cocoa);
  text-align:left;cursor:pointer;overflow:hidden;transition:background-color var(--dur) var(--ease)}
.tr span{font-size:11px;line-height:1.4;color:var(--muted)}
.tr:hover span{color:var(--cocoa)}
/* one arched piece per run, never more */
.tr--arch{--muted:rgba(74,57,52,.95);--faint:rgba(74,57,52,.75);background:var(--blush);
  border-radius:50% 50% 0 0 / 34% 34% 0 0}
.trun__line{position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--champagne);border:0;
  margin:0;pointer-events:none}
.trun__foot{display:flex;flex-wrap:wrap;gap:var(--s4);align-items:center;margin-top:var(--s6)}
/* "Take a look": a clean, even grid — every tile the same size, same top and bottom
   edge, nothing cut off at the screen edge. (Replaces the staggered sideways run.) */
.trun__rail{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;overflow:visible;
  padding:0 var(--gutter);max-width:var(--max);margin:0 auto;scroll-snap-type:none}
@container vp (min-width:768px){.trun__rail{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s4)}}
.trun__rail .tr{width:auto;height:auto;aspect-ratio:4/5;padding:0;border-radius:var(--r-lg,18px);
  position:relative;box-shadow:0 18px 36px -28px rgba(74,57,52,.45)}
.trun__rail .tr picture,.trun__rail .tr img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.trun__rail .tr::after{content:"";position:absolute;inset:6px;border:1px solid rgba(250,245,237,.7);
  border-radius:calc(var(--r-lg,18px) - 5px);pointer-events:none}
@container vp (max-width:767.98px){.trun__rail .tr:nth-child(n+7){display:none}}
.trun__line{display:none}
/* ===== the cart =====
   Present at EVERY width and whether or not it holds anything. It used to be a text link
   reading "Your order · 2", hidden until something was in it and only shown at >=1100px —
   so a visitor arriving with an empty basket had no way to see that ordering existed at all,
   and the one clue appeared only after they had already found a product page. A basket
   outline with a count is the thing people look for, so it is always there.

   It also read "Yourorder ·1": the link was display:inline-flex, which turns the whitespace
   between its inline children into dropped flex items. The label is gone now, but the lesson
   stays — this component keeps its spacing in `gap`, never in stray text nodes. */
.hd__cart{display:inline-flex;align-items:center;gap:var(--s2);min-height:44px;padding:0 var(--s3);
  margin-right:var(--s3);border:1px solid var(--champagne);border-radius:var(--r-pill);
  color:var(--cocoa);text-decoration:none;
  transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.hd__cart:hover{background:var(--petal,#F4E4E2);border-color:var(--rose,#844658)}
.hd__cart-i{flex:none;color:var(--cocoa)}
.hd__cart-n{font-family:var(--sans);font-size:var(--t-small);font-weight:500;
  font-variant-numeric:tabular-nums;min-width:1ch;text-align:center}
/* Holding something is worth saying quietly: cocoa on soft pink is about 7:1. */
.hd__cart.is-full{background:var(--soft-pink);border-color:var(--soft-pink)}
.hd__cart.is-full:hover{border-color:var(--cocoa)}
@container vp (min-width:1100px){.hd__cart{margin-right:var(--s4)}}
@container vp (max-width:1099.98px){.hd__cart{margin-right:2px}}
@media (prefers-reduced-motion:reduce){.hd__cart{transition:none}}

/* ===== quantity stepper + add-to-order ===== */
/* Same border/radius/tap-target logic as the .qty component on the order page — quiet
   pill outline, no new hues. Both buttons and the number all clear the 44px floor. */
.buy--add{display:flex;flex-direction:column;gap:var(--s3)}
.qty{display:inline-flex;align-items:center;border:1px solid var(--cocoa-22);border-radius:var(--r-pill);
  width:fit-content}
.qty__b{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:44px;height:44px;padding:0;background:none;border:0;border-radius:var(--r-pill);
  font-family:var(--sans);font-size:18px;line-height:1;color:var(--cocoa);cursor:pointer;
  transition:background-color var(--dur) var(--ease),transform var(--dur) var(--ease)}
.qty__b:hover{background:var(--cocoa-08)}
.qty__b:active{transform:translateY(1px)}
@media (prefers-reduced-motion:reduce){.qty__b:active{transform:none}}
.qty__n{min-width:32px;text-align:center;font-variant-numeric:tabular-nums;font-weight:500;
  font-family:var(--sans);font-size:var(--t-small);color:var(--cocoa)}
.buy__add{width:100%}
@container vp (min-width:560px){.buy__add{width:auto}}

/* ===== home: find your size — seats at the table (motion.html) =====
   Plain list by default (no JS / reduced motion); .szt--live swaps in the pinned table. */
.szt__scrub{display:none}
.szt__list{list-style:none;margin:0;padding:0;display:grid;gap:var(--s7)}
@container vp (min-width:768px){.szt__list{grid-template-columns:repeat(2,1fr);gap:var(--s8) var(--s6)}}
@container vp (min-width:1100px){.szt__list{grid-template-columns:repeat(3,1fr)}}
.szt__li{display:grid;gap:var(--s2);align-content:start}
.szt__lf{--arch-v:40%;aspect-ratio:4/5;border-radius:50% 50% 8px 8px/40% 40% 8px 8px;overflow:hidden;margin-bottom:var(--s3)}
.szt__lf img{width:100%;height:100%;object-fit:cover}
.szt__lk{font-size:var(--t-micro);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.szt__lk span{font-family:var(--serif);font-style:italic;font-weight:400;font-size:28px;letter-spacing:0;color:var(--deep-rose);margin-right:8px}
.szt__ll{color:var(--muted)}
.szt__lp{font-weight:500;font-variant-numeric:tabular-nums}
.szt__acts,.szt__row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3) var(--s4)}
@container vp (max-width:559.98px){
  .szt__list{gap:0}
  .szt__li{grid-template-columns:112px minmax(0,1fr);column-gap:var(--s4);row-gap:3px;align-items:start;
    padding:var(--s4) 0;border-bottom:1px solid var(--champagne-55,rgba(200,173,141,.55))}
  .szt__li:first-child{padding-top:0}
  .szt__li:last-child{border-bottom:0}
  .szt__lf{grid-row:1 / span 6;grid-column:1;margin:0;aspect-ratio:4/5}
  .szt__li > :not(.szt__lf){grid-column:2}
  .szt__lk span{font-size:22px}
  .szt__li h3{font-size:19px;line-height:1.2}
  .szt__ll{font-size:14px;line-height:1.45}
  .szt__acts{gap:8px 14px;margin-top:6px}
  .szt__acts .btn{min-height:44px;padding:0 18px}
  .szt__acts .btn--text{display:none}
}
.szt__ln{color:inherit;text-decoration:none}
.szt__ln:hover,.szt__ln:focus-visible{color:var(--rose,#844658)}
/* every size card shares the same six rows (photo, label, name, line, price, actions),
   so names, descriptions, prices and buttons line up across a row whatever the copy length */
@container vp (min-width:560px){
  .szt__list{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--s5);row-gap:var(--s8)}
  .szt__li{grid-row:span 6;display:grid;grid-template-rows:subgrid;row-gap:var(--s2)}
  .szt__lf{margin-bottom:var(--s2)}
  .szt__ll{align-self:start}
  .szt__acts{align-self:start}
}
@container vp (min-width:1100px){
  .szt__list{grid-template-columns:repeat(5,minmax(0,1fr));column-gap:var(--s4)}
  .szt__li h3{font-size:22px;line-height:1.2}
  .szt__acts{gap:var(--s2) var(--s3)}
}

.szt--live .szt__list{display:none}
.szt--live .szt__scrub{display:block;height:620vh;position:relative}
.szt__pin{position:sticky;top:var(--szt-top,0px);height:calc(100vh - var(--szt-top,0px));height:calc(100svh - var(--szt-top,0px));overflow:hidden}
.szt__stage{position:absolute;inset:0;--FW:min(calc(100% - 2 * var(--gutter)),1560px);--FH:min(calc(100% - 48px),940px)}
.szt__layer,.szt__ui{position:absolute;left:50%;top:50%;width:var(--FW);height:var(--FH);transform:translate(-50%,-50%)}
.szt__layer{overflow:hidden;background:var(--cocoa);contain:layout paint;clip-path:inset(50% 50% 50% 50%)}
.szt__layer:first-child{clip-path:inset(0 round 24px)}
.szt__layer picture,.szt__layer .szt__w,.szt__layer .szt__tall{position:absolute;inset:0}
.szt__layer img{width:100%;height:100%;object-fit:cover;will-change:transform;backface-visibility:hidden}
.szt__shade{will-change:opacity}
.szt__tall{display:none}
.szt__shade{position:absolute;inset:0;background:linear-gradient(180deg,rgba(34,24,21,0) 45%,rgba(34,24,21,.7) 100%);pointer-events:none}
.szt__ui{z-index:20;color:var(--ivory);pointer-events:none}
.szt__bars{pointer-events:auto}
.szt__cap{position:absolute;left:clamp(20px,3vw,56px);right:clamp(20px,3vw,56px);bottom:clamp(64px,9vh,96px);
  display:flex;justify-content:space-between;align-items:flex-end;gap:var(--s5);opacity:0;will-change:opacity,transform}
.szt__cap:first-child{opacity:1}
.szt__t{display:grid;gap:4px;justify-items:start}
.szt__no{font-family:var(--serif);font-style:italic;font-size:clamp(24px,2.4vw,44px);line-height:1;color:var(--soft-pink)}
.szt__name{font-family:var(--serif);font-size:clamp(32px,4.2vw,76px);line-height:1.02;margin:0;color:var(--ivory)}
.szt__meta{font-size:clamp(14px,1.05vw,19px);margin:0;opacity:.92}
.szt__row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3) var(--s4);margin-top:var(--s3)}
.szt__price{font-weight:500;font-variant-numeric:tabular-nums}
.szt__order{background:var(--ivory);color:var(--cocoa);border-color:var(--ivory)}
.szt__order:hover{background:#fff}
.szt__see{color:var(--ivory);font-weight:600;font-size:15px;text-decoration:none;border-bottom:1px solid rgba(250,245,237,.5);padding-bottom:4px}
.szt__srv{text-align:right;font-family:var(--serif);font-size:clamp(64px,8vw,150px);line-height:.9;margin:0;white-space:nowrap}
.szt__srv small{display:block;font:600 12px/1.4 var(--sans);letter-spacing:.2em;text-transform:uppercase;opacity:.85}
.szt__bars{position:absolute;left:clamp(20px,3vw,56px);right:clamp(20px,3vw,56px);bottom:clamp(20px,3vh,32px);
  list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(5,1fr);gap:8px}
.szt__bars button{all:unset;cursor:pointer;display:grid;gap:8px;width:100%;font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(250,245,237,.75)}
.szt__bars button:focus-visible{outline:2px solid var(--soft-pink);outline-offset:4px}
.szt__bars b{display:block;height:2px;background:rgba(250,245,237,.3);overflow:hidden}
.szt__bars b>i{display:block;height:100%;background:var(--ivory);transform-origin:0 50%;transform:scaleX(0);will-change:transform}
@container vp (max-width:767.98px){.szt__stage{bottom:56px}}  /* keep the frame clear of the phone's sticky inquiry bar */
@container vp (max-width:899.98px){
  .szt__stage{--FH:min(calc(100% - 32px),720px)}
  .szt__w{display:none}.szt__tall{display:block}
  .szt__srv{display:none}
  .szt__bars span{display:none}
  .szt__txt{bottom:56px}
}
.sw{display:inline-grid;vertical-align:bottom}
p.sw{display:grid}
.sw__l{grid-area:1/1}
.sw__w{display:inline-block;overflow:hidden;vertical-align:top;padding-block:.06em .14em;margin-block:-.06em -.14em}
.sw__c{display:inline-block}

/* ===== add to order: the photograph flies to the basket =====
   A round cut of the card's own photograph lifts off, arcs up to the basket in the header
   and drops in; the basket answers with a small pop, the count rolls over, and a scatter
   of sage and blush leaves falls out of it. The pieces live on <body>, outside .vp, so
   they are positioned against the window. Reduced motion skips all of it: the count and
   the status line still change, which is the part that carries meaning. */
.fly{position:fixed;left:0;top:0;z-index:80;width:104px;height:104px;margin:-52px 0 0 -52px;border-radius:50%;
  background:var(--blush) center/cover no-repeat;pointer-events:none;will-change:transform,opacity;
  box-shadow:0 0 0 3px var(--ivory),0 0 0 4px var(--champagne-55),0 18px 34px -12px rgba(74,57,52,.45)}
.fly-leaf{position:fixed;left:0;top:0;z-index:81;width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  border-radius:0 70% 0 70%;pointer-events:none;will-change:transform,opacity}
.hd__cart{position:relative}
.fly-dock{position:fixed;top:12px;right:12px;z-index:79;margin:0;font-family:var(--sans);
  box-shadow:0 12px 26px -14px rgba(74,57,52,.55)}
.fly-dock .hd__cart-n{font-size:15px}
.hd__cart::before{content:"";position:absolute;inset:-2px;border-radius:inherit;pointer-events:none;
  border:1.5px solid var(--deep-rose);opacity:0}
.hd__cart.is-pop{animation:cart-pop 620ms cubic-bezier(.34,1.56,.64,1)}
.hd__cart.is-pop::before{animation:cart-ring 760ms var(--ease)}
@keyframes cart-pop{0%{transform:scale(1)}30%{transform:scale(1.18)}62%{transform:scale(.95)}100%{transform:scale(1)}}
@keyframes cart-ring{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(1.55)}}
.hd__cart-n{display:inline-block}
.hd__cart-n.is-roll{animation:cart-roll 460ms cubic-bezier(.16,.84,.24,1)}
@keyframes cart-roll{from{transform:translateY(80%);opacity:0}}
.buy__add.is-sent{animation:buy-sent 520ms var(--ease)}
@keyframes buy-sent{40%{transform:scale(.97)}}
@media (prefers-reduced-motion:reduce){
  .hd__cart.is-pop,.hd__cart.is-pop::before,.hd__cart-n.is-roll,.buy__add.is-sent{animation:none}}

/* ===== instagram strip (instagram.py) — only ever rendered once there are photos ===== */
.ig__head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--s3) var(--s5);margin-bottom:var(--s6)}
.ig__k{font-size:var(--t-micro);font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-bottom:var(--s2)}
.ig__grid{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s2)}
@container vp (min-width:768px){.ig__grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3)}}
@container vp (min-width:1100px){.ig__grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
.ig__t{display:block;aspect-ratio:1;overflow:hidden;border-radius:var(--r-sm);background:var(--baby-pink)}
.ig__t img{width:100%;height:100%;object-fit:cover;transition:transform 700ms var(--ease)}
.ig__t:hover img,.ig__t:focus-visible img{transform:scale(1.04)}
.ig__t:focus-visible{outline:2px solid var(--deep-rose);outline-offset:3px}
@media (prefers-reduced-motion:reduce){.ig__t img{transition:none}}
.ig__grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}
@container vp (min-width:768px) and (max-width:1099px){
  .ig__grid--4 li:nth-child(n+4),.ig__grid--8 li:nth-child(n+7){display:none}}

/* ===== the order panel (sections.order_sheet, motion.html "order panel") =====
   A right-hand panel on wide screens, a sheet from the bottom on phones. */
html.osh-lock{overflow:hidden}
.osh{position:fixed;inset:0;z-index:60}
.osh__scrim{position:absolute;inset:0;background:rgba(43,33,30,.42);opacity:0;transition:opacity 320ms var(--ease)}
.osh__panel{position:absolute;left:0;right:0;bottom:0;max-height:92vh;max-height:92dvh;display:flex;flex-direction:column;
  background:var(--paper,#FDF9F4);border-radius:var(--r-lg,18px) var(--r-lg,18px) 0 0;box-shadow:0 -20px 60px -30px rgba(43,33,30,.5);
  transform:translateY(104%);transition:transform 380ms cubic-bezier(.16,.84,.24,1);outline:0;
  padding-bottom:env(safe-area-inset-bottom,0px)}
.osh.is-open .osh__scrim{opacity:1}
.osh.is-open .osh__panel{transform:none}
@media (min-width:768px){
  .osh__panel{left:auto;top:0;width:min(480px,100%);max-height:none;border-radius:0;transform:translateX(104%);
    box-shadow:-20px 0 60px -30px rgba(43,33,30,.5)}
  .osh.is-open .osh__panel{transform:none}
}
.osh__hd{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:var(--s4) var(--s5);border-bottom:1px solid var(--champagne-55)}
.osh__t{font-family:var(--serif);font-weight:400;font-size:26px;margin:0}
.osh__x{width:44px;height:44px;display:grid;place-items:center;border:0;background:none;color:var(--cocoa);cursor:pointer;border-radius:50%}
.osh__x:hover{background:var(--cocoa-08)}
.osh__body{flex:1;overflow:auto;padding:var(--s5);display:flex;flex-direction:column;gap:var(--s5)}
.osh__body>[hidden]{display:none!important}
.osh__msg{font-size:var(--t-body);color:var(--muted);margin:0}
.osh__lines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--s3)}
.osh__line{display:grid;grid-template-columns:1fr auto auto;align-items:center;gap:var(--s3);
  padding-bottom:var(--s3);border-bottom:1px solid var(--cocoa-12)}
.osh__ln{font-family:var(--serif);font-size:19px;line-height:1.25}
.osh__q{display:inline-flex;align-items:center;border:1px solid var(--cocoa-22);border-radius:var(--r-pill)}
.osh__qb{width:38px;height:38px;border:0;background:none;color:var(--cocoa);font-size:18px;cursor:pointer;border-radius:50%}
.osh__qb:hover{background:var(--cocoa-08)}
.osh__q output{min-width:1.6em;text-align:center;font-variant-numeric:tabular-nums;font-weight:500}
.osh__lp{min-width:4.5em;text-align:right;font-variant-numeric:tabular-nums;font-weight:500}
.osh__more summary,.osh__note summary{cursor:pointer;font-size:var(--t-small);font-weight:600;color:var(--deep-rose);
  list-style:none;display:inline-flex;align-items:center;gap:6px;min-height:36px}
.osh__more summary::before,.osh__note summary::before{content:"+";font-size:18px;line-height:1}
.osh__more[open] summary::before,.osh__note[open] summary::before{content:"\2212"}
.osh__more summary::-webkit-details-marker,.osh__note summary::-webkit-details-marker{display:none}
.osh__adds{display:grid;gap:var(--s2);margin-top:var(--s2)}
.osh__addb{display:flex;justify-content:space-between;gap:var(--s3);padding:12px 14px;border:1px solid var(--cocoa-22);
  border-radius:var(--r-md);background:none;color:var(--cocoa);font:500 var(--t-small)/1.3 var(--sans);cursor:pointer;text-align:left}
.osh__addb:hover{border-color:var(--rose,#844658)}
.osh__addb span+span{font-variant-numeric:tabular-nums;color:var(--muted)}
.osh__grp{display:flex;flex-direction:column;gap:var(--s2)}
.osh__lab{font-size:var(--t-micro);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:0}
.osh__chips{display:flex;flex-wrap:wrap;gap:var(--s2)}
.osh__chip{display:grid;justify-items:center;gap:2px;min-width:74px;padding:10px 12px;border:1px solid var(--cocoa-22);
  border-radius:var(--r-md);background:none;color:var(--cocoa);font:500 13px/1.2 var(--sans);cursor:pointer}
.osh__chip span{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.osh__chip b{font-weight:600;font-size:15px}
.osh__chip:hover{border-color:var(--rose,#844658)}
.osh__chip[aria-checked="true"]{background:var(--cocoa);border-color:var(--cocoa);color:var(--ivory)}
.osh__chip[aria-checked="true"] span{color:rgba(250,245,237,.8)}
.osh__chip--w{min-width:0;padding:12px 18px}
.osh__zip{display:flex;flex-direction:column;gap:var(--s2);margin-top:var(--s2)}
.osh__in{width:100%;min-height:52px;padding:12px var(--s3);border:1px solid var(--cocoa-22);border-radius:var(--r-sm);
  background:#fff;color:var(--cocoa);font:400 16px/1.4 var(--sans)}
.osh__in:focus{outline:2px solid var(--deep-rose);outline-offset:1px;border-color:transparent}
#osh-zip{max-width:160px;font-size:18px;letter-spacing:.08em;font-variant-numeric:tabular-nums}
.osh__note textarea{margin-top:var(--s2);resize:vertical}
.osh__hint{font-size:var(--t-micro);line-height:1.5;color:var(--muted)}
.osh__hint.is-bad{color:var(--deep-rose);font-weight:500}
.osh__err{margin:0;font-size:var(--t-small);color:var(--cocoa);background:var(--blush);padding:12px 14px;border-radius:var(--r-sm)}
.osh__ft{padding:var(--s4) var(--s5) var(--s5);border-top:1px solid var(--champagne-55);background:var(--paper,#FDF9F4);display:grid;gap:var(--s3)}
.osh__ft[hidden]{display:none}
.osh__sum{margin:0;display:grid;gap:4px}
.osh__sum>div{display:flex;justify-content:space-between;gap:var(--s3)}
.osh__sum dt{font-size:var(--t-small);color:var(--muted)}
.osh__sum dd{margin:0;font-variant-numeric:tabular-nums}
.osh__sum .osh__tot dt,.osh__sum .osh__tot dd{color:var(--cocoa);font-weight:600;font-size:var(--t-body)}
.osh__go{width:100%;justify-content:center;min-height:54px;font-size:16px}
.osh__go:disabled{opacity:.45;cursor:not-allowed}
.osh__fine{margin:0;text-align:center;font-size:var(--t-micro);color:var(--muted)}
.osh__fine a{color:var(--cocoa)}
@media (prefers-reduced-motion:reduce){.osh__panel,.osh__scrim{transition:none}}
/* one Order button where the stepper and "Add to order" used to be */
.buy--order{display:flex;flex-direction:column;gap:var(--s2)}
.buy--order .buy__order{align-self:flex-start;min-width:180px;justify-content:center}
.pc__buy.buy--order .buy__order{align-self:stretch}
.lad__acts{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s4)}
.ord__acts{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3);margin-top:var(--s5)}

/* ===== Valma's butterfly (home story section) =====
   A landscape vector stage (the flight needs less height than width, so the section keeps
   no dead air); the page ground shows through, so it sits on the section rather than in a box. The svg may overflow the square by a few px (a wingtip mid-flight)
   but never takes pointer events: the stage box itself is the click target. The wings flap
   by reshaping their paths (not by a squash transform), so the ink line keeps one weight. */
.bfly{--bfly-ink:#4A5346;--bfly-soft:#4F5A49;--bfly-ground:var(--ivory,#FAF5ED);
  position:relative;width:100%;max-width:560px;aspect-ratio:780/720;margin:0 auto;cursor:pointer;
  -webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;
  -webkit-touch-callout:none;touch-action:manipulation}
@supports not (aspect-ratio:1){.bfly::before{content:"";display:block;padding-top:92.3%}}
.bfly.is-reduced{cursor:default}
.bfly__svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible;pointer-events:none}
html.js .bfly:not(.is-ready) .bfly__svg{visibility:hidden}   /* no end-card flash before the first frame */
.bfly__p{stroke:var(--bfly-ink);stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1}
.bfly__rule{stroke:var(--bfly-soft);opacity:.8;vector-effect:non-scaling-stroke}
.bfly__wm{font-family:var(--serif,"Playfair Display",Georgia,serif);font-size:72px;font-weight:500;
  letter-spacing:.04em;fill:var(--cocoa,#4A3934);text-rendering:geometricPrecision}
.bfly__hd{font-family:var(--sans,Montserrat,sans-serif);font-size:32px;font-weight:500;letter-spacing:.26em;
  fill:var(--bfly-soft);text-rendering:geometricPrecision}
.bfly__fade{fill:var(--bfly-ground)}
@media (forced-colors:active){
  .bfly__fade{fill:Canvas}
  .bfly__wm,.bfly__hd{fill:CanvasText}
  .bfly__p,.bfly__rule{stroke:CanvasText}
  .bfly__glow{display:none}}
/* the story figure that holds it: no wipe curtain, no arch clip. Tablets in portrait keep the
   full-width stage (stacked); two columns from 900px, even columns from 1100px */
.story__f--bfly{max-width:520px;margin:0 auto}
@container vp (min-width:900px){
  .story{grid-template-columns:minmax(0,.94fr) minmax(0,1.06fr);gap:var(--s7);align-items:center}
  .story__f--bfly{max-width:100%;margin:0}}
@container vp (min-width:1100px){.story{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--s9)}
  .story__f--bfly{justify-self:center}}

body{background:var(--ivory)}
