@charset "UTF-8";
/* ==========================================================================
   Purple Pot Designs - implements design-system.md
   Ivory paper, plum ink, one gold hairline. The clothes carry the colour.
   ========================================================================== */

/* -------------------------------------------------- tokens */
:root{
  --plum-900:#2B0724; --plum-700:#480C3C; --plum-500:#6B2A5C; --plum-100:#F3ECF1;
  --gold-600:#866718; --gold-500:#B89028; --gold-100:#EFE6CE;
  --ivory:#FBF9F6; --bone:#F4EFE8; --ink:#241A20; --muted:#6B5F66; --line:#E3DBD4;

  --ff-display:"Cormorant Garamond",Georgia,"Times New Roman",serif;
  --ff-sans:"Jost","Helvetica Neue",Arial,sans-serif;

  --fs-display:clamp(2.5rem,5.5vw,4.25rem);
  --fs-h2:clamp(1.9rem,3.2vw,2.75rem);
  --fs-h3:clamp(1.25rem,1.8vw,1.5rem);
  --fs-lede:clamp(1.06rem,1.5vw,1.25rem);
  --fs-body:clamp(1rem,1.1vw,1.0625rem);
  --fs-small:.875rem;
  --fs-eyebrow:.75rem;

  --s1:.5rem; --s2:.75rem; --s3:1rem; --s4:1.5rem; --s5:2rem; --s6:3rem; --s7:4rem; --s8:6rem;
  --section-y:clamp(3.75rem,7vw,6rem);
  --gutter:clamp(1.25rem,5vw,4rem);
  --wrap:1280px; --wrap-narrow:760px;
  --header-h:72px;
  --ease:cubic-bezier(.22,.61,.36,1);
}

/* -------------------------------------------------- reset */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--ivory);color:var(--ink);
  font-family:var(--ff-sans);font-size:var(--fs-body);font-weight:400;line-height:1.75;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img,svg,picture,video{display:block;max-width:100%}
img{height:auto}
/* <picture> is inline by default, so an img with height:100% inside one resolves
   against an auto-height box and stops filling its aspect-ratio frame. Every
   ratio box therefore stretches its <picture> to fill. */
.piece__media picture,.hero__media picture{position:absolute;inset:0}
button,input,select,textarea{font:inherit;color:inherit}
a{color:var(--plum-700);text-decoration-thickness:1px;text-underline-offset:.25em}
h1,h2,h3,h4{margin:0 0 var(--s4);font-family:var(--ff-display);font-weight:400;color:var(--plum-700);letter-spacing:.005em}
p,ul,ol{margin:0 0 var(--s4)}
/* figure defaults to margin:1em 40px. Inside a grid those 80px inflate each
   track's min-content width and overflow the row at 360px. */
figure,blockquote{margin:0}
:is(h1,h2,h3,h4,p,ul,ol):last-child{margin-bottom:0}
::selection{background:var(--plum-700);color:var(--ivory)}
:focus-visible{outline:2px solid var(--gold-500);outline-offset:3px;border-radius:1px}
.skip{position:absolute;left:var(--s3);top:-4rem;z-index:200;background:var(--plum-700);color:var(--ivory);
  padding:var(--s2) var(--s4);text-decoration:none;transition:top .2s}
.skip:focus{top:var(--s3)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* -------------------------------------------------- type */
/* Cormorant at 300 produced hairline stems that read as washed grey-violet at
   68px rather than the deep plum ink the brief asks for. */
h1{font-size:var(--fs-display);font-weight:400;line-height:1.03;letter-spacing:-.006em;
  color:var(--plum-900);max-width:20ch}
h2{font-size:var(--fs-h2);line-height:1.15;max-width:24ch}
h3{font-size:var(--fs-h3);font-weight:500;line-height:1.3;margin-bottom:var(--s2)}
.eyebrow{
  display:block;font-family:var(--ff-sans);font-size:var(--fs-eyebrow);font-weight:500;
  text-transform:uppercase;letter-spacing:.22em;color:var(--gold-600);margin:0 0 var(--s3);
}
.lede{font-size:var(--fs-lede);font-weight:300;line-height:1.7;max-width:58ch;color:var(--ink)}
p{max-width:66ch}
.muted{color:var(--muted)}
.small{font-size:var(--fs-small)}

/* the single ornament: a gold hairline */
.rule{display:block;width:56px;height:1px;background:var(--gold-500);border:0;margin:0 0 var(--s4);
  transform-origin:left center}
.rule--center{margin-left:auto;margin-right:auto;transform-origin:center}

/* -------------------------------------------------- layout */
.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter)}
/* A narrow measure, but anchored to the site's own left gutter rather than
   centred in the 1280px wrap - centring it stepped the left edge in ~215px for
   one section and back out for the next. Every section now starts on the same x. */
