/* ==================================================================
   Lucy & Lily's — stylesheet
   Chrome is black and white only. Grays carry hierarchy, nothing else.
   Color appears in exactly one place on this site, inside the
   photographs, which is the correct place for it on a florist's site.
   Proportions follow a 7:5:3 relationship throughout.
   ------------------------------------------------------------------
   You should rarely need to edit this file. Text, prices, dates and
   contact details all live in assets/config.js.
   ================================================================== */
:root{
  /* ---- VESSEL ---------------------------------------------------
     Two warm grounds, green ink, clay for prices, and nothing dark.
     A pastel is a ground and never a text color, so every ground has
     a mid-tone relative that carries type.
     ---------------------------------------------------------------- */
  --ink:#2E3A2C;          /* green-black. 12:1 on chalk */
  --paper:#FBF8F3;        /* chalk, the default ground */
  --blush:#F8F0EC;        /* the second ground, full width only */
  --sand:#F2E8DE;         /* the strip, and nothing else */
  --clay:#8C5A50;         /* prices. 5.2:1 on chalk */
  --ink-70:#5B6357;       /* running text that is not the point */
  --stem:#5B6357;         /* same value, named for rules that read as structure */
  --ink-45:#6E7568;       /* fine print. 4.6:1, the floor */
  --ink-20:#DCD2CA;       /* field edges */
  --rule:#E6DCD5;         /* hairlines */
  --hair:#E6DCD5;
  --field:#F1E9E3;        /* behind a photograph that has not loaded */

  /* Three faces, three jobs, no overlap. Cormorant is the wordmark
     and appears nowhere else; Caslon is what is looked at; the
     grotesque is everything that is read. */
  --mark:"Cormorant Garamond",Garamond,Georgia,serif;
  --serif:"Libre Caslon Text",Baskerville,Georgia,"Times New Roman",serif;
  --sans:"Helvetica Neue",Helvetica,"Archivo",Arial,system-ui,sans-serif;

  /* Caslon has more presence than Cormorant at the same size, so the
     display scale sits a full step lower than it used to. */
  --d5:clamp(1.8rem,2.9vw,2.4rem);
  --d3:clamp(1.4rem,2vw,1.7rem);

  --t-lead:1.0625rem;
  --t-body:0.9375rem;
  --t-small:0.8125rem;
  --t-fine:0.75rem;

  --s3:1.5rem;
  --s5:2.5rem;
  --s7:3.5rem;
  --s-band:clamp(4.5rem,9vw,7.5rem);

  --edge:clamp(1.25rem,5vw,4.5rem);
  --measure:60ch;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:var(--t-body);
  line-height:1.62;
  letter-spacing:0.004em;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit}
/* iOS gives a button with no color of its own the system blue. Every
   button on the site sets one; this is the floor under all of them. */
button{color:inherit}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
h1[tabindex="-1"]:focus{outline:none}

/* ---- GRID · 15 columns so 7, 5 and 3 are all exact spans -------- */
.shell{max-width:1120px;margin:0 auto;padding-inline:var(--edge)}
.grid{display:grid;grid-template-columns:repeat(15,1fr);gap:0 var(--s3)}
.c5{grid-column:auto/span 5}
.c8{grid-column:auto/span 8}
.c10{grid-column:auto/span 10}
.start8{grid-column-start:8}

/* ---- TYPE ------------------------------------------------------- */
.display-5{font-family:var(--serif);font-weight:400;font-size:var(--d5);line-height:1.07;letter-spacing:-0.01em;margin:0;overflow-wrap:break-word}
.display-3{font-family:var(--serif);font-weight:400;font-size:var(--d3);line-height:1.14;margin:0}

h2.head{font-family:var(--sans);font-size:1.0625rem;font-weight:600;line-height:1.3;letter-spacing:-0.006em;margin:0 0 var(--s3)}
p{margin:0 0 1rem;max-width:var(--measure)}
p:last-child{margin-bottom:0}
.lead{font-size:var(--t-lead);line-height:1.55}
.quiet{color:var(--ink-70)}
.fine{font-size:var(--t-fine);line-height:1.5;color:var(--ink-45);letter-spacing:0.01em}
.num{font-variant-numeric:tabular-nums}

/* ---- CONTROLS --------------------------------------------------- */
.btn{
  display:inline-block;font:inherit;font-size:var(--t-body);font-weight:600;
  letter-spacing:0.005em;padding:0.9rem 1.6rem;border:1px solid var(--ink);
  background:var(--ink);color:var(--paper);text-decoration:none;cursor:pointer;
  transition:background .14s linear,color .14s linear;text-align:center;
}
.btn:hover{background:var(--paper);color:var(--ink)}
.btn[disabled]{border-color:var(--ink-20);background:var(--ink-20);color:var(--paper);cursor:not-allowed}
.btn-quiet{background:transparent;color:var(--ink)}
.btn-quiet:hover{background:var(--ink);color:var(--paper)}
.link{text-decoration:none;border-bottom:1px solid var(--ink-20);padding-bottom:1px;transition:border-color .14s linear}
.link:hover{border-color:var(--ink)}

label.f{display:block;margin-bottom:var(--s3);max-width:34rem}
label.f > span{display:block;font-size:var(--t-small);font-weight:600;margin-bottom:0.4rem}
label.f > span.hint:empty{display:none}
label.f > span.hint{display:block;font-size:var(--t-fine);font-weight:400;color:var(--ink-45);margin:-0.15rem 0 0.45rem;line-height:1.45}
input[type=text],input[type=email],input[type=tel],input[type=number],input[type=date],select,textarea{
  width:100%;font:inherit;font-size:var(--t-body);color:var(--ink);
  background:var(--paper);border:1px solid var(--ink-20);border-radius:0;padding:0.7rem 0.75rem;
}
select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--ink) 50%),linear-gradient(135deg,var(--ink) 50%,transparent 50%);background-position:calc(100% - 18px) 55%,calc(100% - 13px) 55%;background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:2.4rem}
textarea{min-height:6.5rem;resize:vertical;line-height:1.55}

/* ---- Dropdowns ---------------------------------------------------
   The field keeps the border, the ground and the padding every other
   field on the site has; what changes is that the list which opens is
   drawn here too. The select itself is still in the form, laid over
   its own wrapper at zero opacity so validation can focus it, with
   pointer events off so the click lands on the button.

   The caret is a hairline corner rotated, in the same weight as the
   rules, and it turns over when the list is open. On a touch screen
   the platform picker takes the taps back: our list is hidden and the
   select is live again. */
.sel{position:relative;display:block;width:100%}
.sel select{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;
  background:none;opacity:0;pointer-events:none;appearance:none}
.sel-btn{display:flex;align-items:center;justify-content:space-between;gap:0.75rem;width:100%;
  font:inherit;font-size:var(--t-body);color:var(--ink);background:var(--paper);
  border:1px solid var(--ink-20);border-radius:0;padding:0.7rem 0.75rem;text-align:left;
  cursor:pointer;transition:border-color .14s linear}
.sel-btn:hover{border-color:var(--ink-45)}
.sel-btn:focus-visible,.sel.on .sel-btn{outline:none;border-color:var(--ink);
  box-shadow:inset 0 0 0 1px var(--ink)}
