/* ═══════════════════════════════════════════════════════════════
   Maison Du Croissant
   Ground: their own forest green, not the cream every bakery defaults to.
   Structure: hairline gold rules and generous ruled lists. Lamination is not
   drawn as stacked stripes anywhere — it reads as a barcode, not as pastry.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* sampled from their logo: #003C30 is 73.5% of the mark */
  --green-900: #00201A;
  --green-800: #00281F;
  --green-700: #003C30;
  --green-600: #0B4B3D;
  --green-500: #17604F;

  /* ── the ground ──
     One base colour for the whole page, one fold-lattice printed on it, and
     sections that only TINT what is already there. Two things fall out of
     that: the lattice is never buried, and every boundary is transparent at
     both edges — so a seam cannot show a step no matter what sits either
     side of it. Continuity is structural, not something tuned. */
  --seam: #00281F;

  --gold-400: #E4CE96;
  --gold-500: #C9A961;
  --gold-600: #A8873F;

  --cream: #F4EFE4;
  --cream-dim: #C9C2B2;
  --ink: #12100C;

  /* Marhey carries character in the joins and terminals without giving up
     legibility the way a full ruq'ah hand does. Rubik is its Hebrew match —
     same geometric warmth, same softened corners. */
  --ff-latin: "Marcellus", Georgia, serif;
  --ff-ar-d: "Marhey", system-ui, sans-serif;
  --ff-ar-b: "IBM Plex Sans Arabic", system-ui, sans-serif;
  --ff-he-d: "Rubik", system-ui, sans-serif;
  --ff-he-b: "Frank Ruhl Libre", Georgia, serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --wrap: 1120px;
}

/* the two language skins swap only the faces — layout is RTL either way */
html[lang="ar"] { --ff-d: var(--ff-ar-d); --ff-b: var(--ff-ar-b); }
html[lang="he"] { --ff-d: var(--ff-he-d); --ff-b: var(--ff-he-b); }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body { overflow-x: clip; }

/* the fold lattice, printed once behind the whole page. Fixed, so the page
   scrolls over it the way paper moves across a bench. */
.grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.grain svg { display: block; width: 100%; height: 100%; }

body {
  background: var(--seam);
  color: var(--cream);
  font-family: var(--ff-b);
  font-weight: 300;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ol, ul { list-style: none; }

.wrap { width: min(100% - 44px, var(--wrap)); margin-inline: auto; }

/* ─────────── intro: the croissant proves, bakes, and is flown into ───────────
   It swells past its size and settles the way dough does under heat, the crust
   colours up, the wordmark sets, and then we fly through the belly and land on
   the page inside the coil — which is that same croissant's cut face.        */

.fold {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 30px;
  background: var(--green-900);
  transition: opacity 0.8s var(--ease), visibility 0.8s;
}

body.done .fold { visibility: hidden; }
body.no-motion.ready .fold { opacity: 0; visibility: hidden; }

/* the origin sits on the belly, so the fly-in heads into the body of the
   croissant rather than past it */
.fold-stage {
  display: grid;
  place-items: center;
  transform-origin: 50% 66%;
}

/* ── the handoff ──
   We fly into the finished croissant and come out inside its own cut face:
   the coil behind the hero IS that cross-section, so the zoom lands somewhere
   real instead of just wiping the screen. */
body:not(.no-motion).ready .fold-stage {
  will-change: transform;
  animation: flyIn 0.95s cubic-bezier(0.55, 0, 0.9, 0.45) forwards;
}

@keyframes flyIn { to { transform: scale(13); opacity: 0.08; } }

body:not(.no-motion).ready .fold-mark { animation: markOut 0.36s ease forwards; }

@keyframes markOut { to { opacity: 0; transform: translateY(8px) scale(0.97); } }

/* the ground drops away late, so the page is already showing as we arrive */
body:not(.no-motion).ready .fold { animation: foldFade 0.62s ease 0.34s forwards; }

@keyframes foldFade { to { opacity: 0; } }

.croi {
  width: min(66vw, 290px);
  height: auto;
  overflow: visible;
  color: var(--gold-400);
}

.croi-skin { opacity: 0; }
body:not(.no-motion) .croi-skin { animation: skinIn 1.1s var(--ease) 0.5s forwards; }
@keyframes skinIn { to { opacity: 1; } }

.croi-score {
  stroke: #6B4E1B;
  stroke-width: 2.4;
  stroke-linecap: round;
  opacity: 0.42;
  stroke-dasharray: 60;
  stroke-dashoffset: 60;
}

/* the scoring draws itself, middle first — the roll travelling outward */
body:not(.no-motion) .croi-score {
  animation: score 0.5s var(--ease) var(--d, 0s) forwards;
}

@keyframes score { to { stroke-dashoffset: 0; } }

/* it proves and then bakes: swells past its size, settles, and the colour
   comes up out of raw dough as the crust takes on heat */
body:not(.no-motion) .croi { animation: prove 2.3s var(--ease) forwards; }

@keyframes prove {
  0%   { transform: scale(0.6) rotate(-5deg); filter: saturate(0.35) brightness(1.34); }
  50%  { filter: saturate(0.72) brightness(1.16); }
  76%  { transform: scale(1.06) rotate(1.4deg); }
  100% { transform: scale(1) rotate(0deg); filter: saturate(1) brightness(1); }
}

/* their wordmark is a three-line stack, not a single line — MAISON over a
   ruled DU over CROISSANT. It sets itself in that order, each line opening
   its tracking as it lands, the way a stamp presses out. */
.fold-mark {
  display: grid;
  justify-items: center;
  gap: 10px;
  font-family: var(--ff-latin);
  color: var(--cream);
  text-transform: uppercase;
  direction: ltr;
}

.fm-rule {
  width: clamp(104px, 30vw, 148px);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-500) 22%, var(--gold-500) 78%, transparent);
  transform: scaleX(0);
}

