/* ==========================================================================
   The Posy Poise Studio — design system v2
   Tokens → primitives → layout → components → pages
   ========================================================================== */

/* --- 1. Tokens -------------------------------------------------------------
   Every colour and every type size on this site comes from this block. If a
   value is written anywhere else, that is a bug — it is how a system drifts
   until two greys are almost the same grey and nobody knows which is correct.

   The full map, with what each one is for, is in DESIGN-SYSTEM.md.
   --------------------------------------------------------------------------- */
:root {

  /* --- colour ---------------------------------------------------------------
     Cream and olive, sampled from the thank-you card illustration.
     Contrast figures are against --paper unless stated; anything used for body
     text clears 4.5:1, anything used for large text clears 3:1.
     ------------------------------------------------------------------------ */
  --paper:  #F6F0E3;  /* page ground                                        */
  --card:   #FCFAF4;  /* raised surface — a shade lighter than the page     */
  --field:  #FFFFFF;  /* form inputs only. See the note below.              */
  --dusk:   #E7DFCC;  /* second surface — chips, fills, hover               */
  --forest: #2F3527;  /* dark band + footer ground                          */
  --ink:    #2A2A22;  /* body text            — 13.9:1                      */
  --accent: #4F5A38;  /* buttons, links, prices, focus  — 6.5:1             */
  --stem:   #6F7D62;  /* utility marks only, never decorative               */
  --muted:  #6E6B5C;  /* captions and meta    — 5.2:1                       */
  --warn:   #B5644A;  /* needs a decision, not an error                     */
  --late:   #A33B2E;  /* overdue, full, destructive                         */
  --line:   rgba(42, 42, 34, .14);   /* hairline on light                   */
  --line-lt:rgba(246, 240, 227, .22);/* hairline on --forest                */

  /* Inputs are white, not cream. On a cream page a cream input reads as
     disabled — the eye takes "same colour as the background" to mean "not
     yours to type in". White is the only surface here that says the opposite. */

  /* --- type: the scale ------------------------------------------------------
     Twelve steps, nothing between them. A size that is not on this list does
     not go on the page.
     ------------------------------------------------------------------------ */
  --s-10: 0.625rem;   --s-12: 0.75rem;    --s-14: 0.875rem;
  --s-16: 1rem;       --s-18: 1.125rem;   --s-20: 1.25rem;
  --s-24: 1.5rem;     --s-32: 2rem;       --s-40: 2.5rem;
  --s-48: 3rem;       --s-64: 4rem;       --s-72: 4.5rem;

  /* --- type: the roles ------------------------------------------------------
     Always reach for a role, not a step. The role says what the text IS, so
     changing every caption on the site is one line here rather than a search
     for 0.75rem. Headings interpolate between two steps on the scale, so they
     shrink on a phone without ever landing off it.
     ------------------------------------------------------------------------ */
  --t-micro:   var(--s-10);  /* eyebrows, table headers, badges, legends     */
  --t-caption: var(--s-12);  /* helper text, hints, footnotes, meta          */
  --t-small:   var(--s-14);  /* buttons, nav, dense UI, secondary body       */
  --t-body:    var(--s-16);  /* default reading size                         */
  --t-lead:    var(--s-18);  /* opening paragraph of a section               */
  --t-h4:      var(--s-20);  /* smallest heading                             */
  --t-h3:      clamp(var(--s-20), 2.4vw, var(--s-24));
  --t-h2:      clamp(var(--s-24), 4vw,   var(--s-32));
  --t-h1:      clamp(var(--s-32), 6vw,   var(--s-48));
  --t-hero:    clamp(var(--s-40), 9vw,   var(--s-72));

  /* Older aliases, kept so the whole stylesheet did not have to be rewritten
     in one go. They now resolve to the scale above, so nothing escapes it. */
  --t-label: var(--t-micro);
  --t-1: var(--t-h1);
  --t-2: var(--t-h2);
  --t-3: var(--t-lead);

  --f-display: "Fraunces", Georgia, serif;
  --f-body:    "Hanken Grotesk", system-ui, -apple-system, sans-serif;
  --f-slip:    "Courier Prime", ui-monospace, "Courier New", monospace;

  /* space */
  --gutter:  clamp(1.25rem, 4vw, 3rem);
  --section: clamp(4.5rem, 11vw, 9rem);
  --maxw:    1320px;
  --arch:    50vw 50vw 6px 6px;

  --ease: cubic-bezier(.2, .7, .3, 1);
}

/* --- 2. Reset & primitives ---------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: var(--t-body);
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .22em; }

button, input, select, textarea { font: inherit; color: inherit; }
/* A placeholder is a hint, so it takes the hint size — 12px, the same step as
   every other piece of helper text. It was inheriting the input's 16px, which
   made a prompt look like content already typed in.

   Only the placeholder shrinks. The input keeps font-size 16px, and that is
   deliberate: iOS Safari zooms the whole page in when you focus a field set
   below 16px, and nobody ever wants that. Shrinking ::placeholder alone gets
   the quiet hint without triggering it. */
