/* =========================================================
   Hot & Cool Inn — Hero A · Charcoal Wave
   Tokens per inspiration-design-language.md §13
   ========================================================= */

:root {
  --cream: #fff7e8;
  --cream-hi: #fffdf6;
  --sand: #ecdbc3;

  --crimson: #920812;
  --crimson-dp: #6b0410;
  --crimson-lt: #b4121f;
  --gold: #fdc752;
  --gold-soft: #ffeb8c;
  --amber: #fc9e25;

  --pine: #0a4d3b;
  --whatsapp: #0e7a40;
  --whatsapp-lit: #25d366;
  --charcoal: #14100e;
  --ink: #2e170d;
  --ink-2: #4a2f20;

  /* secondary text on the crimson field — tinted from the hue, never gray */
  --on-crimson-2: #f2cfc6;

  --font-display: "Bagel Fat One", "Titan One", system-ui, sans-serif;
  --font-text: "Manrope", system-ui, -apple-system, sans-serif;

  /* Two measured heights, republished by the watcher at the foot of index.html,
     so clearances follow the elements when they wrap to two rows on a phone
     instead of being guessed per breakpoint. The values written here are only
     what holds before the script runs.
     --topbar-h  the hero's top air, so the headline starts below the name plate.
     --catbar-h  the pinned category rail, so a jump to a category lands under
                 the rail rather than beneath it. */
  --topbar-h: 6rem;
  --catbar-h: 4.5rem;
  /* even air above and below the pill: the crimson frames it, never floors it */
  --topbar-pad: clamp(0.7rem, 1.4vw, 0.95rem);

  --r-xs: 8px;
  --r-sm: 14px;
  --r-md: 22px;
  --r-lg: 34px;
  --r-leaf: 26px;
  --r-pill: 999px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --shadow-sm: 0 2px 8px rgba(46, 23, 13, 0.1);
  --shadow-md: 0 12px 28px -10px rgba(46, 23, 13, 0.28);
  --shadow-lg: 0 34px 64px -26px rgba(20, 4, 6, 0.62);
}

/* ---------- reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
/* An explicit display in author CSS beats the hidden attribute's UA rule, and this
   page hides a lot of things by attribute — search results, the closed-shop warning,
   the restored-basket notice. Answer it once, here, rather than per component. */
[hidden] {
  display: none !important;
}

/* every in-page jump on this page is a move between two parts of one order, so
   the travel is worth showing rather than cutting */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
/* One column, and the bar shares its first cell with <main> (see the top bar
   block) so the bar can ride over the hero's crimson instead of standing on a
   band of its own. Later children — the footer — fall into the rows below. */
body {
  margin: 0;
  display: grid;
  grid-template-columns: 100%;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img {
  max-width: 100%;
  height: auto;
  display: block;
}
a {
  color: inherit;
  text-decoration: none;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
h1 {
  margin: 0;
}
p {
  margin: 0;
}

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 4px;
}

.wrap {
  width: min(1180px, 100% - 2.5rem);
  margin-inline: auto;
}
@media (max-width: 640px) {
  .wrap {
    width: min(1180px, 100% - 2rem);
  }
}

/* ---------- icons ---------- */
.ico {
  width: 1.15em;
  height: 1.15em;
  flex: none;
}
.ico--stroke {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- buttons: the leaf ---------- */
.btn {
  --r-a: var(--r-leaf);
  --r-b: 0px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 52px;
  padding: 0.85rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--r-a) var(--r-b) var(--r-a) var(--r-b);
  font: 800 1rem/1.1 var(--font-text);
  letter-spacing: 0.005em;
  cursor: pointer;
  transition:
    border-radius 200ms var(--ease-out),
    transform 200ms var(--ease-out),
    rotate 220ms var(--ease-out),
    background-color 200ms var(--ease-out);
}
.btn:hover {
  --r-a: 0px;
  --r-b: var(--r-leaf);
  transform: translateY(-2px);
}
.btn:active {
  transform: translateY(0);
}

.btn.topbar__cta {
  border-radius: var(--r-a) var(--r-a) var(--r-a) var(--r-b);
}

.btn.topbar__cta:hover {
  --r-a: var(--r-leaf);
  --r-b: 0px;
  border-radius: var(--r-b) var(--r-a) var(--r-a) var(--r-a);
}

/* The tandoor poster's ticket move (02/styles.css .ticket), brought onto the hero's
   two actions: each sits a little off-square and straightens as you reach for it.
   Tilted at rest rather than on hover on purpose — the button settles under the
   pointer instead of sliding out from under it, so the character costs nothing in
   aim. It composes with the leaf-corner flip because `rotate` is its own property,
   not a transform function competing for the same slot. Opposite signs so the pair
   reads as two things put down on a table, not one thing skewed twice. */
.btn--tilt {
  rotate: -1.6deg;
}
.btn--tilt-r {
  rotate: 1.6deg;
}
.btn--tilt:hover,
.btn--tilt:focus-visible {
  rotate: 0deg;
}

.btn--lg {
  min-height: 60px;
  padding: 1rem 2.1rem;
  font-size: 1.0625rem;
}
.btn--sm {
  min-height: 46px;
  padding: 0.6rem 1.15rem;
  font-size: 0.9375rem;
  --r-leaf: 18px;
}

.btn--gold {
  background: var(--gold);
  color: var(--crimson-dp);
  box-shadow: var(--shadow-md);
}
.btn--gold:hover {
  background: var(--gold-soft);
}
.btn--ghost {
  background: transparent;
  color: var(--cream);
  border-color: rgba(255, 247, 232, 0.55);
}
.btn--ghost:hover {
  background: rgba(255, 247, 232, 0.1);
  border-color: var(--cream);
}
.btn--wa {
  background: var(--whatsapp);
  color: var(--cream);
}
.btn--wa:hover {
  background: #0b6835;
}

/* ---------- top bar ---------- */
/* The bar shares <body>'s first grid cell with <main>, so it lies over the hero
   rather than above it. That is what lets it carry no ground of its own: the pill
   floats straight on the crimson field, with the hero's own ember texture running
   unbroken behind it, and it never has to survive a change of background because
   it never leaves the hero — it scrolls away with it. The thing worth keeping
   on screen is the category rail, and that is what pins (see .catbar).
   align-self keeps the bar at the top of the shared cell. */
.topbar {
  grid-area: 1 / 1;
  align-self: start;
  position: relative;
  z-index: 60;
  padding-block: var(--topbar-pad);
}
main {
  grid-area: 1 / 1;
}
.topbar__inner {
  width: min(1180px, 100% - 2.5rem);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.75rem);
  row-gap: 0.55rem;
  flex-wrap: wrap;
  padding: 0.6rem 0.6rem 0.6rem 1.4rem;
  background: var(--cream-hi);
  border-radius: var(--r-lg);
  /* floating clear of the crimson field wants more lift than a flat card does */
  box-shadow: 0 10px 26px -18px rgba(20, 4, 6, 0.7);
}
.brand {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.1vw, 1.4rem);
  line-height: 1;
  color: var(--crimson);
  padding-block: 0.2em;
  white-space: nowrap;
}
.topnav {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  margin-inline-start: auto;
  font-weight: 700;
  font-size: 0.9375rem;
  color: var(--ink-2);
}
.topnav a {
  padding: 0.5rem 0;
  border-bottom: 2px solid transparent;
  transition:
    color 160ms var(--ease-out),
    border-color 160ms var(--ease-out);
}
.topnav a:hover {
  color: var(--crimson);
  border-bottom-color: var(--crimson);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.85rem;
  border-radius: var(--r-pill);
  background: rgba(10, 77, 59, 0.09);
  color: var(--pine);
  font-size: 0.8125rem;
  font-weight: 700;
  white-space: nowrap;
}
.status__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--whatsapp-lit);
  box-shadow: 0 0 0 3px rgba(37, 211, 102, 0.22);
}
.status__sep {
  opacity: 0.5;
}