.fm-line {
  --ls: 0.17em;
  font-size: clamp(17px, 5vw, 25px);
  letter-spacing: var(--ls);
  padding-inline-start: var(--ls);
  line-height: 1;
  opacity: 0;
  white-space: nowrap;
}

.fm-2 { --ls: 0.235em; font-size: clamp(14px, 4.1vw, 20px); }

.fm-du {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: clamp(9px, 2.4vw, 11px);
  letter-spacing: 0.34em;
  padding-inline-start: 0.34em;
  color: var(--gold-500);
  opacity: 0;
  line-height: 1;
}

.fm-du i { display: block; width: 15px; height: 1px; background: currentColor; }

body:not(.no-motion) .fm-rule   { animation: ruleOut 0.75s var(--ease) 1.12s forwards; }
body:not(.no-motion) .fm-rule-b { animation-delay: 1.74s; }
body:not(.no-motion) .fm-1      { animation: setLine 0.85s var(--ease) 1.26s forwards; }
body:not(.no-motion) .fm-du     { animation: setDu 0.7s var(--ease) 1.46s forwards; }
body:not(.no-motion) .fm-2      { animation: setLine 0.85s var(--ease) 1.56s forwards; }

@keyframes ruleOut { to { transform: scaleX(1); } }

@keyframes setLine {
  from { opacity: 0; letter-spacing: 0.01em; padding-inline-start: 0.01em; transform: translateY(7px); }
  to   { opacity: 1; letter-spacing: var(--ls); padding-inline-start: var(--ls); transform: none; }
}

@keyframes setDu {
  from { opacity: 0; gap: 0; }
  to   { opacity: 1; gap: 9px; }
}

/* ─────────── header ─────────── */

.head {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px clamp(16px, 4vw, 34px);
  background: rgba(0, 40, 31, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(201, 169, 97, 0.16);
}

.brand { display: flex; align-items: center; gap: 11px; margin-inline-end: auto; }

.brand-mark {
  font-family: var(--ff-latin);
  font-size: 12px;
  letter-spacing: 0.2em;
  padding: 7px 9px 6px;
  color: var(--gold-500);
  border: 1px solid rgba(201, 169, 97, 0.5);
}

.brand-name {
  font-family: var(--ff-latin);
  font-size: 14.5px;
  letter-spacing: 0.14em;
  line-height: 1;
  text-transform: uppercase;
}

.brand-name em { font-style: normal; color: var(--gold-500); padding-inline: 0.34em; }

/* when data.js carries a real logo file, the mark drops its type box and
   becomes the image — nothing else on the page has to change */
.brand-mark.has-logo, .foot-mark.has-logo {
  border: 0;
  padding: 0;
  display: block;
}

.brand-mark.has-logo img { display: block; height: 32px; width: auto; }
.foot-mark.has-logo img { display: block; height: 58px; width: auto; }

/* ── the counter rail ──
   Below 860px the nav links above are gone and nothing replaced them, so a
   phone had no navigation at all. The answer is not to squeeze the same links
   into a smaller bar: a phone is held at the bottom and read at the top, so
   the chrome moves down as you get into the page. The header retracts on the
   way down and this rises in its place — between them the middle of the screen
   is never touched, and there is only ever one bar on screen.

   It carries what the hero carries: the shop's live status, how far through
   the working day it is, and the two actions. Not a copy of the menu links —
   a copy of the hero, which is the part that mattered and the part that
   scrolled away. */

.counter {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 45;
  display: none;
  align-items: center;
  gap: 9px;
  padding: 10px clamp(14px, 4vw, 22px);
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  background: rgba(0, 40, 31, 0.92);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid rgba(201, 169, 97, 0.2);
  transform: translateY(103%);
  visibility: hidden;
  transition: transform 0.44s var(--ease), visibility 0.44s;
}

.counter.is-up { transform: none; visibility: visible; }

/* the day band again, at the width a rail can afford: the phrase, and a rule
   under it saying where in the day we are */
.counter-now { flex: 1 1 auto; min-width: 0; display: grid; gap: 6px; }

.counter-say {
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--cream);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* shut: the day is spent, so the rule reads as spent rather than as a full
   bar of gold, which is what a finished day would otherwise look like */
.counter.is-shut .counter-say { color: var(--cream-dim); }
.counter.is-shut .counter-track i { background: rgba(201, 169, 97, 0.3); }

.counter-track { position: relative; height: 1px; background: rgba(201, 169, 97, 0.22); }

.counter-track i {
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  height: 1px;
  background: var(--gold-500);
  transition: width 0.6s var(--ease);
}

.counter .btn { flex: none; }

/* the same cut piece, at the size a rail wants. The hover rule has to come
   after .btn:hover to win — they are the same specificity. */
.btn-sm { --cut: 11px; padding: 9px 15px; font-size: 13px; }
.btn-sm:hover, .btn-sm:active { --cut: 15px; }

@media (max-width: 859px) {
  .counter { display: flex; }
  .head { transition: transform 0.38s var(--ease); }
  /* only ever set on the home page — see watchHead in app.js */
  .head.is-away { transform: translateY(-102%); }
}

.head-nav { display: none; gap: 26px; font-size: 14px; }
.head-nav a { position: relative; padding-block: 4px; color: var(--cream-dim); transition: color 0.25s; }
.head-nav a:hover { color: var(--cream); }

.head-nav a::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 1px;
  background: var(--gold-500);
  transform: scaleX(0);
  transition: transform 0.3s var(--ease);
}