.wrap--narrow{max-width:var(--wrap)}
.wrap--narrow > *{max-width:var(--wrap-narrow)}
.wrap--narrow > .quote--center{margin-inline:0}
/* The timeline needs more than the 760px prose measure: at that width the serif
   label column is ~320px and every heading wraps. */
/* Was a 900px block centred inside the 1280px wrap, which stepped this one
   section's left edge in ~156px from every other section on the site. Now the
   block starts at the site's own wrap edge and simply runs narrower. */
.wrap--timeline .timeline,.wrap--timeline .section-head{max-width:900px}
.section{padding-block:var(--section-y)}
.section--bone{background:var(--bone)}
.section--plum{background:var(--plum-900);color:#EDE4EA}
.section--plum :is(h1,h2,h3){color:var(--ivory)}
.section--plum .eyebrow{color:var(--gold-500)}
.section--plum .lede,.section--plum p{color:#E0D3DC}
.section--plum a{color:var(--ivory)}
.section-head{margin-bottom:var(--s7)}
.section-head--center{text-align:center;display:flex;flex-direction:column;align-items:center}
.section-head--center h2{max-width:26ch}
.split{display:grid;gap:var(--s6)}
@media (min-width:1024px){
  .split{grid-template-columns:1fr 1fr;gap:var(--s8);align-items:center}
  .split--media-first > .split__media{order:-1}
  /* Forms read better top-aligned than optically centred. */
  .split--top{align-items:start}
}

/* -------------------------------------------------- header */
.site-header{
  position:sticky;top:0;z-index:100;background:transparent;
  /* 350ms meant content passed through a transparent header for a third of a
     second at the start of every scroll. 120ms reads as instant. */
  transition:background .12s linear,box-shadow .12s linear;
}
/* Solid, not translucent: at 94% a saturated hero image bleeds through and the
   nav stops looking clean. */
.site-header.is-stuck{background:var(--ivory);box-shadow:0 1px 0 var(--line)}
.header-inner{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  min-height:var(--header-h);padding-inline:var(--gutter);max-width:var(--wrap);margin-inline:auto;
}
.brand{display:flex;align-items:center;gap:var(--s2);text-decoration:none;flex:0 0 auto}
/* The ornate mark cannot resolve at header size, so the header carries the
   logo's star motif instead; the full ornament stays in the footer and OG card. */
.brand__star{width:19px;height:19px;color:var(--plum-700);flex:0 0 auto;margin-right:.15rem}
.brand__name{font-family:var(--ff-display);font-size:1.0625rem;font-weight:500;color:var(--plum-700);
  text-transform:uppercase;letter-spacing:.14em;line-height:1;white-space:nowrap}
/* .5625rem (9px) at .42em tracking read as a printing fault rather than a
   wordmark. */
.brand__sub{display:block;font-family:var(--ff-sans);font-size:.65rem;font-weight:400;
  letter-spacing:.3em;color:var(--muted);text-transform:lowercase;margin-top:.35em}

.nav{display:none}
@media (min-width:1024px){
  .nav{display:flex;align-items:center;gap:var(--s5)}
}
.nav__link{
  position:relative;display:inline-flex;align-items:center;min-height:44px;
  font-size:.8125rem;font-weight:400;text-transform:uppercase;letter-spacing:.16em;
  color:var(--ink);text-decoration:none;padding:.5rem 0;
}
.nav__link::after{content:"";position:absolute;left:0;right:0;bottom:9px;height:1px;background:var(--gold-500);
  transform:scaleX(0);transform-origin:right;transition:transform .4s var(--ease)}
.nav__link:hover::after,.nav__link:focus-visible::after{transform:scaleX(1);transform-origin:left}
.nav__link[aria-current="page"]{color:var(--plum-700)}
.nav__link[aria-current="page"]::after{transform:scaleX(1)}

.menu-toggle{
  display:inline-flex;align-items:center;justify-content:center;gap:.55rem;
  min-width:44px;min-height:44px;padding:0 .35rem;background:none;border:0;cursor:pointer;
  font-size:.75rem;text-transform:uppercase;letter-spacing:.16em;color:var(--plum-700);
}
.menu-toggle__bars{position:relative;width:20px;height:11px;flex:0 0 auto}
.menu-toggle__bars span{position:absolute;left:0;right:0;height:1px;background:currentColor;
  transition:transform .3s var(--ease),opacity .2s}
.menu-toggle__bars span:nth-child(1){top:0}
.menu-toggle__bars span:nth-child(2){top:5px}
.menu-toggle__bars span:nth-child(3){top:10px}
[aria-expanded="true"] .menu-toggle__bars span:nth-child(1){transform:translateY(5px) rotate(45deg)}
[aria-expanded="true"] .menu-toggle__bars span:nth-child(2){opacity:0}
[aria-expanded="true"] .menu-toggle__bars span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}
/* Declared AFTER .menu-toggle's own display, or the later equal-specificity rule
   wins and the burger stays visible on desktop. */
@media (min-width:1024px){.menu-toggle{display:none}}

.drawer{
  position:fixed;inset:0;z-index:99;background:var(--ivory);
  display:flex;flex-direction:column;justify-content:center;gap:var(--s2);
  padding:calc(var(--header-h) + var(--s5)) var(--gutter) var(--s7);
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .35s var(--ease),transform .35s var(--ease),visibility .35s;
}
.drawer.is-open{opacity:1;visibility:visible;transform:none}
/* :not(.btn) matters - .drawer a is (0,1,1) and beats .btn (0,1,0), which
   zeroed the Shop button's side padding and removed its lower border. */
.drawer a:not(.btn){
  font-family:var(--ff-display);font-size:clamp(1.75rem,8vw,2.5rem);font-weight:300;
  color:var(--plum-700);text-decoration:none;padding:.35em 0;border-bottom:1px solid var(--line);
}
.drawer .btn{margin-top:var(--s5);align-self:flex-start;
  font-family:var(--ff-sans);font-size:.75rem;padding:.9rem 1.9rem}
@media (min-width:1024px){.drawer{display:none}}
body.is-locked{overflow:hidden}

/* -------------------------------------------------- buttons */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6em;
  min-height:44px;padding:.9rem 1.9rem;border:1px solid var(--plum-700);border-radius:0;
  font-family:var(--ff-sans);font-size:.75rem;font-weight:500;text-transform:uppercase;
  letter-spacing:.16em;text-decoration:none;cursor:pointer;background:none;color:var(--plum-700);
  transition:background .35s var(--ease),color .35s var(--ease),border-color .35s var(--ease);
}
.btn--primary{background:var(--plum-700);color:var(--ivory)}
.btn--primary:hover,.btn--primary:focus-visible{background:var(--plum-900);border-color:var(--plum-900)}
.btn--ghost:hover,.btn--ghost:focus-visible{background:var(--plum-700);color:var(--ivory)}
.btn--onplum{border-color:rgba(251,249,246,.5);color:var(--ivory)}
.btn--onplum:hover,.btn--onplum:focus-visible{background:var(--ivory);color:var(--plum-900);border-color:var(--ivory)}
.btn .arrow{transition:transform .35s var(--ease)}
.btn:hover .arrow{transform:translateX(3px)}
.btn-row{display:flex;flex-wrap:wrap;gap:var(--s3)}
.nav__shop{border:1px solid var(--plum-700);padding:.7rem 1.25rem;min-height:40px;display:inline-flex;align-items:center;
  font-size:.75rem;letter-spacing:.16em;text-transform:uppercase;text-decoration:none;color:var(--plum-700);
  transition:background .35s var(--ease),color .35s var(--ease)}