::placeholder {
  color: color-mix(in srgb, var(--muted) 70%, transparent);
  font-size: var(--t-caption);
  opacity: 1;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--paper); padding: .75rem 1.25rem;
}
.skip:focus { left: 0; }

.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* type primitives */
.display {
  font-family: var(--f-display);
  font-weight: 300;
  font-variation-settings: "SOFT" 40, "WONK" 1, "opsz" 100;
  line-height: .95;
  letter-spacing: -.03em;
}
.label {
  font-family: var(--f-slip);
  font-size: var(--t-label);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.lead { font-size: var(--t-3); line-height: 1.55; max-width: 46ch; }
em { font-style: italic; }

/* --- 3. Layout ----------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(3rem, 7vw, 5.5rem); }

.grid { display: grid; gap: var(--gutter); }
@media (min-width: 800px) {
  .grid--split { grid-template-columns: 5fr 7fr; align-items: end; }
  .grid--split-r { grid-template-columns: 7fr 5fr; align-items: center; }
}

/* --- 4. Header ----------------------------------------------------------- */
.head {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.head__row {
  display: flex; align-items: center; gap: 1rem;
  padding-block: .85rem;
}
.head__nav { display: flex; gap: 1.5rem; flex: 1; }
.head__nav a {
  font-size: var(--t-small); text-decoration: none; padding-block: .25rem;
  border-bottom: 1px solid transparent;
}
.head__nav a:hover, .head__nav a[aria-current="page"] { border-bottom-color: var(--accent); }
.head__mark { flex: 0 0 auto; }
/* wordmark is 660x68 (9.7:1) — lock the ratio so it can never squash */
.head__mark img { height: clamp(15px, 3.6vw, 26px); width: auto; aspect-ratio: 660/68; }
.head__utils { display: flex; gap: .5rem; flex: 1; justify-content: flex-end; align-items: center; }

.chip {
  font-family: var(--f-slip); font-size: var(--t-label); letter-spacing: .12em;
  text-transform: uppercase; background: var(--dusk); color: var(--ink);
  border: 0; border-radius: 999px; padding: .5rem .85rem; cursor: pointer;
  display: inline-flex; align-items: center; gap: .4rem;
}
.chip:hover { background: color-mix(in srgb, var(--dusk) 70%, var(--accent) 12%); }

/* Language switch: a link, styled as a chip. Both codes show; the current one
   is solid, the other is the tap target's hint. */
.chip--lang { text-decoration: none; gap: .3rem; }
.chip--lang span { opacity: .45; }
.chip--lang span.is-on { opacity: 1; font-weight: 700; }
/* Three chips plus the wordmark have to share one row on a phone. */
@media (max-width: 520px) {
  .head__utils { gap: .3rem; }
  .head__utils .chip { padding: .45rem .55rem; letter-spacing: .05em; }
  .chip--lang { gap: .12rem; }
}
.chip--cart { background: var(--accent); color: var(--paper); }
.chip--cart:hover { background: color-mix(in srgb, var(--accent) 85%, black); }
/* Something in the order list: the count circle turns red, the pill stays
   green. At zero the circle is cream, as before. */
.chip--cart.has-items .chip__count { background: var(--late); color: var(--paper); }
.chip--cart svg { flex: 0 0 auto; }

/* The badge pulses when something lands in it. Without this the count changes
   silently and the eye, still on the product it just clicked, never sees it. */
@keyframes cartbump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.45); }
  100% { transform: scale(1); }
}
.chip__count[data-bump] { animation: cartbump .42s var(--ease); }

/* The flying thumbnail. Fixed so it is positioned against the viewport rather
   than a scrolled parent, and pointer-events:none so it can never swallow a
   click on the way past. */
.fly {
  position: fixed; z-index: 300; pointer-events: none;
  border-radius: 6px; object-fit: cover;
  box-shadow: 0 6px 20px rgba(42, 42, 34, .28);
  will-change: transform, opacity;
}

@media (max-width: 520px) {
  .chip--cart span:not(.chip__count) { display: none; }
}
.chip__count {
  background: var(--paper); color: var(--accent); border-radius: 999px;
  min-width: 1.35em; text-align: center; font-size: var(--t-micro); padding: .1em .35em;
}

@media (max-width: 640px) {
  .head__row { flex-wrap: wrap; row-gap: .6rem; }
  .head__nav { order: 3; flex: 1 0 100%; justify-content: center; gap: 1.75rem;
               border-top: 1px solid var(--line); padding-top: .6rem; }
}