.head-nav a:hover::after { transform: scaleX(1); }

/* cut from the same sheet as the buttons, at the size this one wants */
.lang {
  --cut: 10px;
  flex: none;
  font-family: var(--ff-latin);
  font-size: 12px;
  letter-spacing: 0.1em;
  padding: 8px 14px;
  color: var(--gold-400);
  border: 1px solid transparent;
  background-origin: border-box;
  background-image: linear-gradient(225deg,
    transparent 0 var(--cut),
    rgba(201, 169, 97, 0.5) calc(var(--cut) + 0.5px) calc(var(--cut) + 1.3px),
    rgba(201, 169, 97, 0.12) calc(var(--cut) + 1.3px));
  transition: --cut 0.28s var(--ease), color 0.25s;
}

.lang:hover {
  --cut: 13px;
  color: var(--green-900);
  background-image: linear-gradient(225deg,
    transparent 0 var(--cut), var(--gold-500) calc(var(--cut) + 0.7px));
}

@media (min-width: 860px) { .head-nav { display: flex; } }

/* ─────────── shared type ─────────── */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ff-latin);
  font-size: 11px;
  letter-spacing: 0.28em;
  color: var(--gold-500);
  text-transform: uppercase;
}

.eyebrow .dot { width: 3px; height: 3px; background: currentColor; transform: rotate(45deg); flex: none; }

.sec-h {
  font-family: var(--ff-d);
  font-weight: 700;
  font-size: clamp(2rem, 6.4vw, 3.1rem);
  line-height: 1.34;
  margin-top: 10px;
}

.body { color: var(--cream-dim); font-size: 15.5px; max-width: 46ch; }
.sec-sub { margin-top: 12px; }

/* ─────────── hero ───────────
   The ground is the coil — a croissant's cut face, magnified until only the
   sweep of its outer turns crosses the frame, off to the side the type does
   not use.                                                                   */

.hero {
  position: relative;
  isolation: isolate;
  padding-block: clamp(20px, 3vh, 42px) clamp(40px, 7vh, 84px);
  overflow: hidden;
  /* a tint, not a ground: the lattice stays visible underneath, and both
     edges are fully transparent so the seams cannot step */
  background: linear-gradient(180deg,
    rgba(23, 96, 79, 0) 0%, rgba(23, 96, 79, 0.055) 46%, rgba(23, 96, 79, 0) 100%);
}

/* The centre sits off-frame: what we want across the hero is the sweep of the
   outer turns, not a bullseye parked behind the headline. */
.coil {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  inset-inline-end: -92%;
  top: 74%;
  width: min(235vw, 980px);
  aspect-ratio: 1;
  transform: translateY(-50%) scale(var(--cs, 1));
  transition: transform 1.9s var(--ease);
}

/* still oversized while the fold is up, so it settles as we land in it */
body:not(.ready):not(.no-motion) .coil { --cs: 1.55; }

.coil-svg { width: 100%; height: 100%; overflow: visible; }

.coil-dough { stroke: var(--gold-500); opacity: 0.115; }
.coil-butter { stroke: var(--cream); opacity: 0.05; }

/* the roll is made from the middle out, so that is how it draws */
body.ready .coil-dough { animation: unroll 3.4s var(--ease) 0.15s forwards; }
body.ready .coil-butter { animation: unroll 3.4s var(--ease) 0.35s forwards; }

@keyframes unroll { to { stroke-dashoffset: 0; } }

/* and it keeps turning, slowly enough that you feel it rather than watch it */
body:not(.no-motion).ready .coil-svg { animation: turn 150s linear 2s infinite; }

@keyframes turn { to { transform: rotate(360deg); } }

@media (min-width: 900px) {
  .coil { inset-inline-end: -42%; top: 70%; width: min(86vw, 1040px); }
}

/* the brand set on its edge, running the height of the frame */
.rail {
  position: absolute;
  inset-inline-start: clamp(6px, 2vw, 18px);
  top: 50%;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--ff-latin);
  font-size: 10px;
  letter-spacing: 0.4em;
  color: var(--gold-600);
  white-space: nowrap;
  writing-mode: vertical-rl;
  transform: translateY(-50%) rotate(180deg);
}

.rail-dot { width: 3px; height: 3px; background: currentColor; transform: rotate(45deg); }

.hero-in { position: relative; z-index: 1; width: min(100% - 74px, var(--wrap)); margin-inline: auto; }

/* the headline runs edge to edge in two ruled bands — the type itself is the
   cross-section, one turn of dough over the next */
.hero-h {
  position: relative;
  z-index: 1;
  font-family: var(--ff-d);
  font-weight: 700;
  font-size: clamp(2.2rem, 10.4vw, 4.8rem);
  line-height: 1.24;
  margin-top: 14px;
}

.hl {
  display: block;
  border-top: 1px solid rgba(201, 169, 97, 0.22);
  padding-block: clamp(12px, 2.4vh, 22px);
}