.nav__shop:hover,.nav__shop:focus-visible{background:var(--plum-700);color:var(--ivory)}
.link-arrow{display:inline-flex;align-items:center;gap:.5em;font-size:.8125rem;font-weight:500;
  text-transform:uppercase;letter-spacing:.16em;text-decoration:none;color:var(--plum-700);
  padding-bottom:.3rem;border-bottom:1px solid var(--gold-500)}
.link-arrow .arrow{transition:transform .35s var(--ease)}
.link-arrow:hover .arrow{transform:translateX(3px)}

/* -------------------------------------------------- hero */
.hero{position:relative;background:var(--bone)}
.hero__grid{display:grid;gap:0}
.hero__panel{
  display:flex;flex-direction:column;justify-content:center;
  padding:calc(var(--section-y) + var(--s4)) var(--gutter) var(--section-y);
  max-width:var(--wrap);margin-inline:auto;width:100%;
}
.hero__media{position:relative;overflow:hidden;aspect-ratio:4/5;background:var(--plum-100)}
.hero__media img{width:100%;height:100%;object-fit:cover;object-position:50% 22%}
.hero h1{margin-bottom:var(--s4);max-width:26ch;text-wrap:balance}
.hero .lede{margin-bottom:var(--s5)}
@media (min-width:1024px){
  .hero__grid{grid-template-columns:1.02fr .98fr;align-items:stretch;min-height:min(86vh,860px)}
  .hero__panel{padding-block:var(--s8);padding-right:var(--s7);
    padding-left:max(var(--gutter),calc((100vw - var(--wrap))/2 + var(--gutter)));margin-inline:0}
  /* The image is portrait 4:5. Left in flow it drives the grid row to ~1160px and
     the hero stops fitting the screen, so it is taken out of flow and the panel
     alone sets the height. */
  .hero__media{aspect-ratio:auto;height:auto}
}