/* --- 5. Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: .6rem;
  border: 1px solid transparent; border-radius: 999px;
  padding: .85rem 1.7rem; font-size: var(--t-small); font-weight: 500;
  cursor: pointer; text-decoration: none; transition: transform .25s var(--ease), background .25s;
}
.btn:hover { transform: translateY(-2px); }
.btn:disabled,
.btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; transform: none; pointer-events: none; }
.btn--primary { background: var(--accent); color: var(--paper); }
.btn--primary:hover { background: color-mix(in srgb, var(--accent) 85%, black); }
.btn--ghost { border-color: var(--ink); background: transparent; }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }
.btn--wide { width: 100%; justify-content: center; }
.on-dark .btn--ghost { border-color: var(--line-lt); color: var(--paper); }
.on-dark .btn--ghost:hover { background: var(--paper); color: var(--ink); }

/* --- 6. Hero ------------------------------------------------------------- */
.hero { padding-top: clamp(3rem, 8vw, 6rem); padding-bottom: var(--section); }
.hero__eyebrow { margin-bottom: 1.75rem; }
.hero__title { font-size: var(--t-hero); max-width: 14ch; }
.hero__title i { font-style: italic; font-variation-settings: "SOFT" 60, "WONK" 1; color: var(--accent); }

/* Emphasis inside a heading used to carry an inline style on every page. Now
   that headings are rendered from the database the <i> arrives bare, so the
   colour belongs here — one rule instead of a style attribute repeated by hand
   and forgotten on the next page. */
h1.display i, h2.display i { color: var(--accent); font-style: italic; }
/* …except on the dark bands, where olive on olive would vanish. */
.on-dark .display i { color: inherit; }
.hero__body { margin-top: 2rem; display: grid; gap: 1.5rem; }
@media (min-width: 900px) {
  .hero__body { grid-template-columns: 1fr 1fr; align-items: start; gap: var(--gutter); }
}
/* Homepage hero: lead and buttons on the left, the three specs on the right,
   with the last spec line level with the buttons. On a wide screen the whole
   block sits in the middle of the first screen instead of hugging the top. */
.hero--home .hero__body { grid-template-areas: "lead" "specs" "cta"; }
.hero--home .lead { grid-area: lead; }
.hero--home .hero__specs { grid-area: specs; }
.hero--home .hero__cta { grid-area: cta; display: flex; gap: .75rem; flex-wrap: wrap; margin-top: .75rem; }
@media (min-width: 900px) {
  .hero--home {
    min-height: calc(100svh - var(--head-h, 72px));
    display: flex; flex-direction: column; justify-content: center;
    padding-block: clamp(2.5rem, 5vw, 4rem);
  }
  .hero--home .hero__body { grid-template-areas: "lead specs" "cta specs"; grid-template-rows: auto 1fr; }
  .hero--home .hero__specs { align-self: end; }
  .hero--home .hero__cta { align-self: end; margin-top: 1.5rem; }
}

/* studio page: header text beside the line drawing */
.hero__head { display: grid; gap: var(--gutter); align-items: center; }
@media (min-width: 900px) { .hero__head { grid-template-columns: 1fr 1fr; } }
.hero__sketch { width: 100%; height: auto; }
.hero__figs--single { grid-template-columns: 1fr !important; max-width: 460px; }

/* The orchid is a layered flourish, not a column: it sits behind the headline
   with a petal crossing the last word, and takes no space in the flow — so the
   spec list stays level with the lead and the buttons stay close underneath. */
.hero { position: relative; }
.hero > *:not(.hero__orchid) { position: relative; z-index: 1; }
.hero__orchid {
  position: absolute; z-index: 0; pointer-events: none; user-select: none;
  /* Sized by HEIGHT, not width: the cap is what keeps the bottom of the stem
     clear of the spec list. Nudge `height` to resize, `right` to shift. */
  /* right: var(--gutter) lands on the content edge, not the border edge —
     the same line the spec table ends on, so the gutter stays clear. */
  top: 0; right: var(--gutter);
  height: clamp(240px, 28vw, 420px); width: auto;
}
@media (max-width: 899px) {
  /* no room to overlap on a phone — drop it back into the flow, right-aligned */
  .hero__orchid { position: static; width: 60%; height: auto; margin: 1.25rem 0 -1rem auto; }
}

.hero__figs {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  display: grid; gap: var(--gutter);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 900px) { .hero__figs { grid-template-columns: 1.2fr .8fr 1fr; align-items: end; } }
.fig { position: relative; }
.fig img { width: 100%; object-fit: cover; border-radius: 6px; }
.fig--arch img { border-radius: var(--arch); aspect-ratio: 3/4.4; }
.fig--tall img { aspect-ratio: 3/4; }
.fig--wide img { aspect-ratio: 4/3; }
.fig figcaption { margin-top: .7rem; }
.fig--hide-sm { display: none; }
@media (min-width: 900px) { .fig--hide-sm { display: block; } }