/* The four parts fit on one line down to roughly 880px. Below that the category
   links are the one part the page repeats elsewhere — the band index carries the
   same three jumps — so they are what goes, and the status takes over the job of
   holding the right edge that the links' auto margin was doing. */
@media (max-width: 880px) {
  .topbar__inner {
    padding-inline: 1rem;
  }
  .topnav {
    display: none;
  }
  /* The links' auto margin was what held the right edge open; with them gone the
     brand takes that job. Pushing from the left rather than pulling from the right
     also means that if the status has to wrap it lands at the start of its own
     line instead of hanging off the far edge. */
  .brand {
    margin-inline-end: auto;
  }
}
/* Phones: the order button steps out — the hero's own button and the carried
   dock both cover it — leaving the name and whether the shop is open. */
@media (max-width: 560px) {
  .topbar__cta {
    display: none;
  }
}
/* Tight enough that the name and the open sign still share one line at 375px,
   which is as narrow as phones commonly get before the next rule takes over. */
@media (max-width: 420px) {
  .topbar__inner {
    padding-inline: 0.75rem;
    column-gap: 0.625rem;
  }
  .status {
    padding-inline: 0.6rem;
    font-size: 0.75rem;
  }
}
@media (max-width: 370px) {
  .brand {
    margin-inline-end: 0;
  }
  .status {
    width: 100%;
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .topnav a {
    transition: none;
  }
}

/* ---------- hero stage ---------- */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--crimson);
  /* Top: the bar now lies over this section rather than above it, so the hero owns
     the whole of the clearance — the bar's measured height plus the air the
     headline needs under it.
     Bottom: enough for the wave's full height plus air, since the showcase now hangs
     into that band instead of the old cut-out which needed none. */
  padding-block: calc(var(--topbar-h) + clamp(1.5rem, 3.5vw, 2.75rem))
    clamp(6rem, 11vw, 9rem);
}
/* Charcoal, at a whisper. The ember photo is the same file 03 uses, but there it IS
   the ground; here it only has to keep the crimson from reading as flat ink, so it
   runs at a sixth strength and is masked out well before the wave — a texture that
   reached the cut would fight the one edge this page is built on. Its own layer, not
   a background-blend stack: a missing file then paints nothing instead of reordering
   the blend and darkening the whole field. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("./images/ember-texture.webp") center / cover no-repeat;
  mix-blend-mode: multiply;
  opacity: 1;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 88%);
  mask-image: linear-gradient(to bottom, #000 40%, transparent 88%);
}
/* the warm glow now sits behind the food rather than behind the type */
.hero__ember {
  position: absolute;
  left: 68%;
  top: 46%;
  width: min(1000px, 105%);
  aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(
    circle,
    rgba(252, 158, 37, 0.3) 0%,
    rgba(252, 158, 37, 0.1) 42%,
    rgba(252, 158, 37, 0) 68%
  );
  z-index: 0;
  pointer-events: none;
}

.hero__grid {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6.5fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
}
.hero__copy {
  position: relative;
  z-index: 4;
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.35rem, 5.6vw, 4.25rem);
  line-height: 0.92;
  color: var(--cream);
  text-wrap: balance;
  display: grid;
  gap: 0.02em;
  text-shadow: 0 6px 24px rgba(20, 4, 6, 0.35);
}
.rise--gold {
  color: var(--gold);
}

.lede {
  margin-top: clamp(1.1rem, 2.4vw, 1.6rem);
  max-width: 46ch;
  font-size: clamp(1rem, 1.45vw, 1.125rem);
  font-weight: 500;
  line-height: 1.6;
  color: var(--on-crimson-2);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}

.reassure {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: clamp(1.1rem, 2.2vw, 1.5rem);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--on-crimson-2);
}

/* ---------- the showcase, lying across the cut ---------- */
/* The leaf, at plate scale: two corners rounded hard, two left square, the same
   diagonal the buttons cut. No shadow anywhere on it — the cream edge and the gold
   hairline separate it from the crimson, and the photograph brings its own near-black
   slate up to the border, so a shadow would only muddy the one clean edge. */
.showcase {
  --r-frame: clamp(30px, 4.5vw, 60px);
  --frame-w: clamp(4px, 0.55vw, 7px);
  position: relative;
  z-index: 3;
  margin: 0;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--charcoal);
  border: var(--frame-w) solid var(--cream);
  border-radius: var(--r-frame) 0 var(--r-frame) 0;
  /* The frame hangs into the wave band so the cut runs under the food rather than
     stopping at it. The grid centres the column, so this drops the frame by half of
     what it takes off the row — budget roughly double the overlap you want. */
  margin-bottom: calc(-1 * clamp(4.5rem, 10vw, 10.5rem));
}
.showcase img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- the wave cut ---------- */
.wavecut {
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: clamp(56px, 8vw, 130px);
  z-index: 2;
  display: block;
}
.wavecut path {
  fill: var(--cream);
}

/* one column: type first, then the showcase, still lying across the cut */
@media (max-width: 860px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.75rem, 5vw, 2.5rem);
  }
  .hero__copy {
    text-align: center;
  }
  .hero__title {
    font-size: clamp(2.35rem, 8vw, 3.75rem);
  }
  .lede {
    margin-inline: auto;
  }
  .actions {
    justify-content: center;
  }
  .hero__ember {
    left: 50%;
    top: 62%;
  }
  .showcase {
    width: min(520px, 100%);
    margin-inline: auto;
  }
}

@media (max-width: 480px) {
  .actions {
    flex-direction: column;
    align-items: stretch;
    gap: 0.7rem;
  }
  .actions .btn {
    width: 100%;
  }
  /* Full-bleed buttons exaggerate the tilt, and opposite signs make the stacked pair
     converge at one end — which reads as a broken box, not a flourish. Shallower, and
     both leaning the same way, so they stack like two tickets laid down together. */
  .btn--tilt,
  .btn--tilt-r {
    rotate: -0.8deg;
  }
}