.sel-btn[disabled]{color:var(--ink-45);cursor:default}
.sel-btn.is-ph .sel-v{color:var(--ink-45)}
.sel-v{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.sel-btn::after{content:'';flex:none;width:0.42rem;height:0.42rem;margin-left:auto;
  border-right:1px solid var(--ink-45);border-bottom:1px solid var(--ink-45);
  transform:translateY(-0.12rem) rotate(45deg);transition:transform .14s linear}
.sel-btn:hover::after,.sel.on .sel-btn::after{border-color:var(--ink)}
.sel.on .sel-btn::after{transform:translateY(0.1rem) rotate(225deg)}

.sel-menu{position:absolute;z-index:40;top:calc(100% + 5px);left:0;right:0;
  max-height:16.5rem;overflow:auto;padding:0.25rem 0;background:var(--paper);
  border:1px solid var(--ink);box-shadow:0 16px 34px rgba(43,38,34,.09)}
/* The selected row carries the same left bar the sizes and the plans
   use, so a chosen thing looks chosen the same way everywhere. */
.sel-o{padding:0.55rem 0.75rem;border-left:2px solid transparent;cursor:pointer;
  line-height:1.35}
.sel-o:hover,.sel-o.at{background:var(--blush)}
.sel-o[aria-selected="true"]{font-weight:600;border-left-color:var(--ink)}
@media (pointer:coarse){
  .sel-btn,.sel-menu{display:none}
  .sel select{position:static;inset:auto;opacity:1;pointer-events:auto;
    width:100%;height:auto;margin:0;padding:0.7rem 2.4rem 0.7rem 0.75rem;
    border:1px solid var(--ink-20);border-radius:0;background:var(--paper);
    color:var(--ink);-webkit-text-fill-color:var(--ink);font:inherit;font-size:1rem;
    appearance:none;-webkit-appearance:none;
    background-image:linear-gradient(45deg,transparent 50%,var(--ink) 50%),
      linear-gradient(135deg,var(--ink) 50%,transparent 50%);
    background-position:calc(100% - 18px) 55%,calc(100% - 13px) 55%;
    background-size:5px 5px,5px 5px;background-repeat:no-repeat}
  .sel select:disabled{color:var(--ink-45);-webkit-text-fill-color:var(--ink-45)}
  .sel select:focus{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
}
/* Radios and checkboxes are excluded: the inset ring is meant for a
   text field's own edge, and on a 13px control it drew a square around
   the dot. Their focus is shown on the row that contains them. */
input:not([type="radio"]):not([type="checkbox"]):focus,select:focus,textarea:focus{outline:none;border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
fieldset{border:0;margin:0 0 var(--s3);padding:0}
fieldset > legend{font-size:var(--t-small);font-weight:600;padding:0;margin-bottom:0.5rem}
input[type=radio],input[type=checkbox]{accent-color:#000;width:1rem;height:1rem;margin:0}

/* ---- IMAGE FIELDS ----------------------------------------------
   A real <img> when there is a photograph, a drawn placeholder when
   there is not. Nothing here is a background image, so real
   photographs are lazily loaded when they arrive.
   ---------------------------------------------------------------- */
/* Every photograph on the site is framed the same way: one black
   hairline on the box. Set here rather than per section so a new slot
   inherits it instead of being missed. */
.field{position:relative;background:var(--field);width:100%;overflow:hidden;border:1px solid var(--ink)}
.field > img,.field > .field-art{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.field-art > svg{width:100%;height:100%;display:block}
.field::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 30%,rgba(255,255,255,0) 40%,rgba(0,0,0,.05) 100%)}
.field.r-portrait{aspect-ratio:4/5}
.field.r-square{aspect-ratio:1/1}
.field-note{margin-top:0.55rem}
figure{margin:0}

/* Placeholder palettes. Real photographs replace these entirely. */
.pal-1{--ph-bg:#F6F2EB;--ph-bg2:#E8E0D4;--ph-1:#B08A93;--ph-2:#6E4B57;--ph-3:#EDE3D6;--ph-4:#9C7C86;--ph-green:#8C9A82;--ph-dark:#2B2A28;--ph-vessel:#DCD4C7}
.pal-2{--ph-bg:#F7F0E4;--ph-bg2:#E4D2BC;--ph-1:#B87B57;--ph-2:#8A5334;--ph-3:#EFE0CB;--ph-4:#CE9E7B;--ph-green:#7E8C72;--ph-dark:#2B2A28;--ph-vessel:#D9CDBB}
.pal-3{--ph-bg:#F3F4EE;--ph-bg2:#DFE3D6;--ph-1:#EFE9DD;--ph-2:#C6C6B4;--ph-3:#7C8C70;--ph-4:#A6B29A;--ph-green:#6F7D64;--ph-dark:#2B2A28;--ph-vessel:#DDDCD1}
.pal-4{--ph-bg:#EFEDE7;--ph-bg2:#DCD9CE;--ph-1:#6E4B57;--ph-2:#4E5A46;--ph-3:#B08A93;--ph-4:#8C9A82;--ph-green:#4E5A46;--ph-dark:#221F1E;--ph-vessel:#CFC9BC}
.pal-5{--ph-bg:#F8F3E9;--ph-bg2:#E9DCC6;--ph-1:#EADCC9;--ph-2:#B8815F;--ph-3:#D2BC9F;--ph-4:#9C8267;--ph-green:#8C9A82;--ph-dark:#2B2A28;--ph-vessel:#E0D6C6}
.pal-6{--ph-bg:#F3F1EC;--ph-bg2:#E2E1D6;--ph-1:#B08A93;--ph-2:#8C9A82;--ph-3:#EDE3D6;--ph-4:#6E4B57;--ph-green:#6F7D64;--ph-dark:#2B2A28;--ph-vessel:#D8D3C6}

/* ---- NAV -------------------------------------------------------- */
.nav{position:sticky;top:0;z-index:40;background:var(--paper);border-bottom:1px solid transparent;transition:border-color .15s linear}
.nav.stuck{border-bottom-color:var(--rule)}
.nav-in{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);height:4.5rem}
/* The wordmark is set italic, as drawn. Everything else in the serif
   stays upright. */
.wordmark{font-family:var(--serif);font-style:italic;font-size:2.05rem;line-height:1;text-decoration:none;letter-spacing:0.008em;white-space:nowrap}
.nav-links{display:flex;align-items:center;gap:1.9rem}
.nav-links a{text-decoration:none;font-size:var(--t-small);letter-spacing:0.01em;padding-bottom:2px;border-bottom:1px solid transparent}
.nav-links a:hover,.nav-links a[aria-current=page]{border-bottom-color:var(--ink)}
.nav-cta{font-size:var(--t-small);border-bottom:1px solid var(--ink)!important}
/* Higher specificity than `.nav-links a`, which otherwise keeps its
   2px bottom padding and pushes the label to the foot of the button. */
.nav-links .nav-cta,.nav-panel .nav-cta{display:inline-flex;align-items:center;line-height:1;padding:0.7rem 1.15rem}
.nav-toggle{display:none;appearance:none;-webkit-appearance:none;font:inherit;
  font-size:var(--t-small);color:var(--ink);-webkit-text-fill-color:var(--ink);
  background:none;border:0;padding:0.4rem 0;cursor:pointer;
  text-decoration:underline;text-underline-offset:3px}
.nav-panel{display:none}
@media (max-width:880px){
  .nav-links{display:none}
  .nav-toggle{display:inline-block}
  .nav-panel.open{display:block;border-top:1px solid var(--rule);padding:var(--s3) 0 var(--s5)}
  .nav-panel a{display:block;text-decoration:none;font-size:1.125rem;padding:0.6rem 0}
}

/* ---- SECTIONS --------------------------------------------------- */
.band{padding-block:var(--s-band)}
.band-tight{padding-block:var(--s7)}
.rule-top{position:relative}
.rule-top::before{content:'';position:absolute;top:0;left:var(--edge);right:var(--edge);border-top:1px solid var(--rule)}

/* ---- How it works ------------------------------------------------
   Three points, and nothing under them. The sentence each one used to
   carry said what the point already says, and three sentences in a row
   is a paragraph pretending to be a diagram.

   The figure is set in the wordmark's face, which appears nowhere else
   on the site, so it reads as a mark rather than as a number in the
   copy. Two grounds, both already in the language: the sand disc the
   strip uses, and green ink on it.
   ---------------------------------------------------------------- */
.how-head{text-align:center}
.how{list-style:none;display:grid;grid-template-columns:repeat(3,1fr);
  gap:var(--s5) var(--s7);margin:var(--s5) 0 0;padding:0}
.how li{display:grid;gap:1.1rem;justify-items:center;text-align:center}
.how-n{display:flex;align-items:center;justify-content:center;
  width:3.5rem;height:3.5rem;border-radius:999px;border:1px solid transparent;
  font-family:var(--mark);font-weight:500;font-size:2rem;line-height:1;
  /* Cormorant sets old-style figures by default, so 1, 2 and 3 are three
     different heights and no single nudge centres all three. Lining
     figures share one height and centre as a set. */
  font-variant-numeric:lining-nums;font-feature-settings:"lnum" 1;
  padding-top:0.04em}
/* One pair of the site's colors per step. Every disc is a color that is
   neither ground, so all three read on chalk and on blush. */
.how li:nth-child(1) .how-n{background:var(--blush);border-color:var(--rule);color:var(--ink)}
.how li:nth-child(2) .how-n{background:var(--ink);color:var(--paper)}
.how li:nth-child(3) .how-n{background:var(--clay);color:var(--paper)}
.how-t{font-family:var(--serif);font-size:1.2rem;line-height:1.3;max-width:15rem}
@media (max-width:760px){
  .how{grid-template-columns:1fr;gap:var(--s5)}
  .how-t{max-width:none}
}

.defs{margin:0}
.defs dt{font-weight:600;margin-top:var(--s3)}
.defs dt:first-child{margin-top:0}
.defs dd{margin:0.3rem 0 0;max-width:var(--measure);color:var(--ink-70)}

.panel{border-top:1px solid var(--ink);padding-top:var(--s3)}
/* The photograph of the chosen arrangement, at the top of the column
   that stays with her. Capped, or a 4:5 picture in a five-column
   panel pushes the total off the screen. */
/* One picture per palette in the order. One is the common case and
   looks exactly as it did; two share the width, which is the whole
   order visible at a glance rather than half of it. */
.sum-art{display:grid;gap:0.85rem;margin:0 0 var(--s5)}
.sum-art.two{grid-template-columns:1fr 1fr;gap:0.7rem}
.sum-art .field{max-height:24rem}
/* When the window is short the frame goes wide, and the vessel sits
   low in every one of these photographs, so the crop is held below
   centre rather than through the middle. */
.sum-art .field > img{object-position:50% 58%}
.sum-art .field.is-empty,.bar-art.is-empty{background:var(--field)}
.sum-art .field.is-empty{aspect-ratio:4/5}
.sum-cap{margin:0.5rem 0 0;font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:0.9375rem;color:var(--ink-70);letter-spacing:0}
@media (min-width:901px){.panel{position:sticky;top:6.5rem}}
.sum{width:100%;border-collapse:collapse}
.sum td{padding:0.5rem 0;border-bottom:1px solid var(--rule);vertical-align:top}
.sum td:last-child{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.sum tr.total td{border-bottom:0;border-top:1px solid var(--ink);font-weight:600;padding-top:0.8rem}

/* A four-column grid rather than a wrapping flex row. Wrapping put
   the line total on its own line under the name, which read as a
   second item and left a ragged hole in every row. Columns hold. */
.items{border-top:1px solid var(--ink);margin-bottom:var(--s5);max-width:34rem}
.item{display:grid;grid-template-columns:minmax(0,1fr) auto auto;
  column-gap:1.1rem;row-gap:0.2rem;align-items:center;padding:0.8rem 0;border-bottom:1px solid var(--rule)}
.item-name{font-weight:600;grid-column:1;grid-row:1;display:flex;align-items:center;gap:0.6rem}
.item-name .chip{width:2.4rem;flex:none;outline-color:var(--rule)}
.item-note{font-size:var(--t-small);color:var(--ink-45);grid-column:1;grid-row:2;line-height:1.5}
.item .stepper{grid-column:2;grid-row:1/span 2}
.item-line{grid-column:3;grid-row:1/span 2;min-width:4.5rem;text-align:right;color:var(--ink-20)}
.item.on .item-line{color:var(--ink)}
.stepper{display:inline-flex;align-items:center;border:1px solid var(--ink-20)}
.stepper button{width:2.75rem;height:2.75rem;font:inherit;font-size:1.05rem;line-height:1;background:var(--paper);border:0;color:var(--ink);cursor:pointer;transition:background .14s linear,color .14s linear}
.stepper button:hover{background:var(--ink);color:var(--paper)}
.stepper > span{min-width:2.25rem;text-align:center}
.stepper.compact button{width:2.4rem;height:2.4rem}

/* Questions, in their own section: a list that opens one answer at a
   time, so the section reads as a short index rather than a wall. */
.faq{border-top:1px solid var(--ink);max-width:46rem;margin:var(--s5) 0 0}
/* Two columns of questions rather than one column and a void. */
/* One list. Split across two columns the reader had to scan down and
   then back up, and an odd number left a hole. */
.faq details{border-bottom:1px solid var(--rule)}
.faq summary{display:flex;align-items:baseline;justify-content:space-between;gap:1.25rem;padding:0.95rem 0;cursor:pointer;font-weight:600;list-style:none}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'\2193';font-weight:400;color:var(--ink-45);line-height:1.2;transition:color .14s linear}
.faq summary:hover::after{color:var(--ink)}
.faq details[open] summary::after{content:'\2191'}
.faq details > p{margin:0 0 1.1rem;color:var(--ink-70)}

/* A page never ends on something passive. */
.cta-band{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s5);border-top:1px solid var(--ink);padding-top:var(--s5)}
.cta-band p{margin:0;max-width:32rem}
.person{display:grid;grid-template-columns:5fr 7fr;gap:var(--s5) var(--s-band);align-items:start}
/* Copy first, photograph pushed right. The events page runs the
   photograph first; on the homepage the heading starts at the left
   margin like every other section heading on the page, and the picture
   breaks right. Text-first in the source is also the right order on
   one column. */
.person--right{grid-template-columns:7fr 5fr}
.person--right figure{max-width:26rem;justify-self:end;width:100%}
@media (max-width:900px){
  .person--right figure{max-width:22rem;justify-self:center;order:-1}
}
/* A short, quiet centered page: thank you, 404. Padding as well as a
   min-height, so the headline can never butt the sticky nav once the
   content outgrows the centring. */
.slab{min-height:62svh;display:flex;align-items:center;padding-block:var(--s7)}
.slab .inner{max-width:34rem}

/* Opt-in that rides along on a form we are already collecting an
   email in. Unticked by default: a pre-ticked box is not consent. */
.optin{display:flex;gap:0.55rem;align-items:flex-start;margin:-0.35rem 0 var(--s3);max-width:34rem;font-size:var(--t-small);line-height:1.5;cursor:pointer}
.optin input{margin-top:0.2rem;flex:none}

/* Newsletter. A secondary action, so it never gets a section of its
   own weight: hairline rules, small label, one inline row. */
.signup{max-width:30rem}
.foot .signup{border-bottom:1px solid var(--rule);padding-bottom:var(--s5);margin-bottom:var(--s5)}
.signup-label{display:block;font-size:var(--t-small);font-weight:600}
.signup-note{margin:0.3rem 0 0.85rem}
.signup-row{display:flex;flex-wrap:wrap;gap:0.5rem}
.signup-row input{flex:1 1 12rem;min-width:0}
.signup-row .btn{padding:0.72rem 1.1rem;font-size:var(--t-small);white-space:nowrap}
.signup-said{margin-top:0.6rem}
.signup-said:empty{display:none}

/* The one editorial instance: end of the homepage, where a reader who
   was not going to buy today has run out of page. */
.signup-band{display:grid;grid-template-columns:1fr minmax(19rem,26rem);gap:var(--s5) var(--s-band);align-items:end}
.signup-band .signup{max-width:none}
@media (max-width:900px){.signup-band{grid-template-columns:1fr;gap:var(--s5)}}

/* The homepage carries its own signup block, so the footer one stands
   down there. Done in CSS so it holds with JavaScript disabled. */
body[data-page="arrangements"] .foot .signup{display:none}

.foot{border-top:1px solid var(--rule);padding-block:var(--s7) var(--s5);margin-top:var(--s-band)}
.foot-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s5) var(--s3)}
.foot h3{font-size:var(--t-small);font-weight:600;margin:0 0 0.6rem}
.foot p,.foot li{font-size:var(--t-small);color:var(--ink-70);margin:0 0 0.3rem}
.foot ul{list-style:none;margin:0;padding:0}
.foot a{text-decoration:none;border-bottom:1px solid var(--ink-20)}

[id]{scroll-margin-top:6rem}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;background:var(--ink);color:var(--paper);padding:0.75rem 1rem;z-index:100}
.skip:focus{left:0}

/* One orchestrated moment on load. Nothing else moves. The homepage
   fold applies it, further down. */
@keyframes settle{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---- MOBILE ----------------------------------------------------- */
/* Under 16px, iOS zooms the page when a field takes focus and does not
   zoom back out, so every control steps up together at this width. */
@media (max-width:900px){
  input[type=text],input[type=email],input[type=tel],input[type=number],
  input[type=date],select,textarea,.sel-btn,.sel-o{font-size:1rem}
  /* A stepper is the most-tapped control on the order page. 44px is the
     floor for a thumb, and the compact variant sat under it. */
  .stepper.compact button{width:2.75rem;height:2.75rem}
  /* Same floor for the menu button, which was a 33px target. */
  .nav-toggle{padding:0.7rem 0;margin-block:-0.7rem}
  .grid{grid-template-columns:1fr;gap:0}
  .c5,.c8,.c10{grid-column:auto}
  .start8{grid-column-start:auto}
  .person{grid-template-columns:1fr;gap:var(--s5)}
  .panel{border-top:1px solid var(--ink)}
  .foot-grid{grid-template-columns:1fr 1fr}
}
@media (max-width:520px){
  .foot-grid{grid-template-columns:1fr}
  .nav-in{height:3.75rem}
  .wordmark{font-size:1.7rem}
}

/* The chip is the palette's face wherever it appears: on the swatches
   in the fold and on the order rows, where it is the fastest way to
   tell one line from another. */

/* ---- THE ORDER, IN THREE CHAPTERS -------------------------------
   The same controls in one undivided column read as a long form.
   Under three numbered headings they read as three short decisions,
   which is what they actually are. Nothing is hidden behind a step
   the buyer has to click through: the whole order stays on one page
   and the summary stays visible beside it.
   ---------------------------------------------------------------- */
/* ==================================================================
   ADDITIONS · the sell page, the order page, the thank you page
   Same vocabulary as everything above: hairline rules, no radius,
   black and white, color only inside the photographs.
   ================================================================== */

/* ---- Availability chip ------------------------------------------
   The one piece of urgency on the site, and it is only persuasive
   because it is read from the same numbers the date picker is. It
   is a box rather than a line so it can sit next to the headline
   without being mistaken for more copy.
   ---------------------------------------------------------------- */
.avail{display:inline-flex;align-items:baseline;gap:0.5rem;border:1px solid var(--ink);
  padding:0.45rem 0.8rem;font-size:var(--t-small);line-height:1.3}
.avail.closed{border-color:var(--ink-20);color:var(--ink-70)}


/* ---- Postcode check ---------------------------------------------
   Answered on the page rather than at the payment screen, where the
   answer costs you the order.
   ---------------------------------------------------------------- */
.zip-row{display:flex;flex-wrap:wrap;gap:0.5rem;max-width:24rem}
.zip-row input{flex:1 1 8rem;min-width:0}
.zip-row .btn{padding:0.7rem 1.1rem;white-space:nowrap}
.zip-said{margin-top:0.6rem;font-size:var(--t-small);line-height:1.5}
.zip-said:empty{display:none}
.zip-said.no{color:var(--ink-70)}

/* Anything that only applies to one branch of the order. */
.only{display:none}
.only.show{display:block}

/* ---- Mobile order bar -------------------------------------------
   Desktop keeps the sticky summary column. Mobile has no column, so
   the total and the button travel with the buyer instead of waiting
   at the bottom of a form she has not finished reading.
   ---------------------------------------------------------------- */
.bar{position:fixed;left:0;right:0;bottom:0;z-index:50;background:var(--paper);
  border-top:1px solid var(--ink);padding:0.7rem var(--edge) calc(0.7rem + env(safe-area-inset-bottom));
  display:none;align-items:center;gap:1rem}
/* On a phone the summary column sits under the form, so the bar
   carries the picture as well as the number. */
.bar .bar-art{flex:none;width:2.4rem;height:3rem}
.bar .bar-sum{flex:1;min-width:0;font-size:var(--t-small);line-height:1.35}
.bar .bar-sum b{display:block;font-size:var(--t-body);font-variant-numeric:tabular-nums}
.bar .bar-sum b .per{font-family:var(--sans);font-size:var(--t-fine);font-weight:400;color:var(--ink-45);margin-left:0.35rem}
.bar .btn{padding:0.8rem 1.2rem;white-space:nowrap}
@media (max-width:900px){
  body[data-page="order"] .bar{display:flex}
  body[data-page="order"]{padding-bottom:calc(5.5rem + env(safe-area-inset-bottom))}
  /* The panel's own button stays. On one column the panel sits at the
     end of the form, which is where somebody who scrolled past the bar
     looks for the way to pay, and it arrives with the total, the
     photograph and the line saying what is still missing. Two buttons
     that do the same thing is the right answer here: the script holds
     both in the same state, so neither can be live while the other is
     not. */
}

@media (max-width:420px){
  /* The number is the thing she is checking; the sentence after it can
     wait for the summary itself, which is a scroll away. */
  .bar{gap:0.7rem}
  .bar .bar-n{display:none}
  .bar .btn{padding:0.8rem 0.95rem}
  /* Quantity on the right, everything about the line under itself on
     the left, rather than three columns sharing 280px. */
  .item{grid-template-columns:minmax(0,1fr) auto;column-gap:0.7rem}
  .item .stepper{grid-column:2;grid-row:1/span 3}
  .item-line{grid-column:1;grid-row:3;min-width:0;text-align:left}
  .item-name .chip{width:2rem}
}
/* Narrower again and the total needs the picture's room as well. */
@media (max-width:360px){
  .bar .bar-art{display:none}
}

/* ---- Order page chrome ------------------------------------------
   One job, so the links that lead away from it stand down. The
   wordmark still goes home, because a locked page reads as a trap.
   ---------------------------------------------------------------- */
/* The checkout carries the wordmark and nothing else, so anything that
   finds its way back into that header stands down. */
body[data-page="order"] .nav-links,
body[data-page="order"] .nav-toggle,
body[data-page="order"] .nav-panel{display:none}

/* ---- What happens next ------------------------------------------ */
.next{list-style:none;margin:var(--s3) 0 0;padding:0;border-top:1px solid var(--ink);max-width:40rem}
.next li{border-bottom:1px solid var(--rule);padding:0.8rem 0;color:var(--ink-70)}
.next li b{display:block;color:var(--ink);font-weight:600}

/* ---- Post-purchase ----------------------------------------------
   Two offers, after the money, where there is nothing left to lose
   by asking.
   ---------------------------------------------------------------- */
.after{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5) var(--s7);margin-top:var(--s5)}
.after section{border-top:1px solid var(--ink);padding-top:var(--s3)}
@media (max-width:900px){.after{grid-template-columns:1fr;gap:var(--s7)}}

/* The order page runs a single column at every width: a summary
   column beside a form the buyer has not filled in yet is a column
   of nothing. It appears once there is something in it. */
.order-grid{display:grid;grid-template-columns:7fr 5fr;gap:var(--s7) var(--s-band);align-items:start}
/* The summary sticks, and a sticky element can only move inside its
   containing block: with the aside collapsed to its own content there
   was nothing to move through, so the picture and the total scrolled
   away with the form. The aside takes the height of the row instead. */
.order-grid > aside{align-self:stretch}
@media (max-width:900px){.order-grid{grid-template-columns:1fr;gap:var(--s5)}}



/* ==================================================================
   THE FOLD CONFIGURATOR
   The photograph is the loudest thing on the site and everything
   below it is deliberately quieter, so the page has one centre
   rather than six equal bands. On desktop the picture runs to the
   window edge: the fold is structurally different from what follows,
   not merely taller.
   ================================================================== */
.hero-config{
  display:grid;
  /* The panel takes a share of the width rather than a fixed 32rem,
     so at the narrow end of the two-column range the picture is not
     squeezed to a third of the panel's size. */
  grid-template-columns:minmax(0, min(52rem, calc(100svh - var(--navh, 4.5rem) - var(--s5) - var(--s3)))) clamp(18rem, 42%, 32rem);
  gap:0 var(--s-band);
  /* The picture is capped by the height on screen, so on a wide, short
     window its column has width to spare. Pinned to one margin with
     the panel pinned to the other, all of that spare width fell
     between them and grew with the window. The pair is centered
     instead, so the two columns stay the same distance apart at every
     width and the surplus goes to the outside. */
  justify-content:center;
  /* Not centered. Centring a short photograph against a tall options
     column opens a hole above and below it that reads as a mistake;
     the two columns start on the same line instead, and the picture
     is pinned so it stays with whatever she is choosing. */
  align-items:stretch;
  /* Inside the margin on both sides. Full-bleed to the left edge cost
     the picture the room it needed to be seen whole. */
  padding:var(--s3) max(var(--edge), calc((100% - 1360px) / 2)) var(--s-band);
}
.hero-config .shot{position:relative}
/* Only the picture is pinned, and nothing shares its lane. At 283px
   plus the 97px offset it always shows whole. */
.hero-config .shot .field{position:sticky;top:calc(var(--navh, 4.5rem) + var(--s3))}
/* The drawn stand-in needs a shape; a real photograph brings its own.
   Forcing 4:5 on both meant the picture was re-cropped at every
   window size, cutting the top off the arrangement. */
.hero-config .shot .field{
  aspect-ratio:4/5;max-width:52rem;
  /* Sticky, so changing the size or the palette repaints a picture
     that is still on screen. A control whose result has scrolled away
     is a control she cannot judge. */
}
/* Square, and the photograph fills it. A 4:5 photograph held to its
   own proportions was narrower than the column, and the two strips of
   background either side of it carried the field's vignette, which
   read as a shadow around the picture. Cover on a square crops the
   photograph evenly top and bottom instead, so it meets both edges.
   The width is capped by the height available on screen so the square
   is never taller than the picture it replaced. */
.hero-config .shot .field:has(img){
  aspect-ratio:1/1;
}
/* The drawing sizes like a picture would. */
.hero-config .shot .field .art{display:block;width:100%;height:auto}

/* The container shrinks to the picture. Left at full column width it
   kept its own gray background either side of a height-capped 4:5
   photograph, which is a letterbox, not a layout. */
/* Photograph or drawing, the box shrinks to the picture and the
   picture keeps its own proportions. */
.hero-config .shot .field:has(img),
.hero-config .shot .field:has(.art){width:100%;margin-inline:0;background:none}
/* A drawing scales freely, so it is capped to something that fits on
   a screen whole rather than to the column it happens to sit in. */
.hero-config .shot .field:has(.art){aspect-ratio:auto;width:100%;max-width:32rem}


.hero-config .panel-cfg{padding-block:0}
/* The photograph is the loudest thing in the fold and this sits beside
   it. At 3.6rem the sentence ran four lines of display serif against a
   square picture, and the two argued. */
.hero-config h1{font-size:clamp(1.75rem,3.2vw,2.6rem);line-height:1.14;text-wrap:balance;margin:0}
.hero-config .lead{margin-top:var(--s3);color:var(--ink-70);max-width:34rem}

/* One label vocabulary for the two controls, quiet enough that the
   controls themselves carry the weight. */
/* No outer border. The controls already have edges of their own, and
   a box around them drew a second frame inside a column that was
   already a column. */
.buy{margin-top:var(--s5)}
.buy > .cfg-label:first-child{margin-top:0}

.cfg-label{display:block;font-size:var(--t-small);font-weight:600;margin:var(--s5) 0 0.6rem}
.cfg-label .n{font-weight:400;color:var(--ink-45)}

/* Two, so each square is big enough to read a palette in rather than
   three thumbnails that all look like flowers. */
.swatches{display:grid;grid-template-columns:1fr 1fr;gap:0.75rem;max-width:26rem}
.swatch{display:block;cursor:pointer}
.swatch input{position:absolute;opacity:0;width:1px;height:1px}
/* A paint chip: the colors themselves, which is the one thing a
   small square can actually prove about a palette. */
.chip{display:flex;aspect-ratio:4/3;overflow:hidden;outline:1px solid var(--rule);outline-offset:0;
  transition:outline-color .14s linear,outline-width .14s linear}
.chip > span{display:block;height:100%}
.swatch.on .chip{outline:1px solid var(--ink);outline-offset:0}
.swatch:has(input:focus-visible) .chip{outline:2px solid var(--ink);outline-offset:3px}

/* A span by default, so it has to be told to be a box before the
   aspect ratio means anything. */
/* Landscape, not square: two square swatches at full column width add
   most of a screen of height to the fold. */
.swatch .field{display:block;aspect-ratio:4/3;outline:1px solid var(--rule);outline-offset:0;transition:outline-color .14s linear,outline-width .14s linear}
.swatch.on .field{outline:1px solid var(--ink);outline-offset:0}
.swatch-n{display:block;font-size:var(--t-fine);margin-top:0.4rem;color:var(--ink-45)}
.swatch.on .swatch-n{color:var(--ink)}
.swatch:has(input:focus-visible) .field{outline:2px solid var(--ink);outline-offset:3px}

/* The product, stated rather than chosen. It keeps the look the
   selectable rows had, black border and the left bar, because that is
   the site's vocabulary for a thing that is chosen; what it loses is
   the radio, which with one product would be a control nobody can
   use. The tick says the same thing without pretending. */
.product{display:flex;align-items:flex-start;gap:0.8rem;padding:0.9rem 1rem;
  border:1px solid var(--ink);box-shadow:inset 3px 0 0 var(--ink);
  max-width:32rem;margin:0 0 var(--s5)}
.product-m{flex:1;min-width:0;display:block}
/* Name at the left, money against the right edge, on one baseline: the
   same order the summary table puts them in. Beside the name it read
   as a tag stuck on the product. */
.product-m b{display:flex;align-items:baseline;gap:0.8rem;font-weight:600}
.product-p{margin-left:auto;font-weight:400;color:var(--ink-70);white-space:nowrap}
.product-m .n{display:block;font-size:var(--t-small);color:var(--ink-45);
  margin-top:0.15rem;line-height:1.5}
.product-tick{flex:none;width:0.72rem;height:0.4rem;margin-top:0.42rem;
  border-left:1.5px solid var(--ink);border-bottom:1.5px solid var(--ink);
  transform:rotate(-45deg)}

/* Opens in place under the tick. Not a step, not a section: three
   fields that only exist if the answer was yes. */
.giftfields{margin-top:var(--s3);padding-left:1.6rem;border-left:1px solid var(--rule)}
.giftfields[hidden]{display:none}
.giftfields-note{margin:0 0 var(--s3);max-width:34rem}
.giftfields .f:last-child{margin-bottom:0}
/* The one add-on, under the tick that makes it relevant. A ribbon is
   how the arrangement arrives rather than a second thing to buy, so
   it sits inside the gift block and nowhere else on the site. */
.giftextras{margin:var(--s5) 0}
.giftextras .cfg-label{margin-top:0}
.extra{margin:0}
.extra-n{display:block;font-weight:600}
.extra-note{display:block;color:var(--ink-70)}

.cfg-foot{margin-top:var(--s5);border-top:1px solid var(--rule);padding-top:var(--s3)}
.cfg-price{font-family:var(--serif);font-size:2.6rem;font-weight:500;line-height:1;display:flex;
  align-items:baseline;flex-wrap:wrap;gap:0 0.55rem}
.cfg-price s{font-size:1.5rem;color:var(--ink-45);text-decoration-thickness:1px}
.cfg-price .per{font-family:var(--sans);font-size:var(--t-small);font-weight:400;color:var(--ink-45)}
.cfg-fine{margin:0.45rem 0 0;font-size:var(--t-small);color:var(--ink-45);max-width:26rem}
.cfg-act{display:flex;flex-wrap:wrap;align-items:center;gap:0.9rem;margin-top:var(--s3)}
.cfg-act .btn{padding:1rem 1.9rem}

/* 820, not 1000: between those widths there is still room for the
   picture to sit beside the panel, which is the only arrangement where
   a portrait drawing is neither too tall nor stranded in white. */
@media (max-width:820px){
  .hero-config{grid-template-columns:1fr;gap:var(--s5);padding:0 0 var(--s7)}
  /* One column, so there is nothing to stay beside. */
  .hero-config .shot .field{aspect-ratio:1/1;position:relative;top:auto}
  /* One column: the picture is scrolled past rather than pinned
     beside a scrolling panel, so it has no reason to fit the window.
     Left capped, it shrank to a third of the row and sat narrower
     than every control under it. */
  /* The picture takes the same gutter the panel gives its controls,
     so it starts and ends on their edges instead of bleeding to the
     window while everything under it is inset. */
  .hero-config .shot{padding-inline:var(--edge)}
  .hero-config .shot .field:has(img){width:100%;max-width:none;margin-inline:0;aspect-ratio:1/1}
  /* One column: the drawing stays a reasonable size and centers,
     rather than becoming a 1040px-tall wall. */
  /* Fills the column like every control under it. The crop above is
     what makes that a reasonable height now; capping the width only
     traded a tall drawing for a small one in a wide empty margin. */
  .hero-config .shot .field:has(.art){width:100%;max-width:none;margin-inline:0}
  /* The lead folds keep their portrait crop on one column, with a
     ceiling on the height rather than a switch of ratio.

     Ratio alone cannot be right across this whole range, because on
     one column the picture's width is the column's width. At 390px
     that is a 350px column and 4:5 is 437px tall, which is the whole
     arrangement. At 780px it is a 690px column and 4:5 is 862px tall,
     which is a wall, and squaring it instead threw away a fifth of
     every photograph on phones as well.

     A height ceiling gives both: under it nothing is cropped, over it
     the crop grows only as far as it has to. Placed after the square
     rules above and carrying :has(img) so the specificity ties at
     (0,3,1) and source order decides. */
  .hero-config--lead .shot .field{aspect-ratio:4/5}
  .hero-config--lead .shot .field:has(img){aspect-ratio:4/5;max-height:34rem}
  .hero-config .panel-cfg{padding:0 var(--edge)}
  /* A chip is a 4:3 box, so width sets its height. Uncapped it grew to
     410\u00d7307 and made the free, secondary choice the loudest thing
     in the fold. */
  .swatches{max-width:26rem}
}

/* ==================================================================
   THE ACCORDION ORDER
   Four steps, one open. Not a wizard: same URL, nothing lost on a
   back button, and a finished step collapses to the answer it
   produced rather than to a label.
   ================================================================== */
.acc{border-top:1px solid var(--ink)}
.acc:last-of-type{border-bottom:1px solid var(--ink)}
.acc-head{display:flex;align-items:center;gap:0.9rem;width:100%;padding:1.15rem 0;
  background:none;border:0;font:inherit;text-align:left;cursor:pointer;color:inherit}
.acc-n{display:flex;align-items:center;justify-content:center;flex:none;
  width:2.25rem;height:2.25rem;border-radius:999px;border:1px solid transparent;
  font-family:var(--mark);font-weight:500;font-size:1.25rem;line-height:1;
  font-variant-numeric:lining-nums;font-feature-settings:"lnum" 1;padding-top:0.04em}
.acc[data-acc="1"] .acc-n{background:var(--blush);border-color:var(--rule);color:var(--ink)}
.acc[data-acc="2"] .acc-n{background:var(--ink);color:var(--paper)}
.acc[data-acc="3"] .acc-n{background:var(--clay);color:var(--paper)}
.acc-t{font-weight:600;font-size:1.0625rem;letter-spacing:-0.006em;flex:none}
.acc-s{flex:1;min-width:0;font-size:var(--t-small);color:var(--ink-45);text-align:right;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acc.open .acc-s{display:none}
.acc-head::after{content:'+';flex:none;color:var(--ink-45);line-height:1.2}
.acc.open .acc-head::after{content:'\2212'}
.acc-body{display:none;padding:0 0 var(--s5) 3.15rem}
.acc.open .acc-body{display:block}
.acc-body > *:last-child{margin-bottom:0}
/* The gift question is the last thing asked in step one and the
   button is the first thing after it. Squeezed together they read as
   one control. A rule and its own air separate them. */
.giftask{margin-top:var(--s5);padding-top:var(--s3);border-top:1px solid var(--rule);max-width:34rem}
.giftask .optin{margin:0}
.acc-body .only[data-only="gift"].show{margin-top:var(--s3)}
.acc-act{margin-top:var(--s5);padding-top:var(--s5);border-top:1px solid var(--rule);max-width:34rem}
@media (max-width:560px){.acc-body{padding-left:0}.acc-t{font-size:var(--t-body)}}

/* ---- Section heads below the fold -------------------------------
   A third typographic level, so the bands are subordinate to the
   fold instead of competing with it.
   ---------------------------------------------------------------- */
h2.head-lg{font-family:var(--serif);font-weight:400;font-size:var(--d3);line-height:1.14;
  letter-spacing:0;margin:0 0 var(--s3)}

/* Padding descends down the page so it resolves rather than marches. */
.band-a{padding-block:var(--s7)}
.band-b{padding-block:var(--s7)}
.band-c{padding-block:var(--s5)}

/* One row: heading, note, field. The gift argument that used to sit
   beside it is a tick in the order form now. */
.reach{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s3) var(--s7);align-items:start}
.reach .head-lg{margin:0}
.reach .fine{margin:0.4rem 0 0;max-width:30rem}
.reach .zip-row{margin:0}
/* The question sits on the control that answers it. As the section
   heading it was a screen-width away from the field, and by the time
   the eye reached the box it had nothing to do with. */
.zip-ask .cfg-label{margin:0 0 0.6rem}
.reach .zip-said{grid-column:1/-1;margin:0}
.reach .zip-said:empty{display:none}
@media (max-width:640px){.reach{grid-template-columns:1fr;align-items:start}}

/* A price floor is never a bare number. On the product page this slot
   holds what the thing beside it costs; here it is the bottom of a
   range, so it carries its own qualifier. */
.cfg-price .from{font-family:var(--sans);font-size:var(--t-small);font-weight:400;color:var(--ink-45);margin-right:0.4rem}

/* ---- The homepage fold ------------------------------------------
   Built on .hero-config, the same fold the product and events pages
   use, rather than on a grid of its own. Three rounds of bespoke rules
   here all failed on geometry those shared rules had already solved:
   the column caps that keep a 4:5 picture inside the window, the
   sticky offset, and the breakpoint where two columns stop being worth
   having.

   What the homepage puts in the right column is the only thing that
   differs, and it is the thing that should differ: two doors with
   their prices, where the product page has controls and events has a
   form.

   The doors restack inside that column. At up to 34rem there is not
   room for a name, a sentence and a price on one line, so the name
   sits above the sentence and the figure holds the right edge.
   ---------------------------------------------------------------- */
.panel-cfg .doorlist{margin-top:var(--s5)}
.panel-cfg .door{grid-template-columns:minmax(0,1fr) auto;gap:0.5rem var(--s3);
  padding:var(--s3) 0}
.panel-cfg .door-n{grid-column:1;grid-row:1;font-size:1.5rem}
.panel-cfg .door-m{grid-column:1;grid-row:2;max-width:none}
.panel-cfg .door-p{grid-column:2;grid-row:1/span 2;align-self:start}
.panel-cfg .door-fig{font-size:1.35rem}
/* The section rule below closes the fold now, so the last door does
   not need its own: confined to the panel it was a 366px hairline
   dangling in the right half of the page. */
.panel-cfg .door:last-child{border-bottom:0}

/* Two doors as a hairline-ruled list, not two bordered cards. As cards
   they were boxes of unequal height sitting next to each other, which
   reads as a broken pricing table rather than as a choice. Rows take
   the full width, so the events door being three facts and two prices
   longer than the other stops being a layout problem and becomes the
   emphasis.

   Events leads on purpose. It is the higher-value ask, it costs the
   reader nothing to make, and one wedding is roughly fifteen baskets.
   ---------------------------------------------------------------- */
.doorlist{border-top:1.5px solid var(--ink)}
.door{display:grid;grid-template-columns:minmax(0,12rem) minmax(0,1fr) auto;
  gap:var(--s3) var(--s5);align-items:start;padding:var(--s5) 0;
  border-bottom:1px solid var(--rule);text-decoration:none;color:inherit;
  transition:border-color .14s linear}
.door--lead{border-bottom-color:var(--ink)}
/* A full-width row is the primary control on the busiest page, so it
   answers before the cursor reaches the small link text. Three cues,
   none of which move anything: the name underlines, its rule darkens,
   and the row's own rule goes black. */
.door:hover .door-n{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}
.door:hover{border-bottom-color:var(--ink)}
.door-n{font-family:var(--serif);font-size:var(--d3);line-height:1.08}
.door-m{max-width:34rem;color:var(--ink-70)}
.door-m > span{display:block}
.door-go{margin-top:0.9rem;font-size:var(--t-small);font-weight:600;color:var(--ink);
  border-bottom:1px solid var(--ink-20);padding-bottom:1px;width:fit-content;
  transition:border-color .14s linear}
.door:hover .door-go{border-color:var(--ink)}
.door:has(:focus-visible){outline:2px solid var(--ink);outline-offset:4px}
.door-p{display:grid;gap:0.8rem;text-align:right;white-space:nowrap}
.door-fig{font-family:var(--serif);font-size:1.5rem;font-weight:500;line-height:1}
.door-fig .from{display:block;font-family:var(--sans);font-size:var(--t-fine);font-weight:400;
  color:var(--ink-45);margin-bottom:0.3rem}
@media (max-width:760px){
  .door{grid-template-columns:1fr;gap:var(--s3)}
  .door-p{text-align:left;grid-auto-flow:column;justify-content:start;gap:var(--s5)}
}

/* The one orchestrated moment on load, kept on the homepage fold now
   that the fold is two columns rather than a band and a line. */
body[data-page="home"] .panel-cfg > *{animation:settle .5s cubic-bezier(.2,.6,.2,1) both}
body[data-page="home"] .panel-cfg > *:nth-child(2){animation-delay:.08s}
body[data-page="home"] .panel-cfg > *:nth-child(3){animation-delay:.16s}

/* ---- The events fold --------------------------------------------
   Same two columns as the product fold, because the structure works:
   the picture on one side, the decision on the other. Not the same
   square. A square suits a thing being bought off a product page;
   this is a photograph of work, so it keeps a portrait crop and shows
   more of the room.
   The picture track carries a height cap, as the base fold's does. A
   flat 30rem overwrote the shorthand and lost it, and at 4:5 a 480px
   track is 600px tall, so the fold needed 697px of viewport before the
   sticky picture showed whole: it clipped on a 1366x768 laptop. The
   0.8 factor is the 4:5 ratio, so the capped height is exactly what is
   on screen.

   Scoped to the two-column range on purpose. Sitting at the top level
   these rules came after the max-width:820px block, so at equal
   specificity they won and pinned the picture to 30rem on one column,
   which stranded it at 480px inside a 700px column. min-width:821px
   says what was always meant: this is the beside-the-panel case.
   ---------------------------------------------------------------- */
@media (min-width:821px){
  .hero-config--lead{grid-template-columns:minmax(0, min(30rem, calc((100svh - var(--navh, 4.5rem) - var(--s5) - var(--s3)) * 0.8))) clamp(18rem,44%,34rem)}
  .hero-config--lead .shot .field,
  .hero-config--lead .shot .field:has(img){aspect-ratio:4/5;max-width:30rem}
}

/* A tick beside a field: the 'not sure yet' beside the date. */
.tick{display:flex;gap:0.6rem;align-items:flex-start;font-size:var(--t-small);line-height:1.5;cursor:pointer}
.tick input{margin:0.22rem 0 0;flex:none;accent-color:#000}
.tick--tight{margin:-0.75rem 0 var(--s3)}

/* The rest of the inquiry, opened in place under the first three
   fields. Collapsed by script rather than by a hidden attribute, so
   the form is whole and submittable with JavaScript off. */
.more{margin-top:var(--s5);border-top:1px solid var(--rule);padding-top:var(--s5)}
.more.is-collapsed{display:none}
.more .cfg-label:first-child{margin-top:0}

/* Two doors, one picture. As consecutive sections they were the same
   shape doing the same job, which read as the page repeating itself. */
.doors{display:grid;grid-template-columns:minmax(0,20rem) minmax(0,1fr);gap:var(--s5) var(--s-band);
  align-items:center}
.doors-art{width:100%}
.doors-art .art{display:block;width:100%;height:auto}
.doors-list{display:grid;gap:var(--s5)}
.doors-list section + section{border-top:1px solid var(--rule);padding-top:var(--s5)}
.doors-list .quiet{max-width:34rem}
@media (max-width:760px){
  .doors{grid-template-columns:1fr;gap:var(--s5)}
  .doors-art{max-width:22rem;margin-inline:auto}
}

/* ---- One delivery, or standing ----------------------------------
   Two columns, both stated honestly. The one-off keeps a real
   advantage — any date you like — so it is not written as the losing
   column, which is what makes the comparison believable.
   ---------------------------------------------------------------- */
/* ---- Subscribe or once, on the product page ---------------------
   Cards rather than a segmented control: the standing option has to
   carry a price comparison, a cadence and three lines of reassurance,
   and none of that fits in a tab. Selected state is a solid rule on
   the left edge plus a black border, never a fill, so the panel keeps
   one ink.
   ---------------------------------------------------------------- */
.cfg-plans{margin-top:0}
/* The offer, not a third form field. The standing card carries an
   ink border from the start and the badge is filled, so the weight on
   the page matches the weight of the decision. */
.pcards{display:grid;gap:0.55rem}
.pcard{display:block;border:1px solid var(--ink-20);cursor:pointer;position:relative;
  padding:0.85rem 0.95rem 0.85rem 0.9rem;transition:border-color .14s linear}
.pcard:hover{border-color:var(--ink-45)}
.pcard.on{border-color:var(--ink);box-shadow:inset 3px 0 0 var(--ink)}
/* Named so it cannot collide: '.lead' is already a content class on
   the hero paragraph, and inside .hero-config it was landing on this
   card too — capping its width and graying its text. */
.pcard--main{border-color:var(--ink-45)}
.pcard--main.on{border-width:2px;padding:calc(0.85rem - 1px) calc(0.95rem - 1px) calc(0.85rem - 1px) calc(0.9rem - 1px)}
.pcard:has(input:focus-visible){outline:2px solid var(--ink);outline-offset:2px}
.pcard-top{display:flex;align-items:flex-start;gap:0.7rem}
.pcard input{margin:0.2rem 0 0;flex:none;accent-color:#000}
.pcard-t{flex:1;font-weight:600;display:flex;flex-wrap:wrap;align-items:baseline;gap:0.35rem 0.5rem;line-height:1.35}
.pcard-save{font-family:var(--sans);font-size:var(--t-fine);font-weight:600;letter-spacing:0.02em;
  background:var(--ink);color:var(--paper);padding:0.14rem 0.46rem;white-space:nowrap}
.pcard-p{font-weight:600;white-space:nowrap;line-height:1.35}
.pcard-p s{color:var(--ink-45);font-weight:400;margin-right:0.4rem}
.sum .was{color:var(--ink-45);text-decoration:line-through;margin-right:0.35rem;font-weight:400}
/* The body belongs to the chosen card only: an unchosen card showing
   its own cadence select invites a click that changes nothing. */
/* The subscription case stays visible whether or not the card is
   selected. An argument that collapses the moment you look at the
   other option is an argument nobody finishes reading. */
.pcard-body{display:block;padding:0.8rem 0 0.15rem 1.6rem}
/* Its controls, though, are only live on the selected card. */
.pcard:not(.on) .freq,.pcard:not(.on) .pcard-day{opacity:.45;pointer-events:none}
/* Frequency as three short buttons, weekday as a select beside the
   word 'on', and the sentence they make written once underneath. Two
   selects that each contained the day name said it three times. */
/* Three equal columns and a select of exactly the same width beneath
   it, so the two controls share a left and a right edge instead of
   the day sitting wherever its own text ended. */
.freq{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--ink-20);
  width:100%;max-width:24rem}
/* Label over rate, so the ladder is legible before anything is
   clicked. */
.freq-o b{display:block;font-weight:600}
.freq-o span{display:block;font-size:var(--t-fine);opacity:.62;margin-top:0.05rem}
.freq-o{position:relative;font-size:var(--t-small);padding:0.45rem 0.4rem;cursor:pointer;text-align:center;
  border-right:1px solid var(--ink-20);white-space:nowrap;transition:background .12s linear,color .12s linear}
.freq-o:last-child{border-right:0}
.freq-o input{position:absolute;opacity:0;width:1px;height:1px}
.freq-o:hover{background:var(--field)}
.freq-o.on{background:var(--ink);color:var(--paper);font-weight:600}
.freq-o:has(input:focus-visible){outline:2px solid var(--ink);outline-offset:2px}
/* display:block — a span ignores width and max-width, which is why
   the day select ran wider than the control above it. */
.pcard-day{display:block;margin-top:0.4rem;width:100%;max-width:24rem}
.pcard-day select{width:100%}
.pcard-n{font-size:var(--t-fine);color:var(--ink-45);font-weight:400}
/* Two tiers. The three reasons to subscribe are headings with a line
   of explanation and a rule between them; the administration runs as
   one quiet paragraph underneath. Five identical gray bullets ranked
   nothing, so nothing in them was read. */
.pbens{display:block;margin-top:0.9rem;border-top:1px solid var(--rule)}
.pben{display:block;padding:0.5rem 0 0.5rem 1.15rem;border-bottom:1px solid var(--rule);
  position:relative;font-size:var(--t-small);color:var(--ink-70);line-height:1.5}
.pben b{font-weight:600;color:var(--ink)}
.pben::before{content:'';position:absolute;left:0;top:0.72em;width:0.46rem;height:0.24rem;
  border-left:1.5px solid var(--ink);border-bottom:1.5px solid var(--ink);transform:rotate(-45deg)}

/* ---- The same decision, restated on the order page --------------
   One line, because by here it is a fact rather than a question.
   ---------------------------------------------------------------- */
.planrow{display:flex;flex-wrap:wrap;align-items:center;gap:0.6rem 0.9rem;
  border:1px solid var(--ink-20);padding:0.7rem 0.85rem;max-width:38rem}
.planrow-m{flex:1 1 12rem;min-width:0;display:flex;flex-direction:column;gap:0.1rem}
.planrow-m b{font-weight:600}
.planrow-n{font-size:var(--t-fine);color:var(--ink-45)}
.planrow-c{display:flex;gap:0.45rem;flex-wrap:wrap}
.planrow-c select{max-width:13rem;min-width:0}
.planrow-b{font:inherit;font-size:var(--t-small);background:none;border:0;padding:0;cursor:pointer;
  color:var(--ink-45);text-decoration:underline;text-underline-offset:3px}
.planrow-b:hover{color:var(--ink)}
.planrow-b.on{color:var(--ink);font-weight:600}
@media (max-width:520px){.planrow-c{width:100%}.planrow-c select{max-width:none;flex:1 1 100%}}

/* The scarcity strip. Never a discount, never a countdown we
   invented: only whether today is still available.

   A gray hairline under it left the one live fact on the page reading
   as chrome. The rule is the same black line the picture and the
   selected controls carry, so the strip belongs to the page rather
   than floating above it. The square marker that used to sit beside
   the text is gone: it carried no information the sentence did not
   already carry, and in the closed state it was a gray box. */
.strip{border-bottom:0;background:var(--sand);font-size:var(--t-small);text-align:center;padding:0.6rem 0}
.strip .avail{border:0;padding:0}
.strip .avail.closed{color:var(--ink)}

/* ==================================================================
   VESSEL — the rules of the language, applied over the components
   above. Everything here is a consequence of five decisions:

   1. Color is ground, not accent. Two warm grounds alternate at full
      width, chalk and blush, with sand reserved for the strip. Green
      is ink and hairline. Clay appears on prices and nowhere else.
      Nothing on the site is dark.
   2. Three faces, three jobs. Cormorant Garamond italic is the
      wordmark alone. Libre Caslon Text is what is looked at: headings,
      product and route names, captions. The grotesque is everything
      that is read, including prices, labels, forms and buttons.
   3. The arch belongs to the photograph a page leads with, cropped
      3:4 and capped at 24rem. Every other image is a rectangle with a
      hairline. Buttons and fields stay square.
   4. No capitals, no padded numerals, no small label above a heading,
      no colored word inside a headline.
   5. No shadows and no vignettes. Depth comes from the two grounds.
   ================================================================== */

/* 2 — the wordmark is the only Cormorant on the site */
.wordmark{font-family:var(--mark)}

/* 2 — what is looked at, in Caslon */
h2.head{font-family:var(--serif);font-weight:400;letter-spacing:0}
h2.head{font-size:1.35rem;line-height:1.2}
.door-n{font-family:var(--serif)}

/* 2 — captions, in Caslon italic. The only italic on the site apart
   from the wordmark. */
.field-note,figcaption{font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:0.9375rem;color:var(--ink-70);letter-spacing:0}

/* 1 — prices are ink, not clay. A price set in a warm red reads as a
   sale to anybody who has shopped online, and these are not
   discounted: they are what the thing costs. The weight a price needs
   comes from its size, which the display figures already have. Clay
   keeps the one home where it is decorative rather than
   transactional, the third numbered disc. */
.door-fig,.cfg-price{color:var(--ink)}
.door-fig{font-family:var(--serif)}
.from{color:var(--ink-45)}

/* 3 — the arch, on the fold photograph only, and capped so a 3:4 crop
   cannot outgrow the window. The pair of rules above it set 1:1 for a
   photograph and 4:5 for a drawing; both are replaced here. */
.hero-config .shot .field,
.hero-config .shot .field:has(img),
.hero-config--lead .shot .field,
.hero-config--lead .shot .field:has(img){
  aspect-ratio:3/4;max-width:24rem;
  border-radius:999px 999px 0 0;
  border-color:var(--hair);
}

/* The picture track is a fixed 24rem, the panel takes the rest, and
   both sit inside the container margins, so the seam between picture
   and text falls in the same place as it does in every section below.
   The rule this replaces sized the picture column from the window
   height, which left the panel narrow and a hole between the two. */
.hero-config{
  grid-template-columns:24rem minmax(0,1fr);
  gap:0 clamp(2rem,4vw,3.25rem);
  justify-content:start;
  max-width:1120px;
  margin-inline:auto;
  padding:var(--s3) var(--edge) var(--s-band);
}
.hero-config .panel-cfg{padding:var(--s3) 0 0}
@media (max-width:820px){
  .hero-config{grid-template-columns:1fr;max-width:none;margin-inline:0;
    gap:var(--s5) 0}
  .hero-config .panel-cfg{padding:0 var(--edge)}
}

/* 3 — every other image: rectangle, hairline, no vignette */
.field{border-color:var(--hair)}
.field::after{display:none}

/* 5 — hairlines, not black rules. The route list keeps a stronger top
   edge because it is the one list a reader has to find. */
.panel,.faq,.cta-band,.avail{border-color:var(--hair)}
.doorlist{border-top:1px solid var(--stem,#5B6357)}

/* 1 — the two grounds. Both are full-bleed elements already, so the
   ground runs edge to edge without a wrapper. */
.foot{background:var(--blush);border-top:0;margin-top:var(--s-band);
  padding-block:var(--s7) var(--s5)}
.foot h3{font-family:var(--serif);font-style:italic;font-weight:400;font-size:1.0625rem;
  color:var(--ink-70)}
.foot .signup{border-bottom-color:var(--rule)}
.foot input[type=email]{background:var(--paper);border-color:var(--ink-20)}

/* 2 — the button is the grotesque, and it must refuse to be squeezed
   by the links beside it in the nav row. */
.btn{font-family:var(--sans);white-space:nowrap;flex:0 0 auto}

/* One column: the arch keeps its crop and its cap, centered. */
@media (max-width:820px){
  .hero-config .shot .field,
  .hero-config .shot .field:has(img),
  .hero-config--lead .shot .field,
  .hero-config--lead .shot .field:has(img){
    aspect-ratio:3/4;max-width:22rem;margin-inline:auto;max-height:none;
  }
}


/* ==================================================================
   VESSEL · GROUNDS AND THE CLOSER
   ------------------------------------------------------------------
   1 said color is ground. A page of chalk with hairlines between the
   sections is the language half-applied: the grounds have to alternate
   or the blush reads as one flat slab wherever it lands. Two grounds
   take turns down every page, and a section that carries a ground does
   not also carry a rule — the change of ground IS the boundary.

   Sand is the second alternate rather than a third color: it is the
   strip's ground, and reusing it once per page on the quietest section
   keeps the rhythm from being two-note.
   ================================================================== */
.ground,.ground-sand{
  /* The sections sit inside the container, so the ground is painted
     past the margins and clipped to the section box. */
  box-shadow:0 0 0 100vmax var(--blush);
  clip-path:inset(0 -100vmax);
  background:var(--blush);
}
.ground-sand{box-shadow:0 0 0 100vmax var(--sand);background:var(--sand)}
.ground.rule-top::before,.ground-sand.rule-top::before{display:none}

/* The arch, on a photograph of the work that is not in the fold. */
.field.r-arch{aspect-ratio:3/4;border-radius:999px 999px 0 0}

/* The closer: the routes on the left, the piece on the right, on the
   same 24rem track the fold uses, mirrored. Replaces the two side by
   side cards, which showed the same choice twice as tiles and gave the
   reader two prices to compare in two different places. */
.closer{display:grid;gap:var(--s5);grid-template-columns:minmax(0,1fr)}
@media (min-width:821px){
  .closer{grid-template-columns:minmax(0,1fr) 24rem;gap:clamp(2rem,4vw,3.25rem);
    align-items:start}
}
.closer figure{width:100%;max-width:24rem;margin-inline:auto}
@media (max-width:820px){.closer figure{order:-1;max-width:22rem}}
/* Narrow column, so the price sits above the description rather than
   beside a name it would print over. */
.closer .door{grid-template-columns:minmax(0,1fr) auto;gap:0.4rem var(--s3);padding:var(--s3) 0}
.closer .door-n{grid-column:1;grid-row:1;font-size:1.35rem}
.closer .door-m{grid-column:1/-1;grid-row:2;max-width:none}
.closer .door-p{grid-column:2;grid-row:1;align-self:baseline}
.closer .door-fig{font-size:1.25rem}

/* Where a ground ends, the next section's rule is a second boundary
   drawn on top of the first. The change of ground is the boundary. */
.ground + .rule-top::before,.ground-sand + .rule-top::before{display:none}

/* ==================================================================
   VESSEL · PROPORTION
   ------------------------------------------------------------------
   The picture track was a fixed 24rem against a fluid text track, so
   the ratio between them changed with the window: at the width the
   design was judged at they were near enough even, and by 1280 the
   picture had become a third of the row while the text ran to a
   column and a half. A share, not a measurement — the two columns now
   hold the same proportion at every width, with a ceiling so a 3:4
   crop can still never outgrow the window.
   ================================================================== */
@media (min-width:821px){
  .hero-config{grid-template-columns:clamp(16rem,42%,26rem) minmax(0,1fr)}
  .hero-config .shot .field,
  .hero-config .shot .field:has(img),
  .hero-config--lead .shot .field,
  .hero-config--lead .shot .field:has(img){max-width:none}
  .closer{grid-template-columns:minmax(0,1fr) clamp(16rem,42%,26rem);align-items:center}
  .closer figure{max-width:none}
}

/* One line, hard against the right edge of the list, on the same
   baseline as the name. Wrapped over two lines it read as a broken
   column rather than a price. */
/* Root cause of the stacked price: the base rule sets the qualifier
   to display:block, which puts "From" on its own line above the
   number in every door. Inline, as it already is on the order page,
   so a price is one line wherever it appears. */
.door-fig{white-space:nowrap}
.door-fig .from{display:inline;font-size:var(--t-small);margin:0 0.3rem 0 0}

/* A chevron, not a full arrow. The arrow was a glyph borrowed from a
   different vocabulary: it means go, and a question that opens in
   place does not go anywhere. Drawn as a rotating hairline so it
   matches the rules around it and turns rather than swapping. */
.faq summary::after{
  content:'';
  width:0.5rem;height:0.5rem;
  border-right:1px solid currentColor;
  border-bottom:1px solid currentColor;
  transform:rotate(45deg) translate(-0.1rem,-0.1rem);
  transform-origin:center;
  color:var(--ink-45);
  flex:0 0 auto;align-self:center;
  transition:transform .18s ease,color .14s linear;
}
.faq summary:hover::after{color:var(--ink)}
.faq details[open] summary::after{
  content:'';
  transform:rotate(225deg) translate(-0.1rem,-0.1rem);
}

/* The closing block on Arrangements does the same job the closer does
   on the homepage: it holds the two routes out of the page. Same job,
   same shape. That makes two arches on the page, the fold and the
   foot, which is the ceiling and reads as a bracket rather than a
   pattern. */
.doors-art .field{aspect-ratio:3/4;border-radius:999px 999px 0 0}

/* The footer heads go back upright. Caslon italic is the caption
   voice: under a photograph it reads as a note on the picture, and
   over a column of addresses and links it just reads as decoration.
   Small, semibold, in the grotesque, the way a label is set
   everywhere else on the site. */
.foot h3{font-family:var(--sans);font-style:normal;font-weight:600;
  font-size:var(--t-small);color:var(--ink);letter-spacing:0}

/* The fold picture was pinned, so the text slid up past a stationary
   photograph and the two read as separate pages sharing a scroll. On
   the four pages whose fold is a picture beside an argument, they
   move together.

   The exception is Arrangements, where the panel is a configurator
   and the picture repaints as she changes the size and the palette:
   there the pin is doing a job, keeping the piece in view while she
   chooses it. Everywhere else it was only a habit. */
.hero-config--lead .shot .field{position:relative;top:auto}

/* Special orders reads like the order page rather than like a page
   with a picture beside an argument: the panel is a form and it is
   taller than the photograph. So the photograph stays put while the
   form scrolls, exactly as it does on Arrangements. The two pages
   with a form in the fold behave the same way; the three with an
   argument in it scroll as one. */
body[data-page="special-orders"] .hero-config--lead .shot .field,
body[data-page="events"] .hero-config--lead .shot .field{
  position:sticky;top:calc(var(--navh, 4.5rem) + var(--s3));
}

/* One column inside the panel too: at this width 'Weddings' is wider
   than the track left beside the figure. */
@media (max-width:400px){
  .panel-cfg .door,.closer .door{grid-template-columns:1fr;gap:0.5rem}
  .panel-cfg .door-p,.closer .door-p{grid-column:1;grid-row:3;text-align:left}
}

/* On a phone a primary action takes the column. At its label width it
   sat as a small block against the left margin, which reads as an
   afterthought beside full-width fields. Two exceptions, both in rows
   that have to stay on one line: the order bar's button, which sits
   beside the total, and the steppers, which are not .btn. */
@media (max-width:560px){
  .btn{display:block;width:100%}
  .cfg-act .btn,.acc-act .btn,.cta-band .btn,.signup-row .btn,.zip-row .btn{width:100%}
  .nav-panel .nav-cta{width:100%;justify-content:center}
  .bar .btn{display:inline-block;width:auto}
}

/* Four promises, one line each. They are complete statements, so a
   sentence of explanation under any of them could only say it twice.
   Set in Caslon like the how-it-works points: this is something to be
   looked at and remembered, not read past. */
/* No rule across the top: the row rules are the structure, and a black
   line above them read as a table header for a list that has none. */
.promises{list-style:none;margin:0;padding:0;max-width:40rem}
.promises li{border-bottom:1px solid var(--rule);padding:0.9rem 0;
  font-family:var(--serif);font-size:1.15rem;line-height:1.35}
/* One promise is true whenever the timeline allows it, and saying so in
   the line would cost the line its force. The asterisk holds the
   qualifier underneath, where it belongs. */
.promises sup{font-family:var(--sans);font-size:0.6em;font-weight:600;color:var(--ink-45);
  vertical-align:super;line-height:0;margin-left:0.15em}
.promises-note{margin:var(--s3) 0 0;max-width:40rem}

/* A line that belongs to the field above it rather than to the step:
   pulled up under the textarea, and it keeps the field's measure. */
.f-aside{margin:-0.9rem 0 var(--s3);max-width:34rem}

/* The note under the fold photograph belongs to the picture, so on the
   product page, where the picture is pinned while she chooses, it is
   pinned with it. */
.shot-note{margin:0.6rem 0 0;max-width:24rem}
@media (min-width:821px){
  body[data-page="arrangements"] .hero-config .shot .field{position:relative;top:auto}
  body[data-page="arrangements"] .hero-config .shot .shot-pin{position:sticky;
    top:calc(var(--navh, 4.5rem) + var(--s3))}
}

/* While a field has focus the keyboard owns the bottom of the screen,
   so the bar that lives there stands down: it cannot be pressed
   through a keyboard, and left in place it sits over the field being
   filled in. The class is set on focus by the script. */
body[data-page="order"].typing .bar{display:none}