/* --- 7. Collections ------------------------------------------------------ */
.coll { border-top: 1px solid var(--line); padding-block: clamp(3rem, 7vw, 5rem); }
.coll__head { display: grid; gap: 1rem; margin-bottom: 2.25rem; }
@media (min-width: 800px) {
  .coll__head { grid-template-columns: 3fr 5fr 2fr; align-items: baseline; }
}
.coll__title { font-size: var(--t-2); }
.coll__note { color: var(--muted); max-width: 42ch; }
.coll__strip {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(200px, 1fr);
  gap: var(--gutter); overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: .75rem; scrollbar-width: thin;
}
.coll__strip > * { scroll-snap-align: start; }
.coll__strip img { width: 100%; aspect-ratio: 4/5; object-fit: cover; border-radius: 6px; }

/* --- 8. Velvet band ------------------------------------------------------ */
.on-dark { background: var(--forest); color: var(--paper); }

/* Courier Prime on deep olive.
   These small caps were set at 62% paper, which measures as acceptable
   contrast and still reads badly — Courier Prime is a typewriter face with
   hairline strokes, and at label size those strokes are barely a pixel wide.
   Thinning them with transparency on top of that leaves the word technically
   present and practically invisible. Raising the opacity AND the weight fixes
   it; the wide letter-spacing keeps the bold from looking heavy.
   Same treatment wherever this face sits on the olive. */
.on-dark .label {
  color: color-mix(in srgb, var(--paper) 88%, transparent);
  font-weight: 700;
}
.on-dark a { color: var(--paper); }
.band__quote { font-size: var(--t-1); max-width: 20ch; }
.band__quote i { font-style: italic; color: var(--dusk); }