.hl:last-child { border-bottom: 1px solid rgba(201, 169, 97, 0.22); }

/* the lower turn sits on a fractionally warmer ground, the way butter reads
   against dough on a cut face — and it starts from the far edge, so the two
   bands cross the frame in opposite directions instead of stacking flush */
.hl-b { color: var(--gold-400); background: rgba(201, 169, 97, 0.045); }
.hl-b i { text-align: end; }

.hl i {
  font-style: normal;
  display: block;
  width: min(100% - 74px, var(--wrap));
  margin-inline: auto;
}

.hero-note { margin-top: 20px; color: var(--cream-dim); font-size: 16px; max-width: 38ch; }

.hero-act { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 28px; }

/* ── buttons ──
   Every croissant in this shop begins the same way: a rolled sheet, one pass
   of a blade, a triangle. So every tappable thing on this site is a piece cut
   from that sheet — the leading corner taken off at 45°, the ground showing
   through where the blade went. The silhouette carries the shop; nothing is
   added on top of it.

   The cut is on the top-RIGHT because both languages here are RTL, so that is
   the corner the eye arrives at. It is drawn as one gradient and not as a
   clip-path or a mask: either of those would take the base shadow and the
   focus ring with it, since both are painted outside the border box.

   Under each piece sits its base, a darker caramelised line. Press and the
   piece descends onto it — the base shortens to nothing as the button travels
   down. That is the affordance that survives on a phone, where nothing ever
   hovers, and a phone is what this site is mostly read on. */

@property --cut {
  syntax: "<length>";
  inherits: true;
  initial-value: 14px;
}

.btn {
  --cut: 14px;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
  font-weight: 500;
  padding: 13px 22px;
  border: 1px solid transparent; /* holds the metrics; the edge is the cut */
  background-origin: border-box;
  isolation: isolate;
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease),
              --cut 0.3s var(--ease), filter 0.25s, color 0.25s;
}

/* the blade goes deeper under the hand — and on the press itself, so a thumb
   gets the same answer a cursor does */
.btn:hover, .btn:active { --cut: 19px; }

/* over the ghost's wash, which blooms from the cut corner at z-index 0 */
.btn > * { position: relative; z-index: 1; }

/* baked: the crust runs from the cut face — the lightest, crispest edge, where
   it meets the dark ground — down into the mass, on the blade's own axis */
.btn-gold {
  color: var(--green-900);
  background-image: linear-gradient(225deg,
    transparent 0 var(--cut),
    #F0D6A0 calc(var(--cut) + 0.7px),
    #DEBA79 46%,
    #C9A961 100%);
  box-shadow: 0 2px 0 var(--gold-600);
}

.btn-gold:hover { transform: translateY(-2px); box-shadow: 0 4px 0 var(--gold-600); filter: brightness(1.05); }
.btn-gold:active { transform: translateY(2px); box-shadow: 0 0 0 var(--gold-600); }

/* raw: the same piece before the oven — a dim plate, with the blade's line
   still bright along the face it cut */
.btn-ghost {
  color: var(--cream);
  background-image: linear-gradient(225deg,
    transparent 0 var(--cut),
    rgba(201, 169, 97, 0.58) calc(var(--cut) + 0.5px) calc(var(--cut) + 1.4px),
    rgba(201, 169, 97, 0.13) calc(var(--cut) + 1.4px));
  box-shadow: 0 2px 0 rgba(201, 169, 97, 0.26);
}

/* gold enters where the blade did, and opens across the piece from there */
.btn-ghost::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 0;
  background-image: linear-gradient(225deg,
    transparent 0 var(--cut),
    rgba(201, 169, 97, 0.17) calc(var(--cut) + 0.7px));
  transform: scale(0);
  transform-origin: 100% 0;
  transition: transform 0.42s var(--ease);
}

.btn-ghost:hover { transform: translateY(-2px); box-shadow: 0 4px 0 rgba(201, 169, 97, 0.4); }
.btn-ghost:hover::before { transform: scale(1); }
.btn-ghost:active { transform: translateY(2px); box-shadow: 0 0 0 rgba(201, 169, 97, 0.4); }

/* keyboard gets the same clarity the pointer does */
.btn:focus-visible, .lang:focus-visible, .jump a:focus-visible {
  outline: 2px solid var(--gold-400);
  outline-offset: 3px;
}

/* the icon leans forward, which in a right-to-left line means left */
.btn svg { transition: transform 0.3s var(--ease); }
.btn:hover svg { transform: translateX(-2px); }

/* ── their day, edge to edge ──
   Not a status pill. The bakery's whole working day drawn as one rule, with a
   marker where the clock actually is, and copy that changes with the hour. */

.daybar {
  position: relative;
  z-index: 1;
  margin-top: clamp(38px, 7vh, 66px);
  padding-top: 20px;
  border-top: 1px solid rgba(201, 169, 97, 0.18);
}

.day-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  width: min(100% - 74px, var(--wrap));
  margin-inline: auto;
  margin-bottom: 15px;
}

/* Marcellus carries no Arabic or Hebrew, and letter-spacing pulls a joined
   Arabic word apart — so this label takes the display face, set plain */
.day-label {
  font-family: var(--ff-d);
  font-weight: 700;
  font-size: 13px;
  color: var(--gold-500);
  flex: none;
}

.day-say { font-size: 14.5px; color: var(--cream); }
.daybar.is-shut .day-say { color: var(--cream-dim); }