/* =========================================================
   SECTION 2 — FORAN ORDER KAREIN
   Six cards on cream, caught directly under the wave. A card is a menu row
   that was given a picture — same pills, same Shamil, same per-size lines —
   so a count taken here shows up on its own row further down without being
   told to. The engine adds .row--in to whatever carries data-item, card or
   row alike, which is why that class name turns up on a .feat.
   ========================================================= */
.feats {
  background: var(--cream);
  padding-block: clamp(1.75rem, 4vw, 3rem) clamp(1.5rem, 3.5vw, 2.5rem);
  scroll-margin-top: 1.25rem;
}

.feats__head {
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}
.feats__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.75rem, 5vw, 3rem);
  line-height: 1;
  color: var(--crimson);
}
.feats__note {
  margin-top: 0.4rem;
  max-width: 52ch;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-2);
}

.feats__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.9rem, 2vw, 1.5rem);
  align-items: start;
}

/* the card wears the leaf silhouette the buttons use, at panel scale */
.feat {
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--cream-hi);
  border: 2px solid rgba(46, 23, 13, 0.1);
  border-radius: var(--r-lg) 0 var(--r-lg) 0;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition:
    transform 200ms var(--ease-out),
    box-shadow 200ms var(--ease-out),
    border-color 200ms var(--ease-out);
}
.feat:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.feat.row--in {
  border-color: var(--crimson);
}

.feat__shot {
  margin: 0;
  aspect-ratio: 1;
  background: var(--sand);
  overflow: hidden;
}
.feat__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.feat__body {
  display: grid;
  align-content: start;
  gap: 0.35rem;
  padding: clamp(0.85rem, 1.8vw, 1.15rem);
}
.feat__name {
  margin: 0;
  font-weight: 800;
  font-size: clamp(0.9375rem, 1.6vw, 1.0625rem);
  line-height: 1.25;
  color: var(--ink);
}
.feat.row--in .feat__name {
  color: var(--crimson);
}
.feat__blurb {
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink-2);
}

.feat__sizecap {
  margin-top: 0.25rem;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.feat__foot {
  margin-top: 0.45rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}
.feat__price {
  display: inline-flex;
  align-items: baseline;
  gap: 0.22rem;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  line-height: 1;
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
}
.feat__price i {
  font: 800 0.62em/1 var(--font-text);
  font-style: normal;
  color: var(--ink-2);
}

.feat .rowlines {
  margin-top: 0.35rem;
}

/* the hero's dashed placeholder is drawn for crimson; on cream it needs ink */
.feat .slot--empty {
  border-color: rgba(146, 8, 18, 0.4);
}
.feat .slot--empty::after {
  color: rgba(46, 23, 13, 0.7);
}

@media (max-width: 900px) {
  .feats__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  /* A card body is a fraction of the width a menu row gets, so "Rs 800 × 1" and
     the counter stop competing for one line and take a line each. */
  .feat .rowline {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .feat .rowline__text {
    grid-column: 1 / -1;
  }
}

@media (max-width: 560px) {
  /* One up, turned on its side. The picture stops being a headline and becomes a
     thumbnail, which fits all six into far less scroll than a 2-up grid would —
     six cards must not cost a whole screen before the menu starts. */
  .feats__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.6rem;
  }
  .feat {
    grid-template-rows: none;
    grid-template-columns: clamp(96px, 27vw, 124px) minmax(0, 1fr);
  }
  .feat__shot {
    aspect-ratio: auto;
  }
  .feat__body {
    padding: 0.7rem 0.8rem;
  }
}

/* =========================================================
   SECTION 3 — THE MENU, AS BANDS
   Categories arrive as alternating cream/crimson fields, each cut in by
   the same wave the hero uses. The cut is the page's spine, not a one-off.
   ========================================================= */
/* Neither of these lands under the rail — a jump to the menu arrives above where
   the rail starts, and a jump to the order card arrives below where it lets go —
   so they want air at the top, not a clearance. */
.menu,
.checkout {
  scroll-margin-top: 1.25rem;
}
/* the menu now sits directly under the wave cut, so it carries the clearance
   the category rail used to hold open */
.menu {
  background: var(--cream);
  padding-block: clamp(1.5rem, 3.5vw, 2.75rem) clamp(2rem, 5vw, 4rem);
}

.menu__intro {
  padding-block: clamp(0.5rem, 2vw, 1.5rem) clamp(1.5rem, 3vw, 2.5rem);
}
.menu__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 5.5vw, 3.5rem);
  line-height: 1;
  color: var(--crimson);
}
.menu__note {
  margin-top: 0.6rem;
  max-width: 54ch;
  font-size: clamp(0.9375rem, 1.4vw, 1.0625rem);
  font-weight: 500;
  color: var(--ink-2);
}
.menu__note b {
  color: var(--ink);
  font-weight: 800;
}

/* ---------- finding things in 112 items ---------- */
.finder {
  margin-top: clamp(1.1rem, 2.4vw, 1.6rem);
}
.qbox {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 30rem;
  padding: 0 0.9rem;
  border: 2px solid var(--sand);
  border-radius: var(--r-pill);
  background: var(--cream-hi);
  transition: border-color 160ms var(--ease-out);
}
.qbox:focus-within {
  border-color: var(--crimson);
}
.qbox > .ico {
  width: 1.15rem;
  height: 1.15rem;
  color: var(--ink-2);
}
.qbox__in {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  border: 0;
  background: none;
  color: var(--ink);
  font: 600 1rem/1.2 var(--font-text);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.qbox__in::placeholder {
  color: #9a8672;
  font-weight: 500;
}
.qbox__in::-webkit-search-cancel-button {
  display: none;
}
.qbox__x {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink);
  cursor: pointer;
}
.qbox__x svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
}
.qbox__x:hover {
  background: var(--crimson);
  color: var(--cream);
}
.qcount {
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--ink-2);
}
.qcount b {
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
}

/* ---------- the category index ----------
   The rail is the one control worth carrying: 112 items is a long scroll, and
   without it a jump between categories means going back up. So it holds itself
   to the top of the window for the whole of the menu section — sticky inside
   .menu, which means it lets go on its own once the order card arrives and there
   is nothing left to jump between.

   It rides as a full-bleed cream band, not a floating slip. That is what lets it
   have no shape of its own: edge to edge there is no outline to notice, and at
   rest it is the same cream as the menu it sits in, so it simply is not there
   until it catches. What separates it once it is over a crimson band is its own
   solid ground plus the shadow it casts down the page — the band reads as the
   near layer, whatever happens to be passing beneath it. */