/* --- 9. Product grid ----------------------------------------------------- */
/* category pills double as section navigation — they park under the header */
.filters {
  position: sticky;
  top: var(--head-h, 56px);
  scroll-margin-top: var(--head-h, 56px);
  z-index: 40;
  display: flex; flex-wrap: nowrap; gap: .5rem;
  margin-bottom: 2.5rem;
  padding-block: .9rem;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;               /* seven pills: scroll sideways, never wrap */
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.filters::-webkit-scrollbar { display: none; }
.filter { flex: 0 0 auto; }

/* --- FAQ -----------------------------------------------------------------
   Long-form prose, kept narrow. Answer engines lift whole paragraphs, so each
   answer is written to stand on its own out of context — no "as mentioned
   above", no dangling references.
   ------------------------------------------------------------------------ */
.faq__h {
  font-size: var(--t-2); margin-top: 3.5rem; padding-bottom: .6rem;
  border-bottom: 1px solid var(--line);
}
.faq__h:first-of-type { margin-top: 0; }
.faq__item { margin-top: 2.25rem; max-width: 62ch; }
.faq__item h3 {
  font-family: var(--f-display); font-weight: 400; font-size: var(--t-3);
  letter-spacing: -.01em; margin-bottom: .6rem;
}
.faq__item p { margin-bottom: .9rem; }
.faq__item p:last-child { margin-bottom: 0; }
.faq__item ul { margin: 0 0 .9rem 1.1rem; padding: 0; display: grid; gap: .45rem; }
.faq__item li { padding-left: .2rem; }
.faq__item strong { font-weight: 600; }

.empty {
  grid-column: 1 / -1;
  display: grid; gap: .75rem; justify-items: center; text-align: center;
  max-width: 46ch; margin-inline: auto;
  padding: clamp(2.5rem, 6vw, 4rem) 1.5rem;
  border: 1px dashed var(--line); border-radius: 8px;
  color: var(--muted);
}
.filter {
  background: transparent; border: 1px solid var(--line); border-radius: 999px;
  padding: .5rem 1rem; font-size: var(--t-small); cursor: pointer;
}
.filter[aria-pressed="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.products {
  display: grid; gap: var(--gutter);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.card { display: flex; flex-direction: column; gap: .85rem; }
/* The stamp sits behind every product photo at 60% of the frame. A photo
   covers it completely; a product with no photo, or one that fails to load,
   shows the stamp instead of a broken-image icon. */
.card__media { overflow: hidden; border-radius: 6px; aspect-ratio: 4/5;
               background: var(--dusk) url("../img/empty-stamp.webp") center / 60% no-repeat; }
.card__media img {
  display: block; width: 100%; height: 100%; aspect-ratio: 4/5; object-fit: cover;
  transition: transform .6s var(--ease);
}
.card:hover .card__media img, .card:focus-within .card__media img { transform: scale(1.04); }
.card__name { font-family: var(--f-display); font-weight: 400; font-size: var(--t-h4);
              font-variation-settings: "SOFT" 40, "WONK" 1; line-height: 1.15; }
.card__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.card__price { font-family: var(--f-slip); color: var(--accent); white-space: nowrap; }
.card__price small { color: var(--muted); display: block; font-size: var(--t-micro); letter-spacing: .1em; }
/* Two lines at most (the dashboard caps it at 90 characters too). Spacing
   follows the text, so a short description does not leave a gap. */
.card__desc { font-size: var(--t-small); color: var(--muted);
              display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card__foot { padding-top: .25rem; }

.dot { display: inline-flex; align-items: center; gap: .45rem; font-size: var(--t-label);
       font-family: var(--f-slip); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.dot::before { content: ""; width: 6px; height: 6px; border-radius: 999px; background: var(--stem); }
.dot--local::before { background: var(--accent); }

/* --- 10. Spec rows / FAQ ------------------------------------------------- */
.spec { border-top: 1px solid var(--line); display: flex; justify-content: space-between;
        gap: 1rem; padding: .7rem 0; font-size: var(--t-small); }
.spec dt { font-family: var(--f-slip); font-size: var(--t-label); letter-spacing: .14em;
           text-transform: uppercase; color: var(--muted); }
.spec dd { text-align: right; }

.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; padding: 1.35rem 0; display: flex;
  justify-content: space-between; gap: 1.5rem; align-items: baseline;
  font-family: var(--f-display); font-size: var(--t-body); font-variation-settings: "SOFT" 40, "WONK" 1;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--f-slip); color: var(--accent); flex: 0 0 auto; }
.faq details[open] summary::after { content: "–"; }
.faq p { padding-bottom: 1.35rem; max-width: 62ch; color: var(--muted); }

/* --- 11. Cart drawer ----------------------------------------------------- */
.scrim {
  position: fixed; inset: 0; background: rgba(46, 31, 38, .45); z-index: 90;
  opacity: 0; pointer-events: none; transition: opacity .3s;
}
.scrim[data-open="true"] { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 100%);
  background: var(--paper); z-index: 100; display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .38s var(--ease);
  border-left: 1px solid var(--line);
}
.drawer[data-open="true"] { transform: none; }
.drawer__head { display: flex; justify-content: space-between; align-items: center;
                padding: 1.25rem var(--gutter); border-bottom: 1px solid var(--line); }
.drawer__body { flex: 1; overflow-y: auto; padding: 1.25rem var(--gutter); }
.drawer__foot { border-top: 1px solid var(--line); padding: 1.25rem var(--gutter); display: grid; gap: .85rem; }
.iconbtn { background: none; border: 0; cursor: pointer; font-size: var(--t-h4); line-height: 1; padding: .25rem; }

.line { display: grid; grid-template-columns: 56px 1fr auto; gap: .9rem;
        padding: .9rem 0; border-bottom: 1px solid var(--line); align-items: start; }
.line img { width: 56px; height: 68px; object-fit: cover; border-radius: 4px; }
.line__name { font-size: var(--t-small); font-weight: 500; }
.line__opt { font-size: var(--t-label); font-family: var(--f-slip); color: var(--muted); }
.qty { display: inline-flex; align-items: center; gap: .1rem; margin-top: .4rem; }
.qty button:not(.line__rm) { width: 24px; height: 24px; border: 1px solid var(--line); background: none;
              cursor: pointer; border-radius: 4px; line-height: 1; }
.qty span { min-width: 2ch; text-align: center; font-family: var(--f-slip); font-size: var(--t-small); }
.line__price { font-family: var(--f-slip); font-size: var(--t-small); white-space: nowrap; }
.line__rm { background: none; border: 0; color: var(--muted); font-size: var(--t-label);
            cursor: pointer; text-decoration: underline; padding: 0 0 0 .75rem;
            width: auto; height: auto; white-space: nowrap; line-height: 1.6; }

.empty { text-align: center; color: var(--muted); padding: 3rem 0; }

/* Empty-state illustration: the anthurium stamp. Drawn by CSS so every empty
   list on the site gets it without touching the markup. Decorative only. */
.empty::before {
  content: ""; display: block;
  width: clamp(96px, 22vw, 132px); aspect-ratio: 1;
  margin: 0 auto .25rem;
  background: url("../img/empty-stamp.webp") center / contain no-repeat;
}

/* --- 12. Order page ------------------------------------------------------ */
.order { display: grid; gap: var(--gutter); align-items: start; }
@media (min-width: 950px) { .order { grid-template-columns: 1fr 1fr; } }

.field { display: grid; gap: .4rem; margin-bottom: 1.1rem; }
.field label { font-family: var(--f-slip); font-size: var(--t-label);
               letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
/* White, not cream. A cream input on a cream page reads as disabled — the eye
   takes "same colour as the background" to mean "not yours to type in".
   The border carries the shape now that the fill no longer does. */
.field input, .field textarea, .field select {
  background: var(--field); border: 1px solid var(--line); border-radius: 6px;
  padding: .8rem .9rem; font-size: var(--t-body); width: 100%;
}
.field input:focus, .field textarea:focus { border-color: var(--accent); }
.field textarea { min-height: 92px; resize: vertical; }
.field__hint { font-size: var(--t-caption); color: var(--muted); line-height: 1.5; }
.field__err { font-size: var(--t-caption); color: var(--late); }
.field--bad input, .field--bad textarea { border-color: var(--late); }

/* checkbox row — the generic .field input rules would blow this up to 100% */
.check { display: flex; gap: .75rem; align-items: flex-start; cursor: pointer;
         margin-bottom: 1.1rem; font-size: var(--t-small); }
.check input { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; margin-top: .15rem;
               accent-color: var(--accent); }
.check small { display: block; color: var(--muted); margin-top: .15rem;
               font-size: var(--t-caption); line-height: 1.5; }
@media (min-width: 560px) {
  /* align-items:start — otherwise each .field stretches to the tallest cell
     and its input grows with it, so the two columns stop lining up */
  .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; align-items: start; }
}

.slip {
  background: var(--forest); color: var(--paper); border-radius: 6px;
  padding: 1.5rem; font-family: var(--f-slip); font-size: var(--t-caption); line-height: 1.75;
}
.slip pre { white-space: pre-wrap; word-break: break-word; margin: 0; font: inherit; }
.slip__head { display: flex; justify-content: space-between; align-items: center;
              margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px dashed var(--line-lt); }
.slip__tag { font-size: var(--t-label); letter-spacing: .18em; text-transform: uppercase;
             color: color-mix(in srgb, var(--paper) 60%, transparent); }
.slip__actions { margin-top: 1.5rem; display: grid; gap: .6rem; }

/* Desktop: pin slip + buttons together. The slip scrolls inside the panel if
   the order is long, so the Send button can never be pushed out of view. */
@media (min-width: 950px) {
  .order__side {
    position: sticky;
    top: calc(var(--head-h, 56px) + 1.5rem);
    max-height: calc(100dvh - var(--head-h, 56px) - 3rem);
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto auto;
  }
  .slip { overflow-y: auto; min-height: 0; }
  .slip__actions { margin-top: 1.25rem; }
}

/* Mobile: the form is long, so the send action lives in a fixed bottom bar. */
@media (max-width: 949px) {
  /* --park is set by parkBar() in order.js. While the footer is off screen it
     is 0 and the bar sits on the bottom edge; as the footer scrolls up, --park
     grows to exactly the height of footer that is showing, so the bar rides up
     and comes to rest on top of it. The footer is the last thing on the page
     and should be able to look like it. */
  .slip__actions {
    position: fixed; left: 0; right: 0; bottom: var(--park, 0px); z-index: 55;
    margin: 0; grid-template-columns: 1fr 1fr; gap: .6rem;
    padding: .75rem var(--gutter);
    padding-bottom: calc(.75rem + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--paper) 94%, transparent);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--line);
  }
  .slip__actions .btn { padding-inline: 1rem; }
  .page-order #main { padding-bottom: 7rem; }
}
.slip__copy { background: none; border: 1px solid var(--line-lt); color: var(--paper);
              border-radius: 999px; padding: .55rem 1rem; font-size: var(--t-label);
              letter-spacing: .12em; text-transform: uppercase; cursor: pointer; }