/* -------------------------------------------------- pillars */
/* A thin strip, so it gets its own reduced padding - the standard --section-y
   top and bottom would be over half the section's height. */
.section--strip{padding-block:clamp(2rem,3.5vw,3rem)}
.section--compact{padding-block:clamp(2.75rem,5vw,4rem)}
.pillars{display:grid;gap:0;border-block:1px solid var(--line)}
.pillar{padding:var(--s5) 0;text-align:center;border-bottom:1px solid var(--line)}
.pillar:last-child{border-bottom:0}
/* Scoped as .pillar .pillar__name: bare .pillar__name (0,1,0) loses to
   .pillar p (0,1,1) below, which silently shrank these to 14px muted grey. */
.pillar .pillar__name{font-family:var(--ff-display);font-size:clamp(1.25rem,2vw,1.5rem);
  font-weight:400;color:var(--plum-700);letter-spacing:.06em;margin:0 0 .5rem;max-width:none}
.pillar p{font-size:var(--fs-small);color:var(--muted);margin:0;max-width:34ch;margin-inline:auto}
@media (min-width:768px){
  .pillars{grid-template-columns:repeat(3,1fr)}
  .pillar{border-bottom:0;border-right:1px solid var(--line);padding:var(--s6) var(--s4)}
  .pillar:last-child{border-right:0}
}

/* -------------------------------------------------- gallery */
/* One column below 600px. Two columns at 360 gave a 148px-wide garment card
   with a caption nearly as tall as the photograph - the product rendered as a
   thumbnail on the device most people will use. */
.gallery{display:grid;gap:var(--s6) var(--s4);grid-template-columns:1fr}
@media (min-width:600px){.gallery{grid-template-columns:repeat(2,1fr);gap:var(--s5) var(--s4)}}
@media (min-width:768px){.gallery{grid-template-columns:repeat(3,1fr);gap:var(--s6) var(--s5)}}
/* Category group headers: the grid had no typographic anchor - five images and
   ten lines of small text. The categories are facts we already hold. */
.piece-group + .piece-group{margin-top:var(--s8)}
/* Each group's grid is sized to its own item count, so no group ends in an empty
   cell - a fix for one orphan tile had otherwise produced three. */