.catbar {
  position: sticky;
  top: 0;
  /* clear of everything a band raises for itself — the wave cuts sit at 1, a
     crimson band's own .wrap at 2 */
  z-index: 50;
  background: var(--cream);
  padding-block: clamp(0.7rem, 1.6vw, 1rem);
  transition: box-shadow 260ms var(--ease-out);
}
.catbar__inner {
  width: min(1180px, 100% - 2.5rem);
  margin-inline: auto;
}
@media (max-width: 640px) {
  .catbar__inner {
    width: min(1180px, 100% - 2rem);
  }
}
/* A hairline to land the bottom edge when cream is passing under cream, and a
   soft drop underneath it that does the work over the crimson bands. */
.catbar.is-pinned {
  box-shadow:
    0 1px 0 rgba(46, 23, 13, 0.12),
    0 12px 26px -12px rgba(20, 4, 6, 0.45);
}
/* The scrollbar goes. In the flow it was just a track under some pills, but in a
   band with an edge of its own it lands a second line right beside the first and
   the two read as a seam. What replaces it as the sign that the row runs on is
   the fade at the trailing end — and the tab already half-cut there, which the
   fade lets show rather than clipping flat. */
.index {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(
    to right,
    #000 calc(100% - 2.5rem),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    #000 calc(100% - 2.5rem),
    transparent 100%
  );
}
.index::-webkit-scrollbar {
  display: none;
}
.index .tab {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0.35rem 0.9rem;
  border-radius: var(--r-pill);
  background: var(--sand);
  color: var(--ink);
  font-weight: 800;
  font-size: 0.875rem;
  white-space: nowrap;
  scroll-snap-align: start;
  transition:
    background-color 160ms var(--ease-out),
    color 160ms var(--ease-out);
}
.index .tab:hover {
  background: var(--crimson);
  color: var(--cream);
}
/* A search replaces the categories with one flat list of matches, so the rail has
   nothing to point at. The whole container goes, not just the tabs inside it —
   otherwise a pinned pill would hold at the top of the window with nothing in it. */
body.is-searching .catbar {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .catbar,
  .index .tab {
    transition: none;
  }
}

.noresults {
  display: block;
  margin-top: clamp(2rem, 5vw, 3.5rem);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--ink-2);
  text-align: center;
}
.noresults b {
  color: var(--crimson);
}

/* ---------- a category band ---------- */
/* Every jump from the rail lands here, and the rail is pinned when it does — so
   the clearance is the rail's own measured height plus a little air. */
.cat {
  position: relative;
  padding-block: clamp(1.5rem, 3.5vw, 3rem);
  scroll-margin-top: calc(var(--catbar-h) + 0.75rem);
}
.cat--dark {
  background: var(--crimson);
  color: var(--cream);
  margin-block: clamp(2.5rem, 6vw, 5rem);
  padding-block: calc(var(--wave-h, 90px) + clamp(0.5rem, 2vw, 1.5rem));
}
.cat--dark {
  --wave-h: clamp(56px, 8vw, 130px);
}

.cat__wave {
  position: absolute;
  left: 0;
  width: 100%;
  height: var(--wave-h);
  display: block;
  z-index: 1;
}
.cat__wave path {
  fill: var(--cream);
}
.cat__wave--top {
  top: -1px;
  transform: scaleY(-1);
}
.cat__wave--bottom {
  bottom: -1px;
}
.cat--dark .wrap {
  position: relative;
  z-index: 2;
}

/* ---------- category head ---------- */
.cat__head {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 1.75rem);
  margin-bottom: clamp(1rem, 2.5vw, 1.75rem);
}
.cat__photo {
  margin: 0;
  flex: none;
  width: clamp(88px, 14vw, 150px);
  aspect-ratio: 1;
  border-radius: 58% 42% 47% 53% / 45% 52% 48% 55%;
  overflow: hidden;
  background: var(--sand);
  box-shadow: var(--shadow-md);
}
.cat__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cat__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.75rem, 5vw, 3rem);
  line-height: 1;
  color: var(--crimson);
}
.cat__note {
  margin-top: 0.3rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-2);
}
.cat--dark .cat__title {
  color: var(--gold);
}
.cat--dark .cat__note {
  color: var(--on-crimson-2);
}

/* ---------- item rows ---------- */
.rows {
  display: grid;
}
.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas: "main price add";
  align-items: center;
  gap: 0.4rem 1rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid rgba(46, 23, 13, 0.12);
}
.cat--dark .row {
  border-bottom-color: rgba(255, 247, 232, 0.18);
}
.rows .row:last-child {
  border-bottom: 0;
}

.row__main {
  grid-area: main;
  display: grid;
  gap: 0.4rem;
}

/* ---------- the rows that carry a picture and a line of copy: platters, charga ---------- */
.row--big {
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-areas: "shot main price add";
  gap: 0.5rem clamp(1rem, 2vw, 1.5rem);
  padding-block: clamp(1rem, 2vw, 1.4rem);
}
.row__shot {
  grid-area: shot;
  margin: 0;
  width: clamp(118px, 17vw, 210px);
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--sand);
  box-shadow: var(--shadow-sm);
}
.row__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.row__desc {
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-2);
}
.cat--dark .row__desc {
  color: var(--on-crimson-2);
}
.cat--dark .row__shot {
  background: rgba(255, 247, 232, 0.12);
}
.row__name {
  font-weight: 800;
  font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
  color: var(--ink);
}
.cat--dark .row__name {
  color: var(--cream);
}

.row__price {
  grid-area: price;
  justify-self: end;
  display: inline-flex;
  align-items: baseline;
  gap: 0.25rem;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  line-height: 1;
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
  min-width: 5.2rem;
  justify-content: flex-end;
}
.row__price i {
  font: 800 0.62em/1 var(--font-text);
  font-style: normal;
  color: var(--ink-2);
}
.cat--dark .row__price {
  color: var(--gold);
}
.cat--dark .row__price i {
  color: var(--on-crimson-2);
}

/* size pills */
.opts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}
.opt {
  min-height: 32px;
  padding: 0.25rem 0.75rem;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--sand);
  color: var(--ink-2);
  font: 800 0.8125rem/1 var(--font-text);
  cursor: pointer;
  transition:
    background-color 160ms var(--ease-out),
    color 160ms var(--ease-out);
}
.opt:hover {
  background: #e0cbac;
}
.opt.is-on {
  background: var(--crimson);
  color: var(--cream);
}
.cat--dark .opt {
  background: rgba(255, 247, 232, 0.16);
  color: var(--cream);
}
.cat--dark .opt:hover {
  background: rgba(255, 247, 232, 0.26);
}
.cat--dark .opt.is-on {
  background: var(--gold);
  color: var(--crimson-dp);
}

/* the add action — the leaf, at row scale */
/* The action slot holds two states in one footprint: Shamil until the row has
   something on it, then a stepper. Both keep the leaf silhouette. */