.slip__copy:hover { background: var(--paper); color: var(--forest); }

.alert { border-left: 2px solid var(--accent); background: var(--dusk); padding: .9rem 1rem;
         font-size: var(--t-small); border-radius: 0 6px 6px 0; margin-bottom: 1.5rem; }
.alert[hidden] { display: none; }

/* --- 13. Footer ---------------------------------------------------------- */
.foot { background: var(--forest); color: var(--paper); padding-block: clamp(3.5rem, 8vw, 6rem) 2rem; }
.foot__grid { display: grid; gap: 2.5rem; }
@media (min-width: 800px) { .foot__grid { grid-template-columns: 2fr 1fr 1fr; } }
.foot__mark img { height: clamp(24px, 5vw, 30px); width: auto; aspect-ratio: 660/68; }
.foot__tag { margin-top: 1rem; color: color-mix(in srgb, var(--paper) 72%, transparent); }
.foot h3 { font-size: var(--t-label); font-family: var(--f-slip); letter-spacing: .18em;
           text-transform: uppercase; color: color-mix(in srgb, var(--paper) 88%, transparent);
           font-weight: 700; margin-bottom: .9rem; }
.foot ul { list-style: none; padding: 0; display: grid; gap: .5rem; font-size: var(--t-small); }
/* Icon and label on one line, with the icon holding its width whether or not
   the SVG has painted yet — otherwise the list jumps as the glyphs land. */
.foot li a { display: inline-flex; align-items: center; gap: .5rem; }
/* Footer links: no underline at rest, underline on hover, keyboard focus and
   while being tapped on a phone. */
.foot a { text-decoration: none; }
.foot a:hover, .foot a:focus-visible, .foot a:active { text-decoration: underline; text-underline-offset: .25em; }
.foot [data-brand] {
  width: 14px; height: 14px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: .75; transition: opacity .16s ease;
}
.foot li a:hover [data-brand] { opacity: 1; }
.foot__base { margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--line-lt);
              display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
              font-size: var(--t-label); font-family: var(--f-slip); letter-spacing: .1em;
              color: color-mix(in srgb, var(--paper) 82%, transparent); text-transform: uppercase; }