@media (min-width:768px){
  .gallery--pair{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s6) var(--s5)}
  .gallery--single{grid-template-columns:minmax(0,1fr)}
  /* .piece.piece--feature, not .piece--feature: `.piece{display:block}` is
     declared later in this file at equal specificity and would otherwise win.
     This stylesheet has produced that same bug five times - when a modifier
     does not take, check for a later equal-specificity rule first. */
  /* The caption sits against the image, not adrift in the far column - at a full
     column's distance a single large image plus a floating caption reads as the
     grid artefact it is rather than as an editorial choice. */
  .piece.piece--feature{display:grid;grid-template-columns:minmax(0,520px) minmax(0,1fr);
    gap:var(--s5);align-items:end}
  .piece--feature .piece__cap{padding-bottom:var(--s4);max-width:24ch}
  .piece--feature .piece__media{margin-bottom:0}
  .piece--feature .piece__cap{font-size:var(--fs-lede);font-weight:300;line-height:1.6;max-width:26ch}
}
.piece-group__name{font-size:var(--fs-h2);color:var(--plum-700);margin:0 0 var(--s5);
  scroll-margin-top:calc(var(--header-h) + var(--s4));
  padding-bottom:var(--s3);border-bottom:1px solid var(--line);max-width:none}
.gallery--four{grid-template-columns:1fr}
@media (min-width:600px){.gallery--four{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1024px){.gallery--four{grid-template-columns:repeat(4,1fr)}}
.piece{display:block;text-decoration:none;color:inherit}
.piece__media{position:relative;overflow:hidden;aspect-ratio:2/3;background:var(--plum-100);margin-bottom:var(--s3)}
.piece__media img{width:100%;height:100%;object-fit:cover;transition:transform .9s var(--ease)}
@media (hover:hover){.piece:hover .piece__media img{transform:scale(1.03)}}
.piece__cap{font-size:var(--fs-small);line-height:1.6;color:var(--ink);margin:0;max-width:34ch}
.piece__meta{display:block;font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-top:.3rem}

/* -------------------------------------------------- dye cards */
.dyes{display:grid;gap:var(--s5);grid-template-columns:repeat(2,1fr)}
@media (min-width:768px){.dyes{grid-template-columns:repeat(4,1fr);gap:var(--s4)}}
.dye{text-align:center}
/* Photographic now, not a flat fill. */
.dye__swatch{width:clamp(120px,19vw,168px);height:clamp(120px,19vw,168px);border-radius:50%;
  margin:0 auto var(--s3);overflow:hidden;border:1px solid rgba(36,26,32,.12)}
.dye__swatch picture{display:block;width:100%;height:100%}
.dye__swatch img{width:100%;height:100%;object-fit:cover}
.dye h3{font-size:1.0625rem;font-family:var(--ff-sans);font-weight:500;text-transform:uppercase;
  letter-spacing:.14em;margin-bottom:.35rem;color:var(--plum-700)}
.dye p{font-size:var(--fs-small);color:var(--muted);margin:0;max-width:22ch;margin-inline:auto}

/* -------------------------------------------------- quote + timeline */
.quote{margin:0;padding:var(--s6) 0;border-top:1px solid var(--gold-100);border-bottom:1px solid var(--gold-100)}
.quote p{font-family:var(--ff-display);font-size:clamp(1.5rem,3vw,2.25rem);font-weight:300;
  font-style:italic;line-height:1.35;color:var(--plum-700);max-width:22ch;margin:0}
.quote--center{text-align:center}
.quote--center p{margin-inline:auto}
.timeline{list-style:none;margin:0;padding:0}
.timeline__item{padding:var(--s5) 0;border-top:1px solid var(--line)}
.timeline__item:last-child{border-bottom:1px solid var(--line)}
.timeline__item h3{margin-bottom:.35rem}
.timeline__item p{margin:0;color:var(--muted);font-size:var(--fs-small)}
@media (min-width:768px){
  /* Was 1fr / 1.3fr inside a 760px measure, which left the serif label ~195px so
     all three headings wrapped, and `baseline` then dropped the second line
     below the description. */
  .timeline__item{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
    gap:var(--s5);align-items:start}
  .timeline__item h3{margin:0}
}
.timeline__item p{font-size:var(--fs-body);color:var(--ink)}

/* -------------------------------------------------- manifesto */
.manifesto{display:grid;gap:var(--s5)}
@media (min-width:768px){.manifesto{grid-template-columns:repeat(3,1fr);gap:var(--s6)}}
.manifesto p{font-family:var(--ff-display);font-size:clamp(1.15rem,1.9vw,1.375rem);line-height:1.5;
  color:var(--ivory);margin:0;max-width:24ch}

/* -------------------------------------------------- band */
.band{text-align:center}
.band .btn-row{justify-content:center;margin-top:var(--s5)}
.band .rule{margin-inline:auto}
.band h2,.band p{margin-inline:auto}
/* The CTA band used to be plum, which put THREE consecutive plum slabs at the
   foot of the home page - launchpad, band, footer - with no ground change and
   ~380px of dead colour between them. On bone it separates the two plum blocks
   and gives the page a breath before it closes. */
.band--bone{background:var(--bone)}
/* Was ~42% padding around a rule, a headline, one line and a button. */
.band{padding-block:clamp(3rem,5vw,4.25rem)}
/* Collapse the seams around it: adjacent sections each contributing a full
   --section-y produced gaps of nearly 200px of nothing. */
.section--plum + .band--bone{padding-top:var(--section-y)}
.band--bone + .site-footer{padding-top:var(--s6)}
.page-hero + .section{padding-top:var(--s6)}
/* The page-hero media is a 2:3 portrait; left unconstrained it runs to ~960px
   beside a ~230px text column and the row stops reading as a pair. Capped to a
   controlled crop so the two columns relate. */
@media (min-width:1024px){
  .page-hero .split__media img{width:100%;height:clamp(320px,48vh,470px);
    object-fit:cover;object-position:50% 28%}
  /* Top-aligned left a ~190px empty rectangle under the short text column. */
  .page-hero .split{align-items:center}
}
/* The hero's own bottom padding was showing as a bare 68px band of bone above
   the next (ivory) section - two off-whites a hair apart with a visible seam. */
.page-hero{padding-bottom:var(--s6)}

/* -------------------------------------------------- figure / full-bleed */
.figure-wide{margin:0}
.figure-wide img{width:100%;aspect-ratio:1.49/1;object-fit:cover}
figcaption{font-size:var(--fs-small);color:var(--muted);margin-top:var(--s2)}

/* -------------------------------------------------- forms */
.form-grid{display:grid;gap:var(--s4)}
@media (min-width:600px){.form-grid{grid-template-columns:1fr 1fr}.form-grid .span-2{grid-column:1/-1}}
.form-field label{display:block;font-size:.75rem;font-weight:500;text-transform:uppercase;
  letter-spacing:.14em;color:var(--plum-700);margin-bottom:.5rem}
.form-field .req{color:var(--gold-600)}
.form-field input,.form-field select,.form-field textarea{
  width:100%;padding:.85rem 1rem;min-height:48px;background:var(--ivory);
  border:1px solid var(--line);border-radius:0;font-size:1rem;color:var(--ink);
  transition:border-color .25s var(--ease),background .25s var(--ease);
}
.form-field textarea{min-height:170px;resize:vertical;line-height:1.7}
.form-field select{appearance:none;-webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--plum-700) 50%),linear-gradient(135deg,var(--plum-700) 50%,transparent 50%);
  background-position:calc(100% - 20px) 50%,calc(100% - 14px) 50%;background-size:6px 6px;background-repeat:no-repeat;padding-right:3rem}