.rowact {
  grid-area: add;
  justify-self: end;
  display: grid;
}

.rowstep {
  display: flex;
  align-items: center;
  gap: 0.1rem;
  padding: 3px;
  border: 2px solid var(--crimson);
  border-radius: var(--r-leaf) 0 var(--r-leaf) 0;
  background: var(--cream-hi);
}
.rowstep .step {
  width: 34px;
  height: 34px;
}
.rowstep .step__qty {
  min-width: 1.5rem;
  font-size: 0.875rem;
}
.cat--dark .rowstep {
  border-color: var(--gold);
  background: rgba(255, 247, 232, 0.08);
}
.cat--dark .rowstep .step {
  color: var(--gold);
}
.cat--dark .rowstep .step:hover:not(:disabled) {
  background: rgba(253, 199, 82, 0.2);
}
.cat--dark .rowstep .step:disabled {
  color: var(--on-crimson-2);
}
.cat--dark .rowstep .step__qty {
  color: var(--cream);
}
.row--in .row__name {
  color: var(--crimson);
}
.cat--dark .row--in .row__name {
  color: var(--gold-soft);
}

.add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 44px;
  padding: 0.5rem 1.05rem;
  border: 2px solid var(--crimson);
  border-radius: var(--r-leaf) 0 var(--r-leaf) 0;
  background: transparent;
  color: var(--crimson);
  font: 800 0.875rem/1 var(--font-text);
  cursor: pointer;
  transition:
    background-color 180ms var(--ease-out),
    color 180ms var(--ease-out),
    border-radius 200ms var(--ease-out);
}
.add svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
}
.add:hover {
  background: var(--crimson);
  color: var(--cream);
  border-radius: 0 var(--r-leaf) 0 var(--r-leaf);
}
.cat--dark .add {
  border-color: var(--gold);
  color: var(--gold);
}
.cat--dark .add:hover {
  background: var(--gold);
  color: var(--crimson-dp);
}

/* ---------- the lines a sized row grows ----------
   Half and Full are separate things at separate prices, so each one that has been
   ordered keeps its own line here, under the row it came from, with its own counter
   and its own total. The list appears on the first Shamil and takes itself away when
   the last count reaches zero, so a menu nobody has touched stays flat. */
.rowlines {
  grid-column: 1 / -1;
  display: grid;
  gap: 0.3rem;
  margin-top: 0.55rem;
  padding-left: 0.85rem;
  border-left: 3px solid var(--crimson);
}
.rowlines[hidden] {
  display: none;
}
.cat--dark .rowlines {
  border-left-color: var(--gold);
}

.rowline {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.35rem 0.85rem;
  padding: 0.35rem 0.6rem 0.35rem 0.7rem;
  border-radius: 0 var(--r-md) 0 var(--r-md);
  background: rgba(146, 8, 18, 0.07);
}
.cat--dark .rowline {
  background: rgba(255, 247, 232, 0.12);
}