/* --- 14. Motion ---------------------------------------------------------- */
[data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
[data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  [data-reveal] { opacity: 1; transform: none; }
}

/* --- 15. Toast ----------------------------------------------------------- */
.toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translate(-50%, 120%);
  background: var(--ink); color: var(--paper); padding: .8rem 1.4rem; border-radius: 999px;
  font-size: var(--t-small); z-index: 150; transition: transform .35s var(--ease);
}
.toast[data-open="true"] { transform: translate(-50%, 0); }

/* --- 16. Date picker ------------------------------------------------------
   A written picker, because <input type="date"> takes min and max and nothing
   else — it cannot grey out a Tuesday that is already fully booked. See
   assets/js/datepicker.js for why that matters.
   ------------------------------------------------------------------------ */
.dp { position: relative; }

.dp__field {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; cursor: pointer; text-align: left;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 6px; padding: .7rem .85rem;
  font: inherit; color: var(--ink);
}
.dp__field:hover { border-color: var(--accent); }
.dp__field:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dp__field svg { color: var(--muted); flex: 0 0 auto; }
/* Same as every other empty field: white, with the small hint-sized prompt.
   The cream fill made the date fields look disabled next to the white inputs. */
.dp__field { background: var(--field); font-size: var(--t-body); }
.dp__value--placeholder { color: color-mix(in srgb, var(--muted) 70%, transparent); font-size: var(--t-caption); }
/* A dropdown still on its "Choose one" prompt reads as a prompt, not an answer.
   It keeps 16px (smaller makes iPhones zoom in on tap), only the colour softens. */
.field select:has(option[value=""]:checked) { color: color-mix(in srgb, var(--muted) 70%, transparent); }
.field select option { color: var(--ink); }

.dp--off .dp__field { background: var(--paper); cursor: not-allowed; opacity: .65; }
.dp--off .dp__field:hover { border-color: var(--line); }

.dp__pop {
  position: absolute; z-index: 60; top: calc(100% + .4rem); left: 0;
  width: min(20rem, 92vw);
  background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: .8rem;
  box-shadow: 0 12px 32px rgba(42, 42, 34, .18);
}
/* Near the right edge of a narrow screen the popup would run off; anchoring it
   to the right instead keeps it on screen without measuring anything. */
@media (max-width: 520px) { .dp__pop { left: auto; right: 0; } }

.dp__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: .6rem; font-size: var(--t-small);
}
.dp__nav {
  width: 1.9rem; height: 1.9rem; border-radius: 50%;
  border: 1px solid var(--line); background: transparent; cursor: pointer;
  font-size: var(--t-body); line-height: 1; color: var(--ink);
}
.dp__nav:hover:not(:disabled) { background: var(--paper); border-color: var(--accent); }
.dp__nav:disabled { opacity: .3; cursor: not-allowed; }

.dp__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp__grid--names {
  margin-bottom: .3rem; text-align: center;
  font-family: var(--f-slip); font-size: var(--t-micro); letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}
.dp__pad { aspect-ratio: 1; }

.dp__day {
  aspect-ratio: 1; display: grid; place-items: center; position: relative;
  border: 0; border-radius: 6px; background: transparent; cursor: pointer;
  font: inherit; font-size: var(--t-caption); color: var(--ink);
}
.dp__day:hover:not(:disabled) { background: var(--dusk); }
.dp__day--on { background: var(--forest); color: var(--paper); font-weight: 600; }
.dp__day--on:hover { background: var(--forest); }

/* Unavailable, and visibly so before it is clicked. Strike-through rather than
   dimming alone: a faint number reads as "loading", a struck one reads as
   "no". */
.dp__day--off {
  color: color-mix(in srgb, var(--muted) 55%, transparent);
  cursor: not-allowed; text-decoration: line-through;
}
.dp__day--off:hover { background: transparent; }

/* A dot under the number, not a colour on it — the number has to stay legible,
   and the selected day already owns the background. */