.day-band {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-inline: clamp(14px, 4vw, 30px);
}

.day-cap {
  flex: none;
  font-family: var(--ff-latin);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--gold-600);
  direction: ltr;
}

/* the track carries an hour tick every 1/15th of its width */
.day-track {
  position: relative;
  flex: 1;
  height: 30px;
  background-image: linear-gradient(90deg, rgba(201, 169, 97, 0.42) 0 1px, transparent 1px);
  background-size: calc(100% / 15) 9px;
  background-position: 0 50%;
  background-repeat: repeat-x;
}

.day-track::before,
.day-track::after {
  content: "";
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  height: 1px;
  background: rgba(201, 169, 97, 0.3);
}

.day-track::before { inset-inline: 0; }

/* the part of the day already spent, filled from the opening end */
.day-fill {
  position: absolute;
  top: 50%;
  inset-inline-start: 0;
  height: 2px;
  width: 0;
  margin-top: -1px;
  background: linear-gradient(90deg, var(--gold-600), var(--gold-400));
  transition: width 0.9s var(--ease);
}

.day-now {
  position: absolute;
  top: 50%;
  inset-inline-start: 0;
  width: 0;
  height: 0;
  transition: inset-inline-start 0.9s var(--ease);
}

.day-now i {
  position: absolute;
  top: -5px;
  inset-inline-start: -5px;
  width: 10px;
  height: 10px;
  background: var(--gold-400);
  transform: rotate(45deg);
  box-shadow: 0 0 0 0 rgba(228, 206, 150, 0.55);
}

.daybar:not(.is-shut) .day-now i { animation: nowPulse 2.6s ease-out infinite; }

@keyframes nowPulse {
  70% { box-shadow: 0 0 0 10px rgba(228, 206, 150, 0); }
  100% { box-shadow: 0 0 0 0 rgba(228, 206, 150, 0); }
}

/* shut for the day: the whole rule goes quiet */
.daybar.is-shut .day-fill { background: rgba(201, 169, 97, 0.3); }
.daybar.is-shut .day-now i { background: var(--cream-dim); opacity: 0.6; }
.daybar.is-shut .day-track { opacity: 0.55; }

@media (min-width: 900px) {
  .hero-in, .hl i { width: min(100% - 96px, var(--wrap)); }
  .day-head { width: min(100% - 96px, var(--wrap)); }
}

/* ─────────── image slots ─────────── */

figure[data-img] { position: relative; }

.ph {
  position: relative;
  display: grid;
  /* place-content, not place-items — otherwise the two rows each centre in
     their own track and the mark drifts away from its label */
  place-content: center;
  justify-items: center;
  gap: 10px;
  aspect-ratio: var(--ratio, 1);
  max-height: 60vh;
  background: var(--green-700);
  border: 1px solid rgba(201, 169, 97, 0.28);
}

.ph::before, .ph::after {
  content: "";
  position: absolute;
  width: 13px; height: 13px;
  border: 1px solid var(--gold-600);
}

.ph::before { top: 9px; inset-inline-start: 9px; border-width: 1px 0 0 1px; }
.ph::after { bottom: 9px; inset-inline-end: 9px; border-width: 0 1px 1px 0; }

html[dir="rtl"] .ph::before { border-width: 1px 1px 0 0; }
html[dir="rtl"] .ph::after { border-width: 0 0 1px 1px; }

.ph-mark {
  font-family: var(--ff-latin);
  font-size: 15px;
  letter-spacing: 0.3em;
  padding-inline-start: 0.3em;
  color: rgba(201, 169, 97, 0.75);
}

.ph-label {
  font-size: 12px;
  color: var(--cream-dim);
  opacity: 0.7;
  text-align: center;
  max-width: 22ch;
  padding-inline: 14px;
}

figure[data-img] img { width: 100%; aspect-ratio: var(--ratio, 1); object-fit: cover; }

/* ── the section mark ──
   A stack of rules was standing in for laminated dough. It read as a barcode.
   What sits here now is the loaf they actually make, drawn from their own
   photograph, set on a rule. It needs no explaining. */

.mark-rule {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 28px;
  max-width: 400px;
}

.mr-line { flex: 1; height: 1px; background: rgba(201, 169, 97, 0.3); }

/* sized by height, not width: a tall pastry and a wide one then sit level on
   the same rule instead of one dwarfing the other */
.mr-mark { flex: none; display: block; color: var(--gold-500); }
.mr-mark svg { display: block; height: 36px; width: auto; overflow: visible; }

.mr-body {
  fill: rgba(201, 169, 97, 0.16);
  stroke: currentColor;
  stroke-width: 4;
  stroke-linejoin: round;
}

/* fill:none matters — the swirl is an open path and would otherwise blot */
.mr-seam {
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  opacity: 0.5;
}

/* the whole mark is one gold, so a topping has to separate itself by weight
   of fill rather than by hue: cream lighter than the pastry, fruit solid */
.mr-cream {
  fill: rgba(228, 206, 150, 0.34);
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linejoin: round;
}

.mr-fruit { fill: currentColor; opacity: 0.9; }

/* centred under a heading rather than ranged from the start of the measure */
.mark-rule.is-mid { max-width: none; margin-inline: auto; }

/* sitting on the seam between two sections rather than inside one */
.seam-rule { margin-block: clamp(30px, 5vh, 46px); }