.rowline__text {
  display: grid;
  line-height: 1.3;
}
.rowline__opt {
  font-weight: 800;
  font-size: 0.875rem;
  color: var(--crimson);
}
.rowline__unit {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.cat--dark .rowline__opt {
  color: var(--gold);
}
.cat--dark .rowline__unit {
  color: var(--on-crimson-2);
}

.rowline__sum {
  justify-self: end;
  min-width: 4rem;
  text-align: end;
  font-weight: 800;
  font-size: 0.9375rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.cat--dark .rowline__sum {
  color: var(--cream);
}

/* qualified by .rowline on purpose: the base .stepper rule lives further down the
   file and would otherwise win on source order */
.rowline .stepper--line {
  background: var(--cream-hi);
}
.stepper--line .step {
  width: 32px;
  height: 32px;
}
.stepper--line .step__qty {
  min-width: 1.4rem;
  font-size: 0.875rem;
}
.cat--dark .stepper--line {
  background: rgba(255, 247, 232, 0.14);
}
.cat--dark .stepper--line .step {
  color: var(--gold);
}
.cat--dark .stepper--line .step:hover:not(:disabled) {
  background: rgba(253, 199, 82, 0.2);
}
.cat--dark .stepper--line .step:disabled {
  color: var(--on-crimson-2);
}
.cat--dark .stepper--line .step__qty {
  color: var(--cream);
}

.rowline--new {
  animation: rowline-in 220ms var(--ease-out) both;
}
@keyframes rowline-in {
  from {
    opacity: 0;
    transform: translateY(-5px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .rowline--new {
    animation: none;
  }
}

/* On a phone the name, price and action share one line and the size pills drop
   below it. `display: contents` lets the wrapper's children join the row grid
   directly, so a flat-priced item stays exactly one line tall. */
@media (max-width: 620px) {
  .row {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "name price add"
      "opts opts opts";
    align-items: center;
    row-gap: 0.45rem;
  }
  /* the named areas above claim rows 1 and 2; the lines take the implicit third.
     They stay one line tall — "Half" and "Rs 200 × 1" are short enough to hold it. */
  .rowlines {
    grid-column: 1 / -1;
    margin-top: 0.15rem;
    padding-left: 0.6rem;
  }
  .rowline {
    gap: 0.35rem 0.5rem;
    padding-inline: 0.45rem 0.5rem;
  }
  .rowline__sum {
    min-width: 3.2rem;
  }
  .row__main {
    display: contents;
  }
  .row__name {
    grid-area: name;
  }
  /* Scoped to the row on purpose. A featured card reuses this same .opts markup,
     but its body grid has no "opts" area — an unscoped grid-area would resolve
     against implicit lines there and split the card's body into two columns. */
  .row .opts {
    grid-area: opts;
  }
  .row__price {
    grid-area: price;
    min-width: 0;
  }
  .rowact {
    grid-area: add;
    justify-self: end;
  }
  .cat__head {
    gap: 0.9rem;
  }

  .row--big {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "shot  shot  shot"
      "name  price add"
      "desc  desc  desc";
    align-items: center;
  }
  .row--big .row__shot {
    grid-area: shot;
    width: 100%;
    margin-bottom: 0.35rem;
  }
  .row--big .row__desc {
    grid-area: desc;
  }
}

/* the category photo placeholder needs cream-ground contrast, not the hero's */
.cat__photo.slot--empty {
  border-color: rgba(146, 8, 18, 0.4);
  background: rgba(146, 8, 18, 0.07);
}
.cat__photo.slot--empty::after {
  color: var(--crimson);
  font-size: 0.5rem;
  line-height: 1.25;
  letter-spacing: 0;
  word-break: break-all;
  padding: 0.35rem;
}
.cat--dark .cat__photo.slot--empty {
  border-color: rgba(253, 199, 82, 0.5);
  background: rgba(255, 247, 232, 0.1);
}
.cat--dark .cat__photo.slot--empty::after {
  color: var(--gold);
}

/* =========================================================
   SECTION 3 — THE ORDER
   Another cut. The card is the paper; the crimson is the shop.
   ========================================================= */
.checkout {
  position: relative;
  background: var(--crimson);
  color: var(--cream);
  padding-block: calc(clamp(56px, 8vw, 130px) + clamp(1rem, 3vw, 2.5rem))
    clamp(3rem, 7vw, 5.5rem);
}
.checkout__wave {
  position: absolute;
  left: 0;
  top: -1px;
  width: 100%;
  height: clamp(56px, 8vw, 130px);
  transform: scaleY(-1);
  display: block;
}
.checkout__wave path {
  fill: var(--cream);
}

.checkout__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.checkout__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 5.5vw, 3.5rem);
  line-height: 0.95;
  color: var(--cream);
  display: grid;
}
.checkout__title .is-gold {
  color: var(--gold);
}
.checkout__blurb {
  margin-top: clamp(0.9rem, 2vw, 1.35rem);
  max-width: 44ch;
  font-size: clamp(0.9375rem, 1.4vw, 1.0625rem);
  font-weight: 500;
  color: var(--on-crimson-2);
}

.facts {
  display: grid;
  gap: 0.85rem;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
.facts li {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.5;
  color: var(--cream);
}
.facts .ico {
  width: 1.35rem;
  height: 1.35rem;
  margin-top: 0.1rem;
  color: var(--gold);
}

/* ---------- the order card ---------- */
.card {
  background: var(--cream);
  color: var(--ink);
  border-radius: var(--r-md);
  padding: clamp(1.1rem, 2.4vw, 1.75rem);
  box-shadow: var(--shadow-lg);
}
.card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.8rem;
  border-bottom: 2px dashed rgba(146, 8, 18, 0.3);
}
.card__title {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  line-height: 1;
  color: var(--crimson);
}
.card__count {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.olines {
  display: grid;
}
.oline {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.4rem 0.85rem;
  padding-block: 0.6rem;
  border-bottom: 1px solid rgba(46, 23, 13, 0.1);
}
.oline__text {
  display: grid;
  line-height: 1.3;
}
.oline__name {
  font-weight: 800;
  font-size: 0.9375rem;
}
.oline__name em {
  font-style: normal;
  font-weight: 700;
  color: var(--crimson);
}
.oline__unit {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.oline__sum {
  justify-self: end;
  min-width: 4.2rem;
  text-align: end;
  font-weight: 800;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
}

.stepper {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  padding: 3px;
  border-radius: var(--r-pill);
  background: var(--sand);
}
.step {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--crimson);
  cursor: pointer;
  transition: background-color 160ms var(--ease-out);
}
.step svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
}
.step:hover:not(:disabled) {
  background: rgba(146, 8, 18, 0.12);
}
.step:disabled {
  color: var(--ink-2);
  opacity: 0.35;
  cursor: not-allowed;
}
.step__qty {
  min-width: 1.6rem;
  text-align: center;
  font-weight: 800;
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}

.empty {
  padding: 1.35rem 0.25rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-2);
  text-align: center;
}

.addmore {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  margin-top: 0.7rem;
  padding: 0.5rem 1.1rem;
  border: 2px dashed rgba(146, 8, 18, 0.35);
  border-radius: var(--r-pill);
  color: var(--crimson);
  font-weight: 800;
  font-size: 0.9375rem;
  transition:
    background-color 180ms var(--ease-out),
    border-color 180ms var(--ease-out);
}
.addmore:hover {
  background: rgba(146, 8, 18, 0.07);
  border-color: var(--crimson);
}

.total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(0.8rem, 1.8vw, 1.15rem);
  padding-top: clamp(0.7rem, 1.6vw, 0.95rem);
  border-top: 2px dashed rgba(146, 8, 18, 0.3);
}
.total__label {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  line-height: 1;
}
.total__value {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.6vw, 2.5rem);
  line-height: 1;
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
}
.total__value i {
  font: 800 0.42em/1 var(--font-text);
  font-style: normal;
  color: var(--ink-2);
  margin-inline-end: 0.4em;
}
.total__nil {
  font: 800 0.5em/1 var(--font-text);
  color: var(--ink-2);
}

/* ---------- the parchi number and a way out ---------- */
.refline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 0.7rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--ink-2);
}
.refline b {
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.linkbtn {
  min-height: 32px;
  padding: 0.2rem 0;
  border: 0;
  background: none;
  color: var(--ink-2);
  font: 700 0.8125rem/1 var(--font-text);
  cursor: pointer;
  box-shadow: inset 0 -1px 0 currentColor;
}
.linkbtn:hover {
  color: var(--crimson);
}

/* ---------- a basket that survived a refresh ---------- */
.restored {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-top: 0.8rem;
  padding: 0.65rem 0.9rem;
  border-radius: var(--r-sm);
  background: rgba(253, 199, 82, 0.22);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.5;
}
.restored .ico {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.12rem;
  color: var(--crimson);
}

/* ---------- shut, but still taking orders ---------- */
.warn {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-top: clamp(0.9rem, 2vw, 1.25rem);
  padding: 0.7rem 0.9rem;
  border-radius: var(--r-sm);
  border: 2px solid rgba(146, 8, 18, 0.28);
  background: rgba(146, 8, 18, 0.06);
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.5;
}
.warn .ico {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.1rem;
  color: var(--crimson);
}

.field__opt {
  font-weight: 600;
  color: #9a8672;
  text-transform: none;
  letter-spacing: 0;
}

/* ---------- returning visitor ---------- */
.welcome {
  margin-top: 1rem;
  padding: 0.65rem 0.9rem;
  border-radius: var(--r-sm);
  background: rgba(14, 122, 64, 0.1);
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 600;
}
.welcome b {
  color: var(--pine);
}
.welcome a {
  color: var(--crimson);
  font-weight: 800;
  box-shadow: inset 0 -2px 0 currentColor;
}

/* ---------- the details ---------- */
.fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
  margin-top: clamp(1rem, 2vw, 1.4rem);
}
.field {
  display: grid;
  gap: 0.3rem;
  margin: 0;
}
.field--wide {
  grid-column: 1 / -1;
}
.field__label {
  font-size: 0.8125rem;
  font-weight: 800;
  color: var(--ink-2);
}
.field__in {
  width: 100%;
  min-height: 48px;
  padding: 0.7rem 0.9rem;
  border: 2px solid var(--sand);
  border-radius: var(--r-sm);
  background: var(--cream-hi);
  color: var(--ink);
  font: 600 0.9375rem/1.45 var(--font-text);
  resize: vertical;
  transition: border-color 160ms var(--ease-out);
}
.field__in::placeholder {
  color: #9a8672;
  font-weight: 500;
}
.field__in:focus {
  border-color: var(--crimson);
  outline: none;
}
.field__in:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}
.field__msg {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--crimson);
  min-height: 0;
}
.field--bad .field__in {
  border-color: var(--crimson);
  background: rgba(146, 8, 18, 0.05);
}