.dp__day--express::after,
.dp__day--full::after {
  content: ""; position: absolute; bottom: .28rem;
  width: 4px; height: 4px; border-radius: 50%;
}
.dp__day--express::after { background: var(--accent); }
.dp__day--full::after    { background: #A33B2E; }
.dp__day--on::after      { background: var(--paper); }

.dp__key {
  display: flex; flex-wrap: wrap; gap: .75rem; margin-top: .7rem;
  padding-top: .6rem; border-top: 1px solid var(--line);
  font-size: var(--t-micro); color: var(--muted);
}
.dp__key span { display: inline-flex; align-items: center; gap: .3rem; }
.dp__dot { width: 5px; height: 5px; border-radius: 50%; display: inline-block; }
.dp__dot--express { background: var(--accent); }
.dp__dot--full    { background: #A33B2E; }

/* --- 17. Tooltip ----------------------------------------------------------
   For the sentence that only matters once. The delivery field carried four
   sentences of rules underneath it — a wall of small print that every customer
   had to read past on every visit, to learn something most of them did not
   need. The rule that always applies stays visible as one line; the rest moved
   in here, behind a mark you press only if you want it.

   Built on a real <button> so it is reachable by keyboard and announced by a
   screen reader, not a hover-only div that simply does not exist on a phone.
   ------------------------------------------------------------------------ */
.tip {
  display: inline-grid; place-items: center; vertical-align: middle;
  width: 1.05rem; height: 1.05rem; margin-left: .3rem; padding: 0;
  border: 1px solid var(--line); border-radius: 50%; background: transparent;
  color: var(--muted); font-family: var(--f-body); font-size: var(--t-micro);
  line-height: 1; cursor: help; position: relative;
}
.tip:hover, .tip[data-open] { background: var(--accent); color: var(--paper); border-color: var(--accent); }

.tip::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + .5rem); left: 50%;
  translate: -50% 0;
  width: max-content; max-width: min(20rem, 70vw);
  background: var(--forest); color: var(--paper);
  padding: .6rem .75rem; border-radius: 6px;
  font-size: var(--t-caption); font-weight: 400; line-height: 1.45;
  letter-spacing: 0; text-transform: none; text-align: left;
  box-shadow: 0 6px 20px rgba(42, 42, 34, .22);
  opacity: 0; visibility: hidden; transition: opacity .14s var(--ease);
  z-index: 80; pointer-events: none;
}
.tip:hover::after, .tip:focus-visible::after, .tip[data-open]::after {
  opacity: 1; visibility: visible;
}
/* Near the left edge the centred bubble would hang off the page. */
@media (max-width: 560px) {
  .tip::after { left: auto; right: -.5rem; translate: 0 0; }
}

/* Language switch in the footer base. Underlined because it is a link doing
   something a visitor has to notice, not decoration. */
.foot__lang a { text-decoration: none; }
.foot__lang a:hover { color: var(--dusk); }

/* --- 18. "Press send" note -------------------------------------------------
   Shown after the WhatsApp button is clicked. The message is written but not
   sent, and that distinction is invisible from this page.
   ------------------------------------------------------------------------ */
.sent {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: var(--gutter);
  background: rgba(42, 42, 34, .45);
  backdrop-filter: blur(3px);
}
.sent__box {
  width: min(26rem, 100%); background: var(--card);
  border-radius: 10px; padding: 1.75rem;
  box-shadow: 0 18px 50px rgba(42, 42, 34, .3);
}
.sent__box h2 { font-size: var(--t-h3); margin-bottom: .75rem; }
.sent__box p  { font-size: var(--t-small); color: var(--muted); margin-bottom: 1.25rem; }

/* --- floating chat button ---------------------------------------------------
   Same family as the header chips: forest pill, cream text, Courier label. */
.chat-float {
  position: fixed; right: max(1rem, env(safe-area-inset-right)); bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 70; display: inline-flex; align-items: center; gap: .5rem;
  background: var(--forest); color: var(--paper); text-decoration: none;
  border-radius: 999px; padding: .75rem 1.1rem;
  font-family: var(--f-slip); font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase;
  box-shadow: 0 6px 20px rgba(42, 42, 34, .22);
  transition: transform .2s var(--ease), background .2s ease;
}
.chat-float:hover { background: var(--accent); transform: translateY(-2px); }
.chat-float:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.chat-float [data-brand] { width: 16px; height: 16px; display: inline-flex; }
.chat-float svg { width: 16px; height: 16px; }

/* --- photo lightbox ---------------------------------------------------------- */
.card__media img[role="button"] { cursor: zoom-in; }
.lb {
  position: fixed; inset: 0; z-index: 400; display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem); background: rgba(47, 53, 39, .88);
}
.lb[hidden] { display: none; }
.lb__fig { margin: 0; display: grid; gap: .75rem; max-width: min(92vw, 720px); }
.lb__img { width: 100%; max-height: 72vh; object-fit: contain; border-radius: 6px; background: var(--dusk); }
.lb__cap {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  background: var(--paper); border-radius: 6px; padding: .85rem 1rem;
}
.lb__name { font-family: var(--f-display); font-size: var(--t-h4); font-variation-settings: "SOFT" 40, "WONK" 1; line-height: 1.15; }
.lb__price { font-family: var(--f-slip); color: var(--accent); font-size: var(--t-small); margin-top: .2rem; }
.lb__close {
  position: absolute; top: max(.75rem, env(safe-area-inset-top)); right: .75rem;
  width: 2.75rem; height: 2.75rem; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--paper); color: var(--ink); font-size: 1.5rem; line-height: 1;
}
.lb__close:focus-visible { outline: 2px solid var(--paper); outline-offset: 3px; }