/* ─────────── home · a taste of the carte ───────────
   Category names and one line each, then a link out. The items are not
   repeated here: there is one menu and it lives at /menu/, which is what the
   QR code at the counter resolves to. Two copies would drift apart. */

.taste {
  position: relative;
  padding-block: clamp(56px, 11vh, 116px);
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0) 100%);
}

/* the rule marking the seam fades out at both ends rather than running wall
   to wall — a hard line across a soft ground undoes the softness */
.taste::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent,
    rgba(201, 169, 97, 0.26) 18%, rgba(201, 169, 97, 0.26) 82%, transparent);
}

/* ── the showcase rail ──
   Runs to the page edge rather than stopping at the measure, so the last tile
   is visibly cut and the rail reads as swipeable without being labelled. */
.shows {
  display: flex;
  gap: 12px;
  margin-top: clamp(26px, 4vh, 38px);
  padding-inline: max(22px, calc((100% - var(--wrap)) / 2));
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.shows::-webkit-scrollbar { display: none; }

.show {
  flex: none;
  scroll-snap-align: start;
  /* their reels are 9:16 — the tile takes that shape whatever lands in it */
  height: clamp(300px, 50vh, 430px);
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--green-700);
  border: 1px solid rgba(201, 169, 97, 0.22);
}

.show video, .show img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* a still that opens the reel it was taken from */
.show-link { display: block; position: relative; width: 100%; height: 100%; }

.show-link img { transition: transform 0.6s var(--ease); }
.show-link:hover img, .show-link:focus-visible img { transform: scale(1.04); }

/* says there is motion behind this frame, without covering it */
.show-cue {
  position: absolute;
  inset-inline-start: 10px;
  bottom: 10px;
  width: 26px;
  height: 26px;
  padding: 5px;
  color: var(--cream);
  background: rgba(0, 20, 15, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 50%;
  transition: background-color 0.25s;
}

.show-link:hover .show-cue { background: rgba(0, 20, 15, 0.8); }

.show .ph { height: 100%; aspect-ratio: auto; max-height: none; border: 0; }

/* four tiles at this height fill the measure almost exactly, so the rail sits
   as a block rather than trailing off into dead space */
@media (min-width: 880px) {
  .shows { gap: 16px; }
  .show { height: clamp(330px, 46vh, 424px); }
}

/* ── phone: one card at a time ──
   These are 9:16 clips and the phone is a 9:16 screen. A row of small
   thumbnails wastes exactly the format they were shot in, so on a phone the
   card takes most of the width, the next one peeks so the swipe needs no
   label, and the caption and position go underneath rather than over the
   picture. */

.shows-foot { display: none; }

@media (max-width: 879px) {
  .shows { gap: 10px; }

  .show {
    width: 76vw;
    height: auto;
    max-height: 70vh;          /* short screens clamp; object-fit still covers */
    scroll-snap-align: start;
  }

  /* the card you are on stands at full size; its neighbours fall back, so
     depth does the work a label would otherwise have to do */
  .show {
    transform: scale(0.92);
    opacity: 0.45;
    transition: transform 0.5s var(--ease), opacity 0.5s var(--ease);
  }

  .show.is-on { transform: none; opacity: 1; }

  /* the play cue belongs to the card you are actually looking at */
  .show .show-cue { opacity: 0; transition: opacity 0.4s var(--ease); }
  .show.is-on .show-cue { opacity: 1; }

  /* one continuous track, not a row of dots: the same device the day band
     draws for their working hours, filling as you move through the set */
  .shows-foot {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-top: 22px;
  }

  .shows-idx {
    flex: none;
    font-family: var(--ff-latin);
    font-size: 11.5px;
    letter-spacing: 0.16em;
    color: var(--gold-600);
    direction: ltr;
  }

  .shows-track {
    position: relative;
    flex: 1;
    height: 2px;
    background: rgba(201, 169, 97, 0.18);
  }

  .shows-fill {
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    width: 25%;
    background: linear-gradient(90deg, var(--gold-600), var(--gold-400));
    transition: width 0.2s linear;
  }
}

.taste-list { margin-top: 34px; border-top: 1px solid rgba(244, 239, 228, 0.09); }

.tst {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px 14px;
  padding-block: 17px;
  border-bottom: 1px solid rgba(244, 239, 228, 0.09);
}

.tst-name { font-family: var(--ff-d); font-weight: 700; font-size: 1.25rem; line-height: 1.4; }

.tst-en {
  align-self: center;
  font-family: var(--ff-latin);
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--gold-500);
  text-transform: uppercase;
  white-space: nowrap;
}

.tst-line { grid-column: 1 / -1; font-size: 14px; color: var(--cream-dim); }

.taste-act { margin-top: 30px; }

/* ─────────── the carte itself ───────────
   Used only by /menu/ now, but the classes stay generic so a category list can
   be dropped anywhere it is wanted. */

/* ── the spine ──
   The carte's headings are not above their categories, they are down the side
   of them. One rule runs the whole length of the page and every category hangs
   off it, its name set along the rule itself.

   That leaves exactly one structural line on the carte instead of four: the
   sections are divided vertically and the items horizontally, so the two kinds
   of division never have to compete for the same edge.

   And the name sticks. Someone at the counter scrolls a carte fast and loses
   track of which part of it they are in; the usual answer is a second sticky
   bar across the top, and vertical space is the one thing a phone held at
   arm's length has none of. Down the edge it costs nothing at all. */

.cats { margin-top: 40px; display: grid; gap: 46px; position: relative; --spine: 44px; }