@media (max-width: 520px) {
  .fields {
    grid-template-columns: minmax(0, 1fr);
  }
  .oline {
    grid-template-columns: auto minmax(0, 1fr);
    row-gap: 0.4rem;
  }
  .oline__text {
    grid-column: 1 / -1;
  }
  .oline .stepper {
    grid-column: 1;
  }
  .oline__sum {
    grid-column: 2;
    min-width: 0;
  }
}

/* ---------- message preview ---------- */
.preview {
  margin-top: clamp(0.9rem, 2vw, 1.25rem);
}
.preview__cap {
  display: block;
  margin-bottom: 0.45rem;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.bubble {
  white-space: pre-line;
  padding: 0.7rem 0.9rem;
  border: 1px solid rgba(14, 122, 64, 0.22);
  border-radius: 16px 16px 16px 5px;
  background: #e9f8ef;
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
}

#send {
  margin-top: clamp(0.9rem, 2vw, 1.25rem);
}
.btn--block {
  width: 100%;
}
.btn.is-disabled {
  background: var(--sand);
  color: var(--ink-2);
  cursor: not-allowed;
  box-shadow: none;
}
.btn.is-disabled:hover {
  --r-a: var(--r-leaf);
  --r-b: 0px;
  transform: none;
  background: var(--sand);
}

.card__foot {
  margin-top: 0.7rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-2);
  text-align: center;
}

@media (max-width: 980px) {
  .checkout__grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .card {
    max-width: 34rem;
    width: 100%;
  }
}

/* ---------- closed state on the status pill ---------- */
.status--shut {
  background: rgba(146, 8, 18, 0.1);
  color: var(--crimson);
}
.status--shut .status__dot {
  background: var(--crimson-lt);
  box-shadow: 0 0 0 3px rgba(180, 18, 31, 0.2);
}

/* =========================================================
   FOOTER — the facts, nothing else
   ========================================================= */
.foot {
  background: var(--charcoal, #14100e);
  color: var(--cream);
  /* no bottom padding: the colophon strip closes the footer and brings its own */
  padding-top: clamp(2rem, 5vw, 3.5rem);
}
.foot__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
}
.foot__brand {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.6vw, 1.75rem);
  line-height: 1;
  color: var(--gold);
  margin-bottom: 0.5rem;
}
.foot__k {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.4rem;
}
.foot__line {
  font-size: 0.9375rem;
  font-weight: 500;
  color: #e4d5c6;
}
.foot__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  font-weight: 800;
  color: var(--cream);
  box-shadow: inset 0 -2px 0 var(--gold);
}
.foot__link:hover {
  color: var(--gold);
}

/* ---------- payment accounts ----------
   Its own full-width row under the three footer columns rather than a fourth
   column: the number has to stay big enough to read back digit by digit against
   a banking app, and a 15rem column cannot hold one at that size. */
.pay {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  padding-top: clamp(1.5rem, 3.5vw, 2.25rem);
  border-top: 1px solid rgba(255, 247, 232, 0.14);
}
.pay__note {
  max-width: 52ch;
  margin-bottom: clamp(1rem, 2.5vw, 1.4rem);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.6;
  color: #cbb9a8;
}
.pay__note b {
  font-weight: 800;
  color: var(--cream);
}
.pay__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: clamp(0.75rem, 2vw, 1.1rem);
  list-style: none;
}

.acct {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "bank  copy"
    "num   copy"
    "title copy";
  gap: 0.2rem 1rem;
  align-content: center;
  padding: clamp(0.9rem, 2.2vw, 1.15rem) clamp(1rem, 2.5vw, 1.35rem);
  border: 1px solid rgba(253, 199, 82, 0.26);
  border-radius: var(--r-md);
  background: rgba(255, 247, 232, 0.05);
}
.acct__bank {
  grid-area: bank;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
}
/* The digits are the whole point of the card, so they get the size. Tabular
   figures and the extra tracking are what make a 14-digit run checkable by eye;
   user-select:all means a drag or long-press takes the number whole, for anyone
   who reaches past the button. */
.acct__num {
  grid-area: num;
  margin-block: 0.15rem;
  font-size: clamp(1.25rem, 3.2vw, 1.55rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: 0.045em;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
  overflow-wrap: anywhere;
  user-select: all;
}
.acct__title {
  grid-area: title;
  font-size: 0.8125rem;
  font-weight: 600;
  color: #cbb9a8;
}
.acct__title b {
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--cream);
}

.copy {
  grid-area: copy;
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  padding-inline: clamp(0.9rem, 2vw, 1.15rem);
  border: 1.5px solid var(--gold);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--gold);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 800;
  cursor: pointer;
  transition:
    background-color 0.18s var(--ease-out),
    color 0.18s var(--ease-out);
}
.copy:hover {
  background: var(--gold);
  color: var(--charcoal);
}
.copy .ico {
  width: 1.1em;
  height: 1.1em;
}
/* The tick lives in the same button, hidden, so confirming a copy swaps two
   glyphs already in place rather than building an icon on the spot. */
.copy__ok {
  display: none;
}
.copy.is-done {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--charcoal);
}
.copy.is-done .copy__i {
  display: none;
}
.copy.is-done .copy__ok {
  display: block;
}

/* Says in words what the tick says in a glyph — and says which number landed on
   the clipboard, which the tick cannot. Height is held whether or not there is
   anything to say, so a copy never nudges the page. */
.pay__said {
  min-height: 1.5rem;
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--gold);
}
.pay__said--bad {
  color: #ffb4a2;
}

@media (max-width: 430px) {
  .acct {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "bank"
      "num"
      "title"
      "copy";
  }
  .copy {
    justify-content: center;
    margin-top: 0.85rem;
  }
}

/* ---------- colophon: who built it ----------
   A darker strip closing the footer, quiet enough that it never competes with
   the shop's own details a few lines above it. */
.devs {
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  padding-block: clamp(1.1rem, 2.6vw, 1.5rem);
  border-top: 1px solid rgba(255, 247, 232, 0.1);
  background: rgba(0, 0, 0, 0.32);
}
.devs__in {
  display: grid;
  justify-items: start;
  gap: 0.7rem;
}
.devs__list {
  display: flex;
  flex-wrap: wrap;
  /* the column gap carries the link's own negative margin on both sides, so it
     is set an inch wider than it needs to look */
  gap: 0.25rem clamp(1.6rem, 5vw, 3.6rem);
  list-style: none;
}

/* The negative margin gives the link a 44px tap target without the padding
   pushing the two names apart. */
.dev {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 44px;
  padding: 0.3rem 0.5rem;
  margin: -0.3rem -0.5rem;
  border-radius: var(--r-sm);
  color: inherit;
}