.form-field :is(input,select,textarea):focus{border-color:var(--plum-700);background:#fff;outline:2px solid var(--gold-500);outline-offset:1px}
.form-field :is(input,textarea)::placeholder{color:#8F8189}
.form-field .err{display:block;font-size:var(--fs-small);color:#8C1D18;margin-top:.4rem}
.form-field :is(input,select,textarea)[aria-invalid="true"]{border-color:#8C1D18}
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden}
/* The <label> wraps the input, so the activation target is this whole row, not
   the 24px box - min-height keeps that row comfortably past 44px.
   Scoped .form-field .consent (0,2,0) so it beats .form-field label (0,1,1),
   which was setting this whole sentence in letterspaced capitals. */
.form-field .consent{display:flex;gap:.75rem;align-items:flex-start;min-height:44px;padding:.35rem 0;
  font-size:var(--fs-small);font-weight:400;color:var(--muted);cursor:pointer;
  text-transform:none;letter-spacing:normal;line-height:1.6;margin-bottom:0}
.consent input{width:24px;height:24px;min-height:24px;margin-top:.15rem;flex:0 0 auto;accent-color:var(--plum-700);cursor:pointer}
.form-note{font-size:var(--fs-small);color:var(--muted)}
.alert{padding:var(--s4);border-left:2px solid var(--gold-500);background:var(--plum-100);
  font-size:var(--fs-small);margin-bottom:var(--s5)}
.alert--bad{border-left-color:#8C1D18;background:#FBEFEE}

/* contact aside */
.contact-list{list-style:none;margin:0;padding:0}
.contact-list li{padding:var(--s4) 0;border-bottom:1px solid var(--line)}
.contact-list li:first-child{padding-top:0}
.contact-list .k{display:block;font-size:.6875rem;font-weight:500;text-transform:uppercase;
  letter-spacing:.18em;color:var(--muted);margin-bottom:.4rem}
.contact-list a{color:var(--plum-700);text-decoration:none;border-bottom:1px solid var(--gold-500);
  word-break:break-word}
.contact-list a:hover{color:var(--plum-500)}

/* -------------------------------------------------- footer */
.site-footer{background:var(--plum-900);color:#CBB8C4;padding:var(--s8) 0 var(--s5);font-size:var(--fs-small)}
.footer-grid{display:grid;gap:var(--s6)}
@media (min-width:768px){.footer-grid{grid-template-columns:1.4fr 1fr 1fr;gap:var(--s7)}}
.site-footer img.footer-logo{width:190px;margin-bottom:var(--s4)}
.site-footer .footer-head{font-family:var(--ff-sans);font-size:.6875rem;font-weight:500;text-transform:uppercase;
  letter-spacing:.2em;color:var(--gold-500);margin:0 0 var(--s3)}
.site-footer ul{list-style:none;margin:0;padding:0}
.site-footer li{margin-bottom:.7rem}
.site-footer a{color:#E0D3DC;text-decoration:none;transition:color .25s}
.site-footer a:hover,.site-footer a:focus-visible{color:var(--ivory);text-decoration:underline}
.site-footer p{color:#CBB8C4;max-width:40ch}
.footer-tagline{font-family:var(--ff-display);font-style:italic;font-size:1.0625rem;color:#E0D3DC;
  margin:0 0 var(--s4)}
.footer-bottom{margin-top:var(--s7);padding-top:var(--s4);border-top:1px solid rgba(251,249,246,.14);
  display:flex;flex-wrap:wrap;gap:var(--s2) var(--s5);justify-content:space-between;
  font-size:.75rem;color:#A995A4}
.footer-bottom a{color:#A995A4}
/* --muted is tuned for ivory grounds; on the plum footer it lands at 2.98:1.
   This scoped override restores 4.63:1. */
.site-footer .muted{color:#8B7D85}
.footer-bottom p{color:#A995A4;margin:0}

/* ==========================================================================
   MOTION - see design-system.md.
   Hidden start states are scoped to .js-motion, which is set by an inline
   script in <head>. No JS, blocked JS, or an error before that line all leave
   the page fully visible. Revealed selectors carry higher specificity than
   hidden ones, and the fallbacks below are !important and declared last.
   ========================================================================== */
.js-motion .reveal{opacity:0;transform:translateY(14px);
  transition:opacity .7s var(--ease),transform .7s var(--ease);transition-delay:var(--d,0ms)}
.js-motion .reveal.is-in{opacity:1;transform:none}

.js-motion .reveal-rule{transform:scaleX(0);transition:transform .8s var(--ease);transition-delay:var(--d,0ms)}
.js-motion .reveal-rule.is-in{transform:scaleX(1)}

.js-motion .hero__media img{transform:scale(1.06);transition:transform 1.4s var(--ease)}
.js-motion .hero__media img.is-in{transform:scale(1)}

/* Last-resort reveal - set by a load listener and an 1800ms timer, and matched
   here with !important so nothing can leave content hidden. */
html.motion-off .reveal,
html.motion-off .reveal-rule,
html.motion-off .hero__media img{opacity:1!important;transform:none!important;transition:none!important}

@media (prefers-reduced-motion:reduce){
  .js-motion .reveal,.js-motion .reveal-rule,.js-motion .hero__media img,
  .js-motion .reveal.is-in,.js-motion .reveal-rule.is-in,.js-motion .hero__media img.is-in{
    opacity:1!important;transform:none!important;transition:none!important;animation:none!important}
  *,*::before,*::after{transition-duration:.01ms!important;animation-duration:.01ms!important}
}

@media print{
  .site-header,.drawer,.band,.btn,.menu-toggle{display:none!important}
  body{background:#fff}
  .reveal,.reveal-rule{opacity:1!important;transform:none!important}
}