/* drawn once, for the whole carte, and faded at both ends so it does not butt
   into the heading above it or the footer below */
.cats::before {
  content: "";
  position: absolute;
  inset-block: -10px 0;
  inset-inline-start: var(--spine);
  width: 1px;
  background: linear-gradient(180deg,
    rgba(201, 169, 97, 0) 0,
    rgba(201, 169, 97, 0.32) 46px,
    rgba(201, 169, 97, 0.32) calc(100% - 96px),
    rgba(201, 169, 97, 0) 100%);
}

.cat { display: grid; grid-template-columns: var(--spine) 1fr; }

.cat-body { padding-inline-start: 20px; min-width: 0; }

/* the stacked header measures 118.5px; this is that plus a breath.
   `direction: ltr` is not a mistake: once the writing mode is vertical the
   page's RTL becomes an instruction to stack these two bottom-to-top, which
   would put the Latin caption under the name instead of over it. The words
   themselves are single-script runs, so their own shaping is untouched. */
.spine-label {
  position: sticky;
  top: 133px;
  writing-mode: vertical-rl;
  direction: ltr;
  display: flex;
  align-items: center;
  gap: 13px;
  padding-block-start: 3px;
}

.spine-en {
  font-family: var(--ff-latin);
  font-size: 10.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-500);
}

.spine-name {
  font-family: var(--ff-d);
  font-weight: 700;
  font-size: 1.2rem;
  line-height: 1;
}

/* Where you are, on the rule itself. The carte is one long scroll and the
   category name alone tells you what you are reading but not how much of it
   is left; this is the same ruled track the day band and the reel rail use,
   stood on its end. It glides rather than jumps, because it is reporting a
   position and a position does not teleport. */
.cats-here {
  position: absolute;
  inset-inline-start: var(--spine);
  width: 1px;
  background: var(--gold-400);
  opacity: 0.92;
  pointer-events: none;
}

.cats-here.is-live { transition: top 0.55s var(--ease), height 0.55s var(--ease); }

.cat-fig { margin-top: 2px; }

.items { margin-top: 6px; }

.item {
  display: grid;
  gap: 2px;
  padding-block: 15px;
  border-bottom: 1px solid rgba(244, 239, 228, 0.08);
}

.item:last-child { border-bottom: 0; }

.item-top { display: flex; align-items: baseline; gap: 10px; }

.item-en {
  font-family: var(--ff-latin);
  font-size: 1.06rem;
  letter-spacing: 0.02em;
}

.item-note { font-size: 13.5px; color: var(--cream-dim); }

/* printed only when data.js carries a real number for the item */
.item-price {
  flex: none;
  margin-inline-start: auto;
  font-family: var(--ff-latin);
  font-size: 1rem;
  color: var(--gold-400);
  direction: ltr;
}

.item-draft {
  flex: none;
  font-family: var(--ff-latin);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  color: var(--gold-600);
  border: 1px solid rgba(168, 135, 63, 0.55);
  padding: 2px 7px;
  text-transform: uppercase;
}

.cat-note {
  margin-top: 14px;
  font-size: 12px;
  color: var(--gold-600);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* the rule can carry a longer name once there is room for it */
@media (min-width: 700px) {
  .cats { --spine: 58px; }
  .spine-name { font-size: 1.3rem; }
}

/* ─────────── home · catering ───────────
   A side offer, so it gets a band and not a section: what it is, who it is
   for, and the two ways to ask. */

/* No borders at all. It starts and ends on the seam and only deepens through
   its middle, so it still reads as a band without a line drawn round it. */
.cater {
  padding-block: clamp(36px, 6vh, 56px);
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.24) 50%, rgba(0, 0, 0, 0) 100%);
}

.cater-in { display: grid; gap: 22px; align-items: center; }

.cater-h { font-family: var(--ff-d); font-weight: 700; font-size: 1.5rem; line-height: 1.4; margin-top: 8px; }

.cater-copy .body { margin-top: 8px; }

/* who it is for, on one line */
.occas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  font-size: 13px;
  color: var(--gold-600);
}

.occas i { flex: none; width: 3px; height: 3px; background: currentColor; transform: rotate(45deg); }

.cater-act { display: flex; flex-wrap: wrap; gap: 11px; }

@media (min-width: 880px) {
  .cater-in { grid-template-columns: 1fr auto; gap: 44px; }
}

/* ─────────── home · where and when ───────────
   Address and opening hours were two sections saying one thing. */

/* No picture here: the showcase rail carries the page's images now, and this
   section is two short columns of fact. */
.visit {
  padding-block: clamp(56px, 11vh, 120px);
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0) 100%);
}

.visit-grid { display: grid; gap: 34px; }

.addr { font-family: var(--ff-d); font-weight: 700; font-size: 1.4rem; margin-top: 14px; line-height: 1.5; }

.place-act { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 26px; }

/* no border-top of its own — the mark-rule inside is the divider now */
.week-wrap .mark-rule { margin: 0 0 20px; }

.week-label { font-family: var(--ff-d); font-weight: 700; font-size: 1.05rem; }

@media (min-width: 880px) {
  .visit-grid { grid-template-columns: 1fr 1fr; gap: 60px; align-items: start; }
  .week-wrap { margin-top: 44px; }   /* sits level with the address, not the eyebrow */
}

/* the week */

.week { margin-top: 14px; max-width: 620px; }