/* The initials sit under the photo, not instead of it — so the circle is a
   face once the file lands and a readable monogram until then, and never the
   broken-image glyph in between. */
.dev__face {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 2.375rem;
  height: 2.375rem;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(255, 247, 232, 0.1);
  box-shadow: 0 0 0 1.5px rgba(253, 199, 82, 0.4);
  transition: box-shadow 0.18s var(--ease-out);
}
.dev__face::after {
  content: attr(data-initials);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--gold);
}
.dev__face img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.dev__body {
  display: grid;
  gap: 0.1rem;
}
.dev__name {
  font-size: 0.9375rem;
  font-weight: 800;
  color: var(--cream);
}
.dev__site {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: #a99887;
}
.dev__site .ico {
  width: 0.85em;
  height: 0.85em;
}

.dev:hover .dev__face,
.dev:focus-visible .dev__face {
  box-shadow: 0 0 0 1.5px var(--gold);
}
.dev:hover .dev__name {
  color: var(--gold);
}
.dev:hover .dev__site {
  color: var(--gold-soft);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Said in words as well as drawn in an arrow. The icon is a convention, and a
   convention only works on people who have already met it. */
.devs__note {
  display: flex;
  align-items: flex-start;
  gap: 0.35rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.5;
  color: #8d7f72;
}
/* holds the arrow on the first line when the sentence wraps to two */
.devs__note .ico {
  margin-top: 0.18em;
}

/* for text that only the screen reader needs */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- the dock: the running total, carried ----------
   It stands in for the order card only while the card is still ahead of the
   reader — the checkout section carries data-cue-hide, which sets .is-away, so
   the dock neither floats on top of the panel it points at nor follows anyone
   down into the footer past it. Phones get it full-bleed in the thumb zone;
   wider screens get a leaf-cornered slip at the bottom-right. */
.dock {
  --r-a: var(--r-leaf);
  --r-b: 0px;
  position: fixed;
  z-index: 90;
  inset: auto clamp(1rem, 2.4vw, 1.75rem) clamp(1rem, 2.4vw, 1.75rem) auto;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  max-width: min(26rem, calc(100vw - 2rem));
  padding: 0.6rem 1rem;
  border-radius: var(--r-a) var(--r-b) var(--r-a) var(--r-b);
  background: var(--crimson);
  color: var(--cream);
  box-shadow: 0 20px 44px -18px rgba(20, 4, 6, 0.75);

  /* hidden state: visibility keeps it out of the tab order between orders, and
     is flipped only after the slide has finished */
  visibility: hidden;
  opacity: 0;
  translate: 0 132%;
  transition:
    translate 400ms var(--ease-out),
    opacity 180ms var(--ease-out),
    transform 200ms var(--ease-out),
    border-radius 220ms var(--ease-out),
    visibility 0s linear 400ms;
}
.dock.is-live:not(.is-away) {
  visibility: visible;
  opacity: 1;
  translate: 0 0;
  transition:
    translate 620ms var(--ease-out),
    opacity 260ms var(--ease-out),
    transform 200ms var(--ease-out),
    border-radius 220ms var(--ease-out),
    visibility 0s;
}
/* the same leaf flip every button on this page performs */
.dock:hover {
  --r-a: 0px;
  --r-b: var(--r-leaf);
  transform: translateY(-3px);
}
.dock:active {
  transform: translateY(0);
}

.dock__mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: var(--r-xs);
  background: rgba(253, 199, 82, 0.16);
  color: var(--gold);
}
.dock__mark .ico {
  width: 24px;
  height: 24px;
}

.dock__text {
  display: grid;
  gap: 0.05rem;
  line-height: 1.2;
  min-width: 0;
}
.dock__sum {
  display: inline-flex;
  align-items: baseline;
  gap: 0.22rem;
  transform-origin: left center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.2rem;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.dock__sum i {
  font: 800 0.6em/1 var(--font-text);
  font-style: normal;
  color: var(--on-crimson-2);
}
.dock__cap {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--on-crimson-2);
  white-space: nowrap;
}
.dock__cap b {
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}

.dock__go {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-inline-start: auto;
  padding-inline-start: 0.9rem;
  font-size: 0.875rem;
  font-weight: 800;
  white-space: nowrap;
}
.dock__go .ico {
  width: 17px;
  height: 17px;
  color: var(--gold);
  transition: translate 200ms var(--ease-out);
}
.dock:hover .dock__go .ico {
  translate: 3px 0;
}

/* the total is what moved, so the total is what answers a tap made further down
   the menu, where the row that changed is out of sight */
.dock.is-bump .dock__sum {
  animation: dock-bump 560ms var(--ease-out);
}
@keyframes dock-bump {
  0% {
    scale: 1;
    color: var(--gold);
  }
  22% {
    scale: 1.11;
    color: var(--gold-soft);
  }
  100% {
    scale: 1;
    color: var(--gold);
  }
}

@media (max-width: 720px) {
  .dock {
    --r-leaf: 0px;
    inset: auto 0 0 0;
    max-width: none;
    padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom));
    /* full-bleed is a much larger field than the slip — the deeper crimson keeps
       it from vibrating across the bottom of the screen */
    background: var(--crimson-dp);
    box-shadow: 0 -14px 34px -20px rgba(20, 4, 6, 0.85);
  }
  .dock:hover {
    transform: none;
  }
  body.has-dock {
    padding-bottom: 84px;
  }
}
@media (max-width: 400px) {
  .dock {
    gap: 0.6rem;
  }
  .dock__hint {
    display: none;
  }
  .dock__go {
    padding-inline-start: 0.5rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .dock {
    transition-delay: 0s !important;
  }
}

/* ---------- authored entrance ---------- */
.rise {
  animation: rise 700ms var(--ease-out) backwards;
  animation-delay: calc(var(--i, 0) * 90ms);
}
@keyframes rise {
  from {
    opacity: 0;
    translate: 0 18px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}
/* the photo settles inside its frame while the frame itself rises — two speeds, so the
   showcase arrives as an object rather than a pasted rectangle */
.showcase img {
  animation: settle 1000ms var(--ease-out) 220ms backwards;
}
@keyframes settle {
  from {
    opacity: 0;
    scale: 1.05;
    translate: 0 14px;
  }
  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}

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

/* ---------- image-slot placeholders (remove once ./images/ is filled) ---------- */
.is-missing {
  opacity: 0;
}
.slot--empty {
  position: relative;
  border: 2px dashed rgba(255, 247, 232, 0.4);
  border-radius: var(--r-md);
  filter: none;
}
.slot--empty::after {
  content: attr(data-slot);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font: 700 0.8125rem/1.4 var(--font-text);
  color: rgba(255, 247, 232, 0.75);
  letter-spacing: 0.02em;
  padding: 0.5rem 1rem;
  text-align: center;
}