.day {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding-block: 14px;
  border-bottom: 1px solid rgba(244, 239, 228, 0.08);
  color: var(--cream-dim);
  transition: color 0.25s;
}

.day-name { font-size: 15px; flex: none; }

.day-rule {
  flex: 1;
  align-self: center;
  height: 1px;
  background: repeating-linear-gradient(90deg, rgba(201,169,97,.36) 0 2px, transparent 2px 7px);
}

.day-time { font-family: var(--ff-latin); font-size: 14px; letter-spacing: 0.06em; flex: none; direction: ltr; }

.day.is-closed .day-time { color: var(--gold-600); }

.day.is-today { color: var(--cream); }
.day.is-today .day-name { font-weight: 600; }
.day.is-today .day-time { color: var(--gold-400); }

.day.is-today .day-name::before {
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  background: var(--gold-500);
  transform: rotate(45deg);
  margin-inline-end: 9px;
  vertical-align: middle;
}

/* ─────────── /menu/ · the QR carte ───────────
   Someone scanned a code at the counter to read a list. So: no intro, no
   images, one narrow column, and the categories on a rail they can thumb
   along. The rail lives inside the sticky header rather than sticking
   underneath it, which keeps the two from needing to agree on a height. */

.head-stack { display: block; padding: 0; }

.head-stack .head-top {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 13px clamp(16px, 4vw, 34px);
}

.jump {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 0 clamp(16px, 4vw, 34px) 12px;
}

.jump::-webkit-scrollbar { display: none; }

/* the same cut again, smallest of the three — four of these sit in a row, so
   the corner has to register without the rail turning into sawteeth */
.jump a {
  --cut: 9px;
  flex: none;
  font-size: 14px;
  padding: 7px 15px;
  color: var(--cream-dim);
  border: 1px solid transparent;
  background-origin: border-box;
  background-image: linear-gradient(225deg,
    transparent 0 var(--cut),
    rgba(201, 169, 97, 0.4) calc(var(--cut) + 0.5px) calc(var(--cut) + 1.2px),
    rgba(201, 169, 97, 0.1) calc(var(--cut) + 1.2px));
  transition: --cut 0.24s var(--ease), color 0.2s;
}

.jump a:hover, .jump a:focus-visible {
  --cut: 12px;
  color: var(--cream);
}

/* a carte is read a category at a time — one column, and a narrower measure */
.page-menu .wrap { width: min(100% - 44px, 640px); }
.page-menu .cats { grid-template-columns: 1fr; margin-top: 32px; gap: 40px; }

/* a band, not a portrait: the source stays 4:5 so the crop can change later,
   but a full-height photo per category would triple the length of the carte */
.page-menu .cat-fig img { aspect-ratio: 16 / 10; }
/* clears the stacked header (measures 119px) with room to breathe above the
   heading — too little and a jump lands the category name under the rail */
.page-menu .cat { scroll-margin-top: 136px; }

.mpage { padding-block: clamp(28px, 5vh, 46px) clamp(48px, 8vh, 78px); }

.mtitle { font-family: var(--ff-d); font-weight: 700; font-size: clamp(1.9rem, 8vw, 2.6rem); line-height: 1.3; }

.mnote { margin-top: 8px; font-size: 14px; color: var(--cream-dim); }

.mfoot {
  position: relative;
  padding-block: clamp(34px, 6vh, 54px);
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.46) 100%);
}

.mfoot::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent,
    rgba(201, 169, 97, 0.28) 18%, rgba(201, 169, 97, 0.28) 82%, transparent);
}

.mfoot .wrap { display: grid; justify-items: center; text-align: center; gap: 16px; }

.mfoot-say { font-size: 14.5px; color: var(--cream); }
.mfoot.is-shut .mfoot-say { color: var(--cream-dim); }
.mfoot-addr { font-size: 13px; color: var(--gold-600); }

/* ─────────── footer ─────────── */

.foot {
  position: relative;
  padding-block: clamp(54px, 9vh, 96px);
  /* asymmetric on purpose: nothing follows, so it can keep going down */
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.46) 100%);
}

.foot::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent,
    rgba(201, 169, 97, 0.28) 18%, rgba(201, 169, 97, 0.28) 82%, transparent);
}

.foot-in { display: grid; justify-items: center; text-align: center; gap: 4px; }

.foot-mark {
  font-family: var(--ff-latin);
  font-size: 15px;
  letter-spacing: 0.32em;
  padding: 11px 13px 10px;
  padding-inline-start: calc(13px + 0.32em);
  color: var(--gold-500);
  border: 1px solid rgba(201, 169, 97, 0.45);
  margin-bottom: 18px;
}

.foot-name { font-family: var(--ff-latin); font-size: 17px; letter-spacing: 0.16em; text-transform: uppercase; }
.foot-tag { color: var(--cream-dim); font-size: 14px; }
.foot-act { display: flex; flex-wrap: wrap; gap: 11px; justify-content: center; margin-top: 24px; }
.foot-since { margin-top: 26px; font-size: 12px; color: var(--gold-600); }

/* ─────────── reveal ─────────── */

.rise { opacity: 0; transform: translateY(20px); }
body.ready .rise { animation: rise 0.8s var(--ease) var(--d, 0s) forwards; }

@keyframes rise { to { opacity: 1; transform: none; } }

.reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001s !important; transition-duration: 0.001s !important; }
  .rise, .reveal { opacity: 1; transform: none; }
  .coil-dough, .coil-butter { stroke-dashoffset: 0 !important; }
}
