/* ==========================================================================
   CURRY MILE — British Indian. Delivered.
   Velare · build 2026-08-20
   Direction: dark / charcoal, warm white, sparing gold. Cinematic, editorial.
   ==========================================================================
   ONE-LINE SWAPS when the client sends brand assets:
     --gold   → their exact brand gold
     --display / --sans → their chosen typefaces
   ========================================================================== */

:root{
  /* charcoal & black tones — deliberately NOT pure #000 */
  --black:#0A0A0A;
  --charcoal:#121211;      /* page ground */
  --charcoal-2:#191817;    /* raised surface */
  --charcoal-3:#211F1D;    /* hover / inset */
  --warm-white:#F2EEE7;
  --muted:#B0A99D;
  --muted-2:#8C867B;

  /* gold — used sparingly: hairlines, nav states, small details */
  --gold:#B08F4A;
  --gold-dim:rgba(176,143,74,.38);
  --gold-faint:rgba(176,143,74,.16);
  --hair:rgba(242,238,231,.13);
  --hair-soft:rgba(242,238,231,.07);

  /* Headings and body share one typeface — headings are simply larger and lighter.
     Swap --display alone to reintroduce a separate display face. */
  --sans:'Jost',-apple-system,BlinkMacSystemFont,'Helvetica Neue',Arial,sans-serif;
  --display:'Jost',-apple-system,BlinkMacSystemFont,'Helvetica Neue',Arial,sans-serif;

  --ease:cubic-bezier(.22,.61,.36,1);
  --slow:1.1s;
  --maxw:1280px;
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{
  font-family:var(--sans);
  background:var(--charcoal);
  color:var(--warm-white);
  font-size:17.5px;
  line-height:1.72;
  font-weight:300;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--gold);color:var(--black)}

.container{max-width:var(--maxw);margin:0 auto;padding:0 clamp(22px,5vw,64px)}
.narrow{max-width:820px}

/* ---------- type ---------- */
h1,h2,h3{font-family:var(--display);font-weight:300;line-height:1.14;letter-spacing:.004em}
.statement{
  font-family:var(--sans);
  /* 400 was the only weight above 300 in this part of the page and read
     heavy against it; widely tracked caps carry on their own. */
  font-weight:300;
  text-transform:uppercase;
  letter-spacing:.34em;
  line-height:1.5;
}
.eyebrow{
  font-family:var(--sans);
  font-size:12.5px;font-weight:400;
  text-transform:uppercase;letter-spacing:.4em;
  color:var(--gold);
}
.kicker{
  font-family:var(--sans);
  font-size:12.5px;font-weight:400;
  text-transform:uppercase;letter-spacing:.38em;
  color:var(--muted-2);
}
p{color:var(--muted);font-weight:400;letter-spacing:.004em}
p.lead{color:var(--warm-white);font-size:clamp(18px,1.7vw,21px);line-height:1.75}

/* ---------- subtle reveal (no bounce, no fly-in) ---------- */
.reveal{opacity:0;transform:translateY(18px);transition:opacity var(--slow) var(--ease),transform var(--slow) var(--ease)}
.reveal.in{opacity:1;transform:none}
.reveal.d1{transition-delay:.10s}.reveal.d2{transition-delay:.20s}
.reveal.d3{transition-delay:.30s}.reveal.d4{transition-delay:.40s}
@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
  html{scroll-behavior:auto}
}

/* ---------- header ---------- */
header.site{
  position:fixed;top:0;left:0;right:0;z-index:900;
  padding:26px 0;
  transition:background .5s var(--ease),padding .5s var(--ease),border-color .5s var(--ease);
  border-bottom:1px solid transparent;
}
header.site.stuck{
  background:rgba(10,10,10,.82);
  backdrop-filter:saturate(1.2) blur(14px);
  -webkit-backdrop-filter:saturate(1.2) blur(14px);
  padding:16px 0;
  border-bottom-color:var(--hair-soft);
}
header.site .bar{display:flex;align-items:center;justify-content:space-between;gap:32px}
.wordmark{display:flex;align-items:center}
.wordmark img{height:30px;width:auto}
.wordmark.sm img{height:46px}

.nav{display:flex;align-items:center;gap:clamp(20px,2.6vw,38px);list-style:none}
.nav a{
  font-size:12.5px;text-transform:uppercase;letter-spacing:.22em;font-weight:400;
  color:var(--warm-white);padding:8px 0;position:relative;opacity:.9;
  transition:opacity .35s var(--ease),color .35s var(--ease);
}
.nav a::after{
  content:"";position:absolute;left:0;right:100%;bottom:2px;height:1px;
  background:var(--gold);transition:right .45s var(--ease);
}
.nav a:hover{opacity:1}
.nav a:hover::after,.nav a.active::after{right:0}
.nav a.active{color:var(--gold);opacity:1}

.nav-order{
  font-size:12.5px;text-transform:uppercase;letter-spacing:.24em;
  border:1px solid var(--gold-dim);color:var(--gold);
  padding:11px 22px;transition:background .4s var(--ease),border-color .4s var(--ease);
}
.nav-order:hover{background:var(--gold-faint);border-color:var(--gold)}

.burger{display:none;width:26px;height:16px;position:relative}
.burger span{position:absolute;left:0;right:0;height:1px;background:var(--warm-white);transition:.35s var(--ease)}
.burger span:nth-child(1){top:0}.burger span:nth-child(2){top:50%}.burger span:nth-child(3){bottom:0}
body.menu-open .burger span:nth-child(1){top:50%;transform:rotate(45deg)}
body.menu-open .burger span:nth-child(2){opacity:0}
body.menu-open .burger span:nth-child(3){bottom:auto;top:50%;transform:rotate(-45deg)}

.drawer{
  position:fixed;inset:0;z-index:880;background:var(--black);
  display:flex;flex-direction:column;justify-content:center;gap:6px;
  padding:0 clamp(22px,7vw,64px);
  opacity:0;visibility:hidden;transition:opacity .5s var(--ease),visibility .5s;
}
body.menu-open .drawer{opacity:1;visibility:visible}
.drawer a{
  font-family:var(--display);font-weight:300;font-size:clamp(28px,7vw,44px);
  padding:12px 0;border-bottom:1px solid var(--hair-soft);color:var(--warm-white);
}
.drawer a:last-child{border-bottom:0;color:var(--gold)}

/* ---------- cinematic hero ---------- */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;overflow:hidden}
.hero.short{min-height:74svh}
.hero .bg{
  position:absolute;inset:0;background-size:cover;background-position:center;
  transform:scale(1.04);
  animation:drift 26s var(--ease) forwards;
  /* the charcoal treatment the brief asks for: deepen and desaturate the plate,
     keep the food warm and legible */
  filter:brightness(.60) saturate(.86) contrast(1.08);
}
@keyframes drift{to{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.hero .bg{animation:none;transform:none}}
/* the "dark/charcoal treatment" from the brief: desaturate + deepen, keep food warm */
.hero .grade{
  position:absolute;inset:0;
  background:
    linear-gradient(to right,rgba(10,10,10,.86) 0%,rgba(10,10,10,.5) 42%,rgba(10,10,10,.34) 100%),
    linear-gradient(to top,rgba(10,10,10,.96) 0%,rgba(10,10,10,.55) 38%,rgba(10,10,10,.34) 66%,rgba(10,10,10,.78) 100%),
    radial-gradient(120% 90% at 50% 58%,rgba(10,10,10,0) 0%,rgba(10,10,10,.6) 100%);
}
.hero .container{position:relative;z-index:2;width:100%}

/* ---------- steam rising off the dish ----------
   Sits above the photograph and its scrim, below the copy. Pure CSS: five
   blurred plumes on long, staggered, offset cycles so it never visibly loops.
   Deliberately slow — the brief asks for movement that is felt, not watched. */
.steam{
  position:absolute;z-index:1;pointer-events:none;
  left:52%;top:3%;
  width:min(500px,48vw);height:34%;
  transform:translateX(-50%);
}
.steam span{
  position:absolute;bottom:0;
  width:52%;height:52%;
  border-radius:50%;
  background:radial-gradient(closest-side,
    rgba(255,251,244,.62),
    rgba(255,249,240,.24) 50%,
    rgba(255,249,240,0) 76%);
  filter:blur(15px);
  opacity:0;
  will-change:transform,opacity;
  animation:steam-rise 13s ease-out infinite;
}
.steam span:nth-child(1){left:8%; animation-delay:0s;   animation-duration:13s}
.steam span:nth-child(2){left:30%;width:62%;height:62%;animation-delay:2.6s; animation-duration:15s}
.steam span:nth-child(3){left:50%;animation-delay:5.2s; animation-duration:12s}
.steam span:nth-child(4){left:20%;width:44%;height:44%;animation-delay:7.8s; animation-duration:16s}
.steam span:nth-child(5){left:40%;animation-delay:10.4s;animation-duration:14s}
@keyframes steam-rise{
  0%   {transform:translate3d(0,16%,0) scale(.42);opacity:0}
  12%  {opacity:.55}
  45%  {transform:translate3d(-14px,-68%,0) scale(1.05);opacity:.34}
  100% {transform:translate3d(12px,-190%,0) scale(1.6);opacity:0}
}
@media (prefers-reduced-motion:reduce){.steam{display:none}}
@media (max-width:860px){.steam{width:min(310px,66vw);top:2%;height:26%}}

/* ---------- homepage: city gateway ---------- */
.gateway{min-height:100svh;display:flex;flex-direction:column;position:relative;overflow:hidden}
.gateway .bg{
  position:absolute;inset:0;background-size:cover;background-position:center;
  transform:scale(1.05);animation:drift 30s var(--ease) forwards;
  filter:brightness(.62) saturate(.86) contrast(1.08);
}
.gateway .grade{
  position:absolute;inset:0;
  background:
    linear-gradient(to bottom,rgba(10,10,10,.9) 0%,rgba(10,10,10,.42) 24%,rgba(10,10,10,.5) 58%,rgba(10,10,10,.94) 100%),
    radial-gradient(100% 74% at 50% 52%,rgba(10,10,10,0) 0%,rgba(10,10,10,.72) 100%);
}
.gateway .top,.gateway .mid,.gateway .base{position:relative;z-index:2}
.gateway .top{padding:34px 0}
.gateway .mid{flex:1;display:flex;flex-direction:column;justify-content:center;text-align:center;padding:40px 0}
.gateway .base{padding:0 0 40px;text-align:center}

.brand-statement{
  font-family:var(--sans);font-weight:300;
  font-size:clamp(23px,4.5vw,52px);
  text-transform:uppercase;letter-spacing:.3em;
  line-height:1.42;
  margin-bottom:clamp(38px,6vw,64px);
}
.brand-statement em{font-style:normal;color:var(--gold)}
.prompt{
  font-family:var(--display);font-weight:300;
  font-size:clamp(16px,2.05vw,23px);letter-spacing:.06em;color:var(--muted);
  margin-bottom:clamp(30px,4.5vw,52px);
}

.cities{max-width:640px;margin:0 auto;width:100%}
.city{
  display:flex;align-items:center;gap:22px;
  padding:26px 4px 20px;
  border-bottom:1px solid var(--hair);
  position:relative;
  transition:border-color .6s var(--ease);
}
.city:first-child{border-top:1px solid var(--hair)}
.city .name{
  flex:0 0 auto;
  font-family:var(--sans);font-weight:300;
  font-size:clamp(20px,3.4vw,32px);
  text-transform:uppercase;letter-spacing:.24em;
  transition:color .6s var(--ease),letter-spacing .6s var(--ease);
}
.city .rule{flex:1;height:1px;background:var(--hair);position:relative;overflow:hidden}
.city .rule::after{
  content:"";position:absolute;inset:0;background:var(--gold);
  transform:scaleX(0);transform-origin:left;transition:transform .7s var(--ease);
}
.city .arrow{
  flex:0 0 auto;width:42px;height:42px;border-radius:50%;
  border:1px solid var(--hair);
  display:grid;place-items:center;
  transition:border-color .6s var(--ease),background .6s var(--ease),transform .6s var(--ease);
}
.city .arrow svg{width:14px;height:14px;stroke:var(--warm-white);transition:stroke .6s var(--ease)}
.city .tag{
  position:absolute;right:60px;bottom:22px;
  font-size:10px;letter-spacing:.34em;text-transform:uppercase;color:var(--gold);
}
.city:hover{border-bottom-color:var(--gold-dim)}
.city:hover .name{color:var(--gold);letter-spacing:.28em}
.city:hover .rule::after{transform:scaleX(1)}
.city:hover .arrow{border-color:var(--gold);background:var(--gold-faint);transform:translateX(5px)}
.city:hover .arrow svg{stroke:var(--gold)}

.signature{
  display:inline-block;
  font-size:12px;text-transform:uppercase;letter-spacing:.6em;
  color:var(--muted);opacity:.9;
}

/* ---------- sections ---------- */
.section{padding:clamp(76px,10vw,140px) 0}
.section.tight{padding:clamp(60px,7.5vw,104px) 0}
.section.dark2{background:var(--charcoal-2)}
.rule-top{border-top:1px solid var(--hair-soft)}
.sec-head{margin-bottom:clamp(40px,5vw,68px)}
.sec-head.center{text-align:center;margin-left:auto;margin-right:auto;max-width:720px}
.sec-head h2{font-size:clamp(36px,5.8vw,72px);margin-top:16px}
.sec-head p{margin-top:18px;max-width:580px;font-size:18px}
.sec-head.center p{margin-left:auto;margin-right:auto}

/* ---------- ordering ---------- */
.order-direct{
  border:1px solid var(--gold-dim);
  background:linear-gradient(180deg,rgba(176,143,74,.08),rgba(176,143,74,.03));
  padding:clamp(30px,4.4vw,52px);
  display:flex;align-items:center;justify-content:space-between;gap:32px;flex-wrap:wrap;
}
.order-direct .t{display:flex;flex-direction:column;gap:12px}
.order-direct .t b{
  font-family:var(--sans);font-weight:400;
  font-size:clamp(20px,2.6vw,30px);
  text-transform:uppercase;letter-spacing:.28em;color:var(--warm-white);
}
.order-direct .t span{font-size:14.5px;text-transform:uppercase;letter-spacing:.3em;color:var(--gold)}
.btn-gold{
  display:inline-flex;align-items:center;gap:14px;
  border:1px solid var(--gold);color:var(--gold);
  padding:17px 36px;font-size:13px;text-transform:uppercase;letter-spacing:.28em;
  transition:background .45s var(--ease),color .45s var(--ease);
  white-space:nowrap;
}
.btn-gold:hover{background:var(--gold);color:var(--black)}
.btn-gold svg{width:13px;height:13px;stroke:currentColor}
.btn-line{
  display:inline-flex;align-items:center;gap:14px;
  font-size:13px;text-transform:uppercase;letter-spacing:.28em;color:var(--warm-white);
  /* was inheriting 300 from the body. Jane asked for this heavier; 500 reads
     as emphasis at 13px with .28em tracking without going blocky. */
  font-weight:500;
  padding-bottom:10px;border-bottom:1px solid var(--gold-dim);
  transition:color .45s var(--ease),border-color .45s var(--ease),gap .45s var(--ease);
}
.btn-line:hover{color:var(--gold);border-color:var(--gold);gap:20px}
.btn-line svg{width:13px;height:13px;stroke:currentColor}

.partners{margin-top:34px}
.partners .lbl{font-size:12px;text-transform:uppercase;letter-spacing:.4em;color:var(--muted-2);margin-bottom:20px}
.partner-row{display:flex;flex-wrap:wrap;border-top:1px solid var(--hair-soft)}
.partner{
  flex:1 1 0;min-width:150px;
  padding:26px 8px;text-align:center;
  border-bottom:1px solid var(--hair-soft);border-right:1px solid var(--hair-soft);
  font-size:14px;text-transform:uppercase;letter-spacing:.26em;color:var(--warm-white);opacity:.86;
  transition:color .45s var(--ease),opacity .45s var(--ease),background .45s var(--ease);
}
.partner:last-child{border-right:0}
.partner:hover{color:var(--gold);opacity:1;background:rgba(200,167,91,.045)}
.partner small{display:block;margin-top:8px;font-size:11px;letter-spacing:.3em;color:var(--muted-2)}

/* ---------- popular dishes (editorial strip) ---------- */
.dishes{display:grid;grid-template-columns:repeat(6,1fr);gap:14px}
.dish{position:relative;display:block;overflow:hidden;background:var(--black);grid-column:span 2}
.dish:nth-child(4),.dish:nth-child(5){grid-column:span 3}
/* 4:3 matches the source photography, so the frame shows the dish, not a slice of it.
   The two wider tiles go 16:10 so both rows sit at a similar height. */
.dish .ph{display:block;aspect-ratio:4/3;overflow:hidden}
.dish:nth-child(4) .ph,.dish:nth-child(5) .ph{aspect-ratio:16/10}
.dish img{
  width:100%;height:100%;object-fit:cover;
  filter:saturate(.94) contrast(1.06) brightness(.8);
  transform:scale(1.02);
  transition:transform 1.4s var(--ease),filter 1.4s var(--ease);
}
.dish:hover img{transform:scale(1.07);filter:saturate(1) contrast(1.06) brightness(.92)}
.dish .veil{position:absolute;inset:0;background:linear-gradient(to top,rgba(10,10,10,.92) 0%,rgba(10,10,10,.06) 58%)}
.dish .cap{position:absolute;left:0;right:0;bottom:0;padding:26px 24px 28px}
.dish .cap b{
  display:block;font-family:var(--sans);font-weight:400;font-size:15px;line-height:1.4;
  text-transform:uppercase;letter-spacing:.2em;
}
.dish .cap i{
  display:block;width:26px;height:1px;background:var(--gold);margin-top:14px;font-style:normal;
  transition:width .7s var(--ease);
}
.dish:hover .cap i{width:64px}

/* ---------- numbers ---------- */
.numbers{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--hair-soft);border-bottom:1px solid var(--hair-soft)}
.num{padding:clamp(34px,4.4vw,54px) 24px;border-right:1px solid var(--hair-soft);text-align:center}
.num:last-child{border-right:0}
/* The figure carried font-weight twice — 400 then 300, so 300 quietly won.
   One declaration now, at 600. */
.num b{
  display:block;font-family:var(--display);
  font-size:clamp(25px,3.3vw,42px);font-weight:400;color:var(--gold);
  /* set in caps — which is how the brief itself writes these four figures.
     Caps at this size need a touch more tracking or they set too tight. */
  text-transform:uppercase;letter-spacing:.07em;white-space:nowrap;
}
.num span{display:block;margin-top:14px;font-size:12.5px;text-transform:uppercase;letter-spacing:.28em;color:var(--muted-2);line-height:1.9}

/* ---------- ratings / social proof ---------- */
.ratings{display:flex;flex-wrap:wrap;justify-content:center;gap:0}
.rating{
  flex:1 1 0;min-width:180px;text-align:center;padding:34px 20px;
  border-right:1px solid var(--hair-soft);
}
.rating:last-child{border-right:0}
.rating b{
  display:flex;align-items:baseline;justify-content:center;gap:9px;
  font-family:var(--display);font-size:clamp(25px,3.3vw,40px);font-weight:300;letter-spacing:.03em;white-space:nowrap;
}
.rating b .st{color:var(--gold);font-family:var(--sans);font-size:.5em;line-height:1}
.rating span{display:block;margin-top:13px;font-size:12px;text-transform:uppercase;letter-spacing:.34em;color:var(--muted-2)}

/* ---------- about split ---------- */
.split{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(36px,6vw,86px);align-items:center}
.split .ph{position:relative;overflow:hidden}
.split .ph img{width:100%;aspect-ratio:4/3.4;object-fit:cover;filter:saturate(.92) contrast(1.05) brightness(.84)}
.split h2{font-size:clamp(33px,4.8vw,58px)}
.split .body{display:flex;flex-direction:column;gap:22px}

/* ---------- final CTA ---------- */
/* The finale carries a supplied photograph of the kitchen (2026-09-06).
   Two things were asked of it: show the WHOLE frame, and lighten the
   overlay so the picture actually reads.

   Full frame: background-size is `contain`, not `cover`, so the image is
   never cropped whatever shape the band takes, with the charcoal ground
   showing if the band is wider than 16:9. On desktop the band is also given
   the photograph's own 16:9 height, so in practice contain fills it edge to
   edge and no ground shows at all.

   Overlay: the darkening used to come from TWO stacked sources — a
   brightness(.55) filter on the image AND a .92/.70/.96 gradient over it.
   Together they measured 16.7:1 behind the heading, which is another way of
   saying the photograph was invisible. Both are eased. The values below are
   the lightest that still clear WCAG on the small button text, which is the
   binding constraint here, not the big heading. */
.finale{position:relative;min-height:78svh;display:flex;align-items:center;text-align:center;overflow:hidden}
@media (min-width:901px){
  .finale{min-height:min(56.25vw,88vh)}   /* 16:9 — the photograph's own shape */
}
.finale .bg{
  position:absolute;inset:0;
  background-size:contain;background-repeat:no-repeat;background-position:center;
  background-color:#0A0A0A;
  filter:brightness(.82) saturate(.94) contrast(1.04);
}
.finale .grade{
  position:absolute;inset:0;
  background:linear-gradient(to bottom,rgba(10,10,10,.52),rgba(10,10,10,.26) 45%,rgba(10,10,10,.62));
}
.finale .container{position:relative;z-index:2}
.finale h2{font-size:clamp(38px,6.8vw,86px);letter-spacing:.01em}

/* ---------- notify (Abu Dhabi) ---------- */
.notify{border:1px solid var(--hair);padding:clamp(30px,4.4vw,54px);background:var(--charcoal-2)}
.notify h3{font-size:clamp(24px,3.2vw,36px);margin:16px 0 16px}
.notify p{max-width:520px}
.nform{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
.nform input{
  flex:1 1 260px;background:transparent;border:0;border-bottom:1px solid var(--hair);
  color:var(--warm-white);padding:15px 2px;font-family:var(--sans);font-size:16.5px;font-weight:300;
  transition:border-color .4s var(--ease);
}
.nform input::placeholder{color:var(--muted-2);text-transform:uppercase;letter-spacing:.14em;font-size:13px}
.nform input:focus{outline:none;border-bottom-color:var(--gold)}
.nform .err{flex-basis:100%;font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:#D98A6A;display:none}
.nform.bad .err{display:block}
.notify .ok{display:none;margin-top:22px;font-size:13.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--gold)}
.notify.sent .ok{display:block}
.notify.sent .nform{display:none}

/* ---------- badge ---------- */
.badge{
  display:inline-block;margin-bottom:22px;
  border:1px solid var(--gold);color:var(--gold);
  background:rgba(200,167,91,.10);
  padding:10px 22px;font-size:11.5px;text-transform:uppercase;letter-spacing:.38em;
}

/* ---------- menu page ---------- */
.menu-note{border-left:1px solid var(--gold-dim);padding-left:24px;max-width:660px;font-size:16px;line-height:1.7}
.tabs{position:sticky;top:0;z-index:800;background:rgba(10,10,10,.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--hair-soft);border-bottom:1px solid var(--hair-soft)}
.tabs .container{display:flex;gap:0;overflow-x:auto;scrollbar-width:none}
.tabs .container::-webkit-scrollbar{display:none}
.tab{
  padding:20px 26px 18px;white-space:nowrap;
  font-size:12.5px;text-transform:uppercase;letter-spacing:.2em;font-weight:400;color:var(--muted-2);
  border-bottom:1px solid transparent;transition:color .4s var(--ease),border-color .4s var(--ease);
}
.tab:hover{color:var(--warm-white)}
.tab.active{color:var(--gold);border-bottom-color:var(--gold)}

.menu-cat{padding:clamp(56px,7vw,92px) clamp(22px,5vw,64px) 0}
.menu-cat .head{display:flex;align-items:baseline;gap:20px;margin-bottom:12px}
/* the brief asks for light, refined category headings rather than the
   heavy weight that made the menu feel like a different brand */
.menu-cat h2{font-size:clamp(30px,4.4vw,52px);font-weight:200;letter-spacing:.012em}
.menu-cat .line{flex:1;height:1px;background:var(--hair-soft)}
.cat-note{max-width:640px;font-size:16px;line-height:1.7;margin-bottom:44px}
.menu-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(30px,5vw,72px)}
.mi{
  display:flex;align-items:flex-start;justify-content:space-between;gap:24px;
  width:100%;text-align:left;padding:24px 0;border-bottom:1px solid var(--hair-soft);
  transition:border-color .4s var(--ease);
}
.mi:hover{border-bottom-color:var(--gold-dim)}
.mi .n{display:block;font-size:17.5px;font-weight:400;letter-spacing:.02em;transition:color .4s var(--ease)}
.mi:hover .n{color:var(--gold)}
.mi .d{display:block;margin-top:9px;font-size:15.5px;color:var(--muted);line-height:1.65}
.mi .tags{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.mi .tag{font-size:10.5px;text-transform:uppercase;letter-spacing:.22em;color:var(--muted-2);border:1px solid var(--hair-soft);padding:5px 10px}
.mi .tag.hot{color:var(--gold);border-color:var(--gold-dim)}
.mi .price{flex:0 0 auto;font-family:var(--display);font-weight:400;font-size:18px;letter-spacing:.03em;color:var(--warm-white);white-space:nowrap}
.mi .price .cur{font-family:var(--sans);font-size:11px;letter-spacing:.2em;color:var(--muted-2);margin-left:6px}

/* modal */
.modal{position:fixed;inset:0;z-index:960;display:none;place-items:center;padding:24px}
.modal.open{display:grid}
.modal .veil{position:absolute;inset:0;background:rgba(6,6,6,.86);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.modal .card{
  position:relative;max-width:520px;width:100%;background:var(--charcoal-2);
  border:1px solid var(--hair);max-height:88svh;overflow:auto;
}
.modal .card img{width:100%;aspect-ratio:16/10;object-fit:cover;filter:brightness(.88) saturate(.95)}
.modal .card .in{padding:clamp(24px,4vw,38px)}
.modal .card h3{font-size:clamp(24px,3.3vw,34px);margin-bottom:8px}
.modal .card .pr{font-family:var(--display);font-weight:400;letter-spacing:.06em;color:var(--gold);font-size:18.5px;margin-bottom:18px}
.modal .card p{font-size:16px;line-height:1.7}
.modal .x{position:absolute;top:14px;right:14px;width:38px;height:38px;border-radius:50%;background:rgba(10,10,10,.7);display:grid;place-items:center;font-size:19px;line-height:1;color:var(--warm-white)}

/* ---------- footer ---------- */
footer.site{background:var(--black);border-top:1px solid var(--hair-soft);padding:clamp(52px,6vw,80px) 0 34px}
footer.site .cols{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr 1.15fr;gap:40px}
footer.site h4{font-size:11.5px;text-transform:uppercase;letter-spacing:.34em;color:var(--gold);margin-bottom:20px;font-family:var(--sans);font-weight:400}
footer.site ul{list-style:none;display:flex;flex-direction:column;gap:12px}
footer.site a,footer.site li{font-size:15px;color:var(--muted);transition:color .4s var(--ease)}
footer.site a:hover{color:var(--gold)}
footer.site .f-brand img{height:26px;margin-bottom:18px}
footer.site .f-brand p{font-size:15px;max-width:300px}
.social{display:flex;gap:18px;margin-top:22px}
.social a{font-size:11.5px;text-transform:uppercase;letter-spacing:.24em}
.f-bottom{
  margin-top:clamp(40px,5vw,64px);padding-top:24px;border-top:1px solid var(--hair-soft);
  display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-size:12px;text-transform:uppercase;letter-spacing:.18em;color:var(--muted-2);
}
.f-bottom a{
  color:var(--muted-2);border-bottom:1px solid var(--hair-soft);padding-bottom:2px;
  transition:color .4s var(--ease),border-color .4s var(--ease);
}
.f-bottom a:hover{color:var(--gold);border-color:var(--gold-dim)}

/* ---------- article ---------- */
.article{padding-top:clamp(120px,14vw,180px)}
/* Article heading eased down from 76px. At the old size the Our Story
   title took two lines and orphaned "Curry in Dubai" on the second, which
   is what made it feel oversized rather than grand.
   text-wrap:balance evens the two lines wherever the browser supports it,
   so the break no longer depends on one hard-coded <br>. */
.article h1{font-size:clamp(34px,4.9vw,60px);margin:20px 0 26px;
  line-height:1.12;text-wrap:balance}
/* the colon is a natural hinge: on a wide screen the subtitle half drops to
   its own line, on a phone it wraps naturally */
@media (min-width:820px){ .article h1 .h1-break{display:block} }
.article h1 .h1-break{display:inline}
.article .meta{font-size:12px;text-transform:uppercase;letter-spacing:.34em;color:var(--muted-2)}
.article-body{max-width:720px}
.article-body h2{font-size:clamp(28px,4vw,46px);margin:56px 0 20px}
.article-body h3{font-family:var(--sans);font-weight:400;font-size:15px;text-transform:uppercase;letter-spacing:.28em;color:var(--gold);margin:46px 0 16px}
.article-body p{margin-bottom:22px;font-size:18px;line-height:1.85}
.article-body p.big{font-family:var(--display);font-weight:300;font-size:clamp(22px,2.8vw,31px);color:var(--warm-white);line-height:1.45;letter-spacing:.01em;margin:38px 0}
.article-body figure{margin:48px 0}
.article-body figure img{filter:saturate(.92) contrast(1.05) brightness(.86)}
.article-body figcaption{margin-top:14px;font-size:12.5px;text-transform:uppercase;letter-spacing:.26em;color:var(--muted-2)}
.article-body hr{border:0;border-top:1px solid var(--hair-soft);margin:52px 0}

/* ---------- journal grid ---------- */
.posts{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,3vw,40px)}
.post{display:block;background:var(--charcoal-2);border:1px solid var(--hair-soft);transition:border-color .5s var(--ease)}
.post:hover{border-color:var(--gold-dim)}
.post .ph{display:block;overflow:hidden;aspect-ratio:16/10}
.post img{width:100%;height:100%;object-fit:cover;filter:saturate(.92) brightness(.82);transition:transform 1.3s var(--ease),filter 1.3s var(--ease)}
.post:hover img{transform:scale(1.05);filter:saturate(1) brightness(.95)}
.post .in{display:block;padding:28px}
.post .kicker{display:block}
.post h3{font-size:23px;font-weight:400;margin:15px 0 13px}
.post p{font-size:15.5px}
.post .more{display:inline-block;margin-top:20px;font-size:11.5px;text-transform:uppercase;letter-spacing:.28em;color:var(--gold)}
.post.lead{grid-column:span 3;display:grid;grid-template-columns:1.15fr 1fr;align-items:stretch}
.post.lead .ph{aspect-ratio:auto;height:100%;min-height:320px}
.post.lead .in{padding:clamp(30px,4vw,56px);display:flex;flex-direction:column;justify-content:center}
.post.lead h3{font-size:clamp(28px,4vw,46px)}

/* ---------- responsive ---------- */
@media (max-width:1080px){
  .dishes{grid-template-columns:repeat(2,1fr)}
  .dish,.dish:nth-child(4),.dish:nth-child(5){grid-column:span 1}
  .dish:nth-child(5){grid-column:span 2}
  .dish:nth-child(5) .ph{aspect-ratio:16/9}
  .numbers{grid-template-columns:1fr 1fr}
  .num:nth-child(2){border-right:0}
  .num:nth-child(1),.num:nth-child(2){border-bottom:1px solid var(--hair-soft)}
  .posts{grid-template-columns:1fr 1fr}
  .post.lead{grid-column:span 2}
  footer.site .cols{grid-template-columns:1fr 1fr}
}
@media (max-width:940px){
  .nav,.nav-order{display:none}
  .burger{display:block}
  .split{grid-template-columns:1fr}
  .menu-grid{grid-template-columns:1fr}
  .post.lead{grid-template-columns:1fr}
}
@media (max-width:640px){
  body{font-size:16.5px}
  .dishes{grid-template-columns:1fr;gap:12px}
  .dish,.dish:nth-child(4),.dish:nth-child(5){grid-column:span 1}
  .dish .ph,.dish:nth-child(5) .ph{aspect-ratio:16/10}
  .posts{grid-template-columns:1fr}
  .post.lead{grid-column:span 1}
  .ratings{flex-direction:column}
  .rating{border-right:0;border-bottom:1px solid var(--hair-soft)}
  .rating:last-child{border-bottom:0}
  .order-direct{flex-direction:column;align-items:flex-start}
  .city{flex-wrap:wrap;gap:14px}
  .city .name{order:1}
  .city .rule{order:2}
  .city .arrow{order:3}
  .city .tag{order:4;position:static;flex:0 0 100%;margin-top:0;text-align:left}
  footer.site .cols{grid-template-columns:1fr}
}

/* ==========================================================================
   OPTION B — warm white reading pages
   --------------------------------------------------------------------------
   Homepage and both city pages stay dark and cinematic. The pages people
   READ — Menu, Journal, Our Story — open into Warm White, the fourth colour
   in the client's stated palette (Charcoal / Black / Warm White / Subtle Gold).
   Applied by adding class="light" to <body>. Nothing else changes.
   ========================================================================== */
/* The two darkened tones here (--muted-2 and --gold) came out of the
   contrast audit run on 2026-09-03. On the warm white ground the previous
   #8A8275 measured 3.40:1 and #9C7B27 measured 3.56:1 — both below the 4.5:1
   needed for small text, on Menu, Our Story, Journal, Contact and the legal
   pages. The replacements are the MINIMUM darkening that clears 4.5:1 on
   both warm white tones, so the palette shifts as little as possible. */
body.light{
  --charcoal:#F6F2EA;      /* page ground becomes warm white */
  --charcoal-2:#EFE9DE;    /* raised surface */
  --charcoal-3:#E6DFD2;
  --warm-white:#1A1815;    /* "warm white" role now carries the ink */
  --muted:#5E584E;
  --muted-2:#6E685E;
  --gold:#816620;          /* gold darkened so it holds on a light ground */
  --gold-dim:rgba(129,102,32,.46);
  --gold-faint:rgba(129,102,32,.10);
  --hair:rgba(26,24,21,.16);
  --hair-soft:rgba(26,24,21,.10);
  background:#F6F2EA;
  color:#1A1815;
}
body.light ::selection{background:#9C7B27;color:#F6F2EA}

/* the hero photograph stays dark and cinematic — the page opens up beneath it */
body.light .hero .grade{
  background:
    linear-gradient(to right,rgba(10,10,10,.86) 0%,rgba(10,10,10,.5) 42%,rgba(10,10,10,.34) 100%),
    linear-gradient(to top,rgba(10,10,10,.96) 0%,rgba(10,10,10,.55) 38%,rgba(10,10,10,.34) 66%,rgba(10,10,10,.78) 100%),
    radial-gradient(120% 90% at 50% 58%,rgba(10,10,10,0) 0%,rgba(10,10,10,.6) 100%);
}
body.light .hero .container,
body.light .hero h1,
body.light .hero .menu-note{color:#F2EEE7}
body.light .hero .eyebrow{color:#B08F4A}
body.light .hero .menu-note{border-left-color:rgba(176,143,74,.54)}

/* header: over the dark hero it must stay LIGHT — only once it condenses onto
   the warm-white page does it flip to ink. */
/* .has-hero = the page opens on a dark photograph, so the header starts light
   and flips to ink once it condenses. Pages without a hero start ink. */
body.light.has-hero header.site:not(.stuck) .nav a{color:#F2EEE7}
body.light.has-hero header.site:not(.stuck) .nav a.active{color:#B08F4A}
body.light.has-hero header.site:not(.stuck) .nav a::after{background:#B08F4A}
body.light.has-hero header.site:not(.stuck) .nav-order{color:#B08F4A;border-color:rgba(200,167,91,.4)}
body.light.has-hero header.site:not(.stuck) .nav-order:hover{background:rgba(176,143,74,.14);border-color:#B08F4A}
body.light.has-hero header.site:not(.stuck) .burger span{background:#F2EEE7}

body.light:not(.has-hero) header.site .nav a{color:#1A1815}
body.light:not(.has-hero) header.site .nav a.active{color:#755A18}
body.light:not(.has-hero) header.site .nav a::after{background:#9C7B27}
body.light:not(.has-hero) header.site .nav-order{color:#755A18;border-color:rgba(156,123,39,.5)}
body.light:not(.has-hero) header.site .burger span{background:#1A1815}
body.light:not(.has-hero) header.site .wordmark img{content:url(logo-dark.svg)}
body.light header.site.stuck{
  background:rgba(246,242,234,.9);
  border-bottom-color:rgba(26,24,21,.12);
}
body.light header.site.stuck .nav a{color:#1A1815}
body.light header.site.stuck .nav a.active{color:#755A18}
body.light header.site.stuck .nav-order{color:#755A18;border-color:rgba(156,123,39,.5)}
body.light header.site.stuck .burger span{background:#1A1815}
body.light header.site.stuck .wordmark img{content:url(logo-dark.svg)}

/* sticky menu tab bar */
body.light .tabs{
  background:rgba(246,242,234,.94);
  border-top-color:rgba(26,24,21,.10);
  border-bottom-color:rgba(26,24,21,.10);
}
body.light .tab:hover{color:#1A1815}
body.light .tab.active{color:#755A18;border-bottom-color:#9C7B27}

/* editorial imagery is not darkened on a light ground */
body.light .article-body figure img,
body.light .post img,
body.light .split .ph img{filter:saturate(1) contrast(1.02) brightness(1)}
body.light .modal .card img{filter:none}
body.light .modal .veil{background:rgba(26,24,21,.55)}
body.light .modal .card{background:#FFFDF9;border-color:rgba(26,24,21,.14)}
body.light .modal .x{background:rgba(26,24,21,.55);color:#F6F2EA}

/* buttons re-weighted for a light ground */
body.light .btn-gold{border-color:#9C7B27;color:#755A18}
body.light .btn-gold:hover{background:#9C7B27;color:#F6F2EA}
body.light .order-direct{
  border-color:rgba(156,123,39,.45);
  background:linear-gradient(180deg,rgba(156,123,39,.07),rgba(156,123,39,.02));
}
body.light .post{background:#FFFDF9}
body.light .notify{background:#EFE9DE}

/* the footer stays dark on every page — it anchors the whole site */
body.light footer.site{
  background:#0A0A0A;color:#B0A99D;border-top-color:rgba(242,238,231,.07);
}
body.light footer.site h4{color:#B08F4A}
body.light footer.site a,body.light footer.site li{color:#B0A99D}
body.light footer.site a:hover{color:#B08F4A}
body.light footer.site .f-bottom{color:#8C867B;border-top-color:rgba(242,238,231,.07)}
body.light footer.site .f-bottom a{color:#8C867B;border-bottom-color:rgba(242,238,231,.07)}
body.light footer.site .f-bottom a:hover{color:#B08F4A;border-color:rgba(176,143,74,.38)}
body.light footer.site .f-brand img,
body.light .drawer{filter:none}
body.light .drawer{background:#0A0A0A}
body.light .drawer a{color:#F2EEE7}
body.light .drawer a:last-child{color:#B08F4A}

@media (max-width:860px){
  .hero .grade{
    background:
      linear-gradient(to top,rgba(10,10,10,.95) 0%,rgba(10,10,10,.5) 40%,rgba(10,10,10,.28) 70%,rgba(10,10,10,.7) 100%),
      radial-gradient(130% 80% at 50% 55%,rgba(10,10,10,0) 0%,rgba(10,10,10,.5) 100%);
  }
  .post.lead .ph{aspect-ratio:16/10;min-height:0;height:auto}
}


/* ── Menu legibility & dietary colour coding ─────────────────────────────────
   Requested 2026-08-23. Two rules govern this block:
   1. Every colour that carries TEXT is checked against its own ground at
      WCAG AA (4.5:1). Measured values are noted beside each.
   2. Colour is never the ONLY signal — each tag keeps its written word
      ("Vegetarian", "Gluten free"), so the coding survives colour blindness,
      greyscale printing and the brief's reduced-motion/plain-text fallbacks.
   The lighter gold (#9C7B27) stays on borders and rules, where contrast
   minimums do not apply; gold TEXT on the warm-white ground uses #755A18.   */

.mi .tag{
  font-weight:400;letter-spacing:.16em;
  border-radius:2px;
}

/* dish name holds ink on the warm-white page, and stays legible on hover */
body.light .menu-cat h2{color:#1A1815}          /* 15.9:1 */
body.light .mi .n{color:#171512}                /* 16.3:1 */
body.light .mi:hover .n{color:#755A18}          /*  5.8:1 */
body.light .mi .d{color:#4F4A42}                /*  8.0:1 */

/* ---- dark ground (city pages / all-charcoal build) ---- */
.mi .tag-v{color:#7FBF8A;border-color:rgba(127,191,138,.42)}        /* 8.7:1 */
.mi .tag-ve{color:#7FBF8A;border-color:rgba(127,191,138,.42)}
.mi .tag-gf{color:#8FBEDB;border-color:rgba(143,190,219,.42)}       /* 9.4:1 */
.mi .tag-signature{color:#B08F4A;border-color:rgba(176,143,74,.48)} /* 8.2:1 */
.mi .tag-mild{color:#B0A99D;border-color:rgba(176,169,157,.36)}     /* 8.0:1 */
.mi .tag-medium{color:#E0A46A;border-color:rgba(224,164,106,.42)}   /* 8.7:1 */
.mi .tag-hot{color:#E08A7A;border-color:rgba(224,138,122,.45)}      /* 7.2:1 */

/* ---- warm-white ground (the menu page) — all verified >= 5.6:1 ---- */
body.light .mi .tag-v,
body.light .mi .tag-ve{color:#2E6B3E;border-color:rgba(46,107,62,.38);background:rgba(46,107,62,.06)}    /* 5.72:1 */
body.light .mi .tag-gf{color:#1F5E7A;border-color:rgba(31,94,122,.38);background:rgba(31,94,122,.06)}    /* 6.40:1 */
body.light .mi .tag-signature{color:#755A18;border-color:rgba(117,90,24,.40);background:rgba(117,90,24,.07)} /* 5.82:1 */
body.light .mi .tag-mild{color:#5E584E;border-color:rgba(94,88,78,.32);background:transparent}           /* 6.31:1 */
body.light .mi .tag-medium{color:#944D14;border-color:rgba(148,77,20,.38);background:rgba(148,77,20,.06)}/* 5.65:1 */
body.light .mi .tag-hot{color:#A32C1E;border-color:rgba(163,44,30,.40);background:rgba(163,44,30,.06)}   /* 6.41:1 */


/* ── Tab bar: black, and the menu's own scroll reveal ────────────────────────
   Requested 2026-08-24. The inactive tab colour was --muted-2, which measures
   only 3.40:1 on the warm-white ground and failed AA. Both states are now ink;
   the active one is separated by the gold rule beneath it and by full ink,
   not by being the only readable item in the row.                            */

body.light .tab{color:#2E2A24}                              /* 12.77:1 */
body.light .tab:hover{color:#1A1815}                        /* 15.87:1 */
body.light .tab.active{color:#1A1815;border-bottom-color:#9C7B27}

/* menu reveal — same fade-and-rise as .reveal, applied to nodes menu.js
   builds after site.js has already gathered its own targets */
.menu-cat .head.rv,
.menu-cat .cat-note.rv,
.mi.rv{
  opacity:0;transform:translateY(16px);
  transition:opacity var(--slow) var(--ease),transform var(--slow) var(--ease);
}
.menu-cat .head.rv.in,
.menu-cat .cat-note.rv.in,
.mi.rv.in{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  .menu-cat .head.rv,
  .menu-cat .cat-note.rv,
  .mi.rv{opacity:1;transform:none;transition:none;transition-delay:0s !important}
}


/* ── Sticky category bar must clear the fixed header ─────────────────────────
   .tabs sticks to top:0, but header.site is position:fixed and 79px tall at
   z-index 900 against the bar's 800 — so once the page scrolled past the hero
   the category bar was 100% covered and the menu lost its navigation entirely.
   --hdr-h is published by site.js from the header's live height (it changes
   when the header condenses), with a static fallback for a no-JS load.       */
.tabs{top:78px;top:var(--hdr-h,78px)}

/* the scrollspy also has to judge "current" from below the header + bar */
html{scroll-padding-top:calc(var(--hdr-h,78px) + 63px + 16px)}


/* ---------- signature cards: caption sat outside the card (2026-09-02) ---
   Measured: the card ended at y1872, the caption ended at y1896 — the text
   was hanging 24px below its own card.

   Cause: .hp-cap is a <span> left at display:inline, and its 22px/26px
   vertical padding is PAINTED but contributes no height, so the card never
   grew to contain it. Same failure that was fixed in the newer build; this
   one still carried the original. display:block makes the padding count.

   Also centred, per Jane — the caption now sits under the middle of the
   photograph rather than ranged left. */
.hp-sig .hp-cap{
  display:block;
  text-align:center;
  box-sizing:border-box;
  width:100%;
}
.hp-sig .hp-nm,
.hp-sig .hp-ds{display:block;text-align:center}
.hp-sig .hp-ds{margin-left:auto;margin-right:auto;max-width:34ch}


/* ---------- city chooser in the hero (2026-09-02) ----------------------
   Only this block was wanted from the other build: the question and the two
   doors. Styled to sit inside this hero rather than as a full-screen
   gateway, and no hover choreography beyond what this build already uses. */
.hp-hero .prompt{
  margin:44px 0 10px;font-size:clamp(15px,1.6vw,19px);
  color:var(--warm-white);opacity:.86;letter-spacing:.02em;
}
.hp-hero .cities{max-width:620px}
.hp-hero .city{
  display:flex;align-items:center;gap:20px;
  padding:20px 2px 16px;border-bottom:1px solid rgba(242,238,231,.16);
  position:relative;text-decoration:none;
  transition:border-color .5s var(--ease);
}
.hp-hero .city:first-child{border-top:1px solid rgba(242,238,231,.16)}
.hp-hero .city .name{
  flex:0 0 auto;font-weight:300;font-size:clamp(19px,2.6vw,27px);
  text-transform:uppercase;letter-spacing:.22em;color:var(--warm-white);
  transition:color .5s var(--ease),letter-spacing .5s var(--ease);
}
.hp-hero .city .rule{flex:1;height:1px;background:rgba(242,238,231,.16);
  position:relative;overflow:hidden}
.hp-hero .city .rule::after{content:"";position:absolute;inset:0;background:#B08F4A;
  transform:scaleX(0);transform-origin:left;transition:transform .6s var(--ease)}
.hp-hero .city .arrow{
  flex:0 0 auto;width:38px;height:38px;border-radius:50%;
  border:1px solid rgba(242,238,231,.22);display:grid;place-items:center;
  transition:border-color .5s var(--ease),background .5s var(--ease),transform .5s var(--ease);
}
.hp-hero .city .arrow svg{width:13px;height:13px;stroke:var(--warm-white);
  transition:stroke .5s var(--ease)}
.hp-hero .city .tag{
  position:absolute;right:56px;bottom:18px;
  font-size:9.5px;letter-spacing:.3em;text-transform:uppercase;color:#B08F4A;
}
.hp-hero .city:hover{border-bottom-color:rgba(200,167,91,.6)}
.hp-hero .city:hover .name{color:#B08F4A;letter-spacing:.26em}
.hp-hero .city:hover .rule::after{transform:scaleX(1)}
.hp-hero .city:hover .arrow{border-color:#B08F4A;background:rgba(176,143,74,.14);transform:translateX(5px)}
.hp-hero .city:hover .arrow svg{stroke:#B08F4A}
@media (max-width:600px){
  .hp-hero .city{flex-wrap:wrap;gap:12px}
  .hp-hero .city .tag{position:static;flex:0 0 100%}
}


/* ---------- header logo resized for the real artwork (2026-09-02) -------
   .wordmark img was height:30px, written when the logo was a 420x74 SVG
   wordmark — a wide strip. The real artwork is a 1600x1600 SQUARE lockup,
   so at height:30 it rendered 30x30: unreadable, and far too small to print
   from. Sized for a square mark, with the header given room to hold it.

   Also: two rules still swapped in logo-dark.svg — the placeholder — on the
   light and stuck header states, which put the old typeset stand-in back on
   the menu page. Both now point at the real PNG. */
header.site .wordmark img{height:72px;width:auto}
header.site.stuck .wordmark img{height:56px;transition:height .45s var(--ease)}
.wordmark.sm img{height:150px}

body.light:not(.has-hero) header.site .wordmark img{content:url(logo-dark.png)}
body.light header.site.stuck .wordmark img{content:url(logo-dark.png)}

@media (max-width:940px){
  header.site .wordmark img{height:56px}
  header.site.stuck .wordmark img{height:48px}
}
@media (max-width:380px){
  header.site .wordmark img{height:48px}
}


/* ---------- footer logo, same square-vs-wide problem (2026-09-02) -------
   footer.site .f-brand img was height:26px — also written for the old
   420x74 SVG strip. With the real 1600x1600 square lockup that rendered a
   26x26 thumbnail. Sized properly here. */
footer.site .f-brand img{height:96px;width:auto;margin-bottom:14px}
@media (max-width:940px){footer.site .f-brand img{height:78px}}
@media (max-width:480px){footer.site .f-brand img{height:68px}}


/* ---------- city chooser alignment (2026-09-02) ------------------------
   .cities was inheriting margin-inline:auto from the full-screen gateway
   rule, so with max-width:620px inside an 822px column it picked up a
   100.9px left margin and sat indented from the headline, the paragraph and
   the question above it. Pinned to the same left edge as the rest of the
   hero. */
.hp-hero .cities{margin-left:0 !important;margin-right:0 !important}
.hp-hero .prompt{margin-bottom:14px}


/* ---------- logo intro --------------------------------------------------
   Five clipped copies of the untouched logo over one square stage, so the
   steam, the bowl and the type can move independently and still line up.  */
.intro-veil{position:fixed;inset:0;z-index:9000;display:none;place-items:center;
  background:#121211;opacity:0;transition:opacity .42s var(--ease)}
.intro-veil.on{display:grid;opacity:1}
.intro-veil.out{display:grid;opacity:0}
.intro-stage{position:relative;width:min(38vh,300px);aspect-ratio:1/1}
.il{position:absolute;inset:0;background:url("logo-light.png") center/contain no-repeat;
  opacity:0;will-change:transform,opacity,clip-path}
/* the four steam bars, clipped by their measured x positions */
/* clips superseded — see the 2026-09-02 block at the end of this file */

.intro-veil.play .il-s0,.intro-veil.play .il-s1,
.intro-veil.play .il-s2,.intro-veil.play .il-s3{animation:il-steam .72s var(--ease) forwards}
.intro-veil.play .il-s0{animation-delay:.10s}
.intro-veil.play .il-s1{animation-delay:.19s}
.intro-veil.play .il-s2{animation-delay:.28s}
.intro-veil.play .il-s3{animation-delay:.37s}
.intro-veil.play .il-bowl{animation:il-bowl .82s var(--ease) .42s forwards}
.intro-veil.play .il-word{animation:il-rise .60s var(--ease) 1.06s forwards}
.intro-veil.play .il-tag {animation:il-rise .60s var(--ease) 1.22s forwards}
/* ---------- logo intro, re-measured for the 6000px master (2026-09-02) ---
   The client supplied final logo artwork on 2026-09-02. Its bands sit a
   little differently from the file it replaced, so every clip below was
   re-measured off the new master rather than carried over:

     steam bars   y  2.0% - 22.7%   x 29.62 / 42.60 / 55.62 / 68.60
     bowl mark    y 29.2% - 76.8%
     CURRY MILE   y 83.1% - 92.1%
     tagline      y 95.4% - 98.1%                                          */
.il-s0{clip-path:inset(0 68.47% 77.30% 29.62%)}
.il-s1{clip-path:inset(0 55.48% 77.30% 42.60%)}
.il-s2{clip-path:inset(0 42.48% 77.30% 55.62%)}
.il-s3{clip-path:inset(0 29.53% 77.30% 68.60%)}
.il-bowl{clip-path:inset(28% 0 22.6% 0)}
.il-word{clip-path:inset(82.4% 0 7.4% 0)}
.il-tag {clip-path:inset(94.8% 0 1.4% 0)}
@keyframes il-steam{
  0%  {opacity:0;transform:translateY(16px) scaleY(.55)}
  60% {opacity:1}
  100%{opacity:1;transform:none}
}
@keyframes il-bowl{
  0%  {opacity:1;clip-path:inset(28% 0 71% 0)}
  100%{opacity:1;clip-path:inset(28% 0 22.6% 0)}
}
@keyframes il-rise{
  0%  {opacity:0;transform:translateY(12px)}
  100%{opacity:1;transform:none}
}

/* ---------- intro on every page change (2026-09-02) --------------------
   Jane asked for the mark on each page change, not only on arrival. The
   first view of a session plays the full sequence; every view after that
   plays the same choreography at roughly half the length, so moving around
   the site does not feel like waiting. The stage is enlarged so the
   wordmark and the tagline are legible rather than a smudge. */
.intro-stage{width:min(52vh,420px)}
.intro-veil.quick .il-s0{animation-duration:.42s;animation-delay:.04s}
.intro-veil.quick .il-s1{animation-duration:.42s;animation-delay:.10s}
.intro-veil.quick .il-s2{animation-duration:.42s;animation-delay:.16s}
.intro-veil.quick .il-s3{animation-duration:.42s;animation-delay:.22s}
.intro-veil.quick .il-bowl{animation-duration:.46s;animation-delay:.20s}
.intro-veil.quick .il-word{animation-duration:.34s;animation-delay:.50s}
.intro-veil.quick .il-tag {animation-duration:.34s;animation-delay:.60s}


/* ---------- hero sub-line on the city pages (2026-09-02) ---------------
   Moved off the homepage and placed directly under "British Indian.
   Delivered." on both city heroes, matching the placement it had. */
.hero .hero-sub{
  margin:22px 0 0;max-width:46ch;
  font-size:clamp(16px,1.7vw,20px);line-height:1.6;
  color:var(--warm-white);opacity:.9;
}
body.light .hero .hero-sub{color:#F2EEE7}
@media (max-width:600px){.hero .hero-sub{font-size:16px;max-width:38ch}}

/* ---------- the page-change logo, a little smaller (2026-09-02) --------
   420px read well but was heavy for something shown on every navigation.
   The arrival splash keeps a larger stage; the quick one steps down. */
.intro-stage{width:min(44vh,340px)}
.intro-veil.quick .intro-stage{width:min(34vh,265px)}


/* =======================================================================
   MENU: BOOTSTRAP GRID, CARDS, PARALLAX — Option B, 2026-09-02
   Only bootstrap-grid.min.css is loaded, not the whole framework: the full
   build ships its own reset and type scale, which would flatten this
   build's design. This is the real Bootstrap grid with none of that.
   ======================================================================= */

/* each category is its own card rather than one continuous list */
#menuContent{max-width:1240px;margin:22px auto 0;padding:0 22px 30px;position:relative}
.menu-book{
  background:rgba(255,255,255,.035);
  border:1px solid rgba(242,238,231,.12);
  border-top:3px solid #B08F4A;
  box-shadow:0 22px 44px -34px rgba(0,0,0,.7);
  padding:clamp(24px,3vw,44px) clamp(18px,2.6vw,40px) clamp(16px,2vw,30px);
  margin:0 0 clamp(24px,3vw,40px);
  position:relative;scroll-margin-top:170px;
}
body.light .menu-book{
  background:#FBF8F1;border-color:rgba(26,24,21,.13);
  box-shadow:0 22px 44px -34px rgba(26,24,21,.34);
}
.menu-book::after{content:"";position:absolute;inset:7px;
  border:1px solid rgba(200,167,91,.20);pointer-events:none}
.menu-book .head{text-align:center;margin-bottom:20px}
.menu-book .head h2{text-align:center}
.menu-book .head .line{display:block;width:130px;height:1px;margin:15px auto 0;flex:none;
  background:linear-gradient(90deg,transparent,#B08F4A,transparent)}

/* Bootstrap's .row is flex; the element still carries .menu-grid, whose
   CSS grid would fight it, so the grid rules stand down inside a card */
.menu-book .menu-grid{display:flex !important;grid-template-columns:none !important;gap:0 !important}
.menu-book .menu-grid > .col-12{display:block}

/* the plate behind the cards, driven by parallax.js */
.menu-plate{
  position:fixed;inset:-14vh 0 -14vh 0;z-index:0;pointer-events:none;
  background-image:url("https://images.pexels.com/photos/2474661/pexels-photo-2474661.jpeg?auto=compress&cs=tinysrgb&w=2000");
  background-size:cover;background-position:center;
  opacity:.10;filter:saturate(.75) contrast(1.05);will-change:transform;
}
/* The parallax plate needs the content above it, but this rule used to read
   `header.site,.tabs,#menuContent,footer.site,.hero,.section{position:relative}`
   — which OVERRODE position:fixed on the header and position:sticky on the
   category bar. The bar stopped sticking and the cards rode over it.

   Only the scrolling content is promoted now; the header and the tab bar
   keep their own positioning and their existing, higher z-indexes. */
#menuContent,footer.site,.hero,.section{position:relative;z-index:1}
.menu-plate{z-index:0}

@media (max-width:767.98px){
  #menuContent{padding:0 14px 24px;margin-top:14px}
  .menu-book{padding:22px 16px 12px;margin-bottom:18px}
  .menu-book::after{inset:5px}
}
@media (prefers-reduced-motion:reduce){
  .menu-plate{display:none}
  .menu-book{transform:none !important}
}


/* =======================================================================
   SECTION ENTRANCES — 2026-09-02
   Each section arrives differently so the page has variety rather than the
   same fade eleven times. Driven by scenes.js, which waits for the logo
   intro to finish before starting the first one.

   Transform and opacity only, so none of it can cause a reflow. Distances
   are reduced on phones and tablets: a 60px slide that reads well on a
   1440px screen is disruptive on a 390px one, and horizontal movement is
   dropped entirely on phones so it can never cause a sideways scroll.
   ======================================================================= */
.sx{will-change:transform,opacity}
.sx-rise    {opacity:0;transform:translateY(46px)}
.sx-left    {opacity:0;transform:translateX(-54px)}
.sx-right   {opacity:0;transform:translateX(54px)}
.sx-zoom    {opacity:0;transform:scale(.955)}
.sx-blur    {opacity:0;transform:translateY(26px);filter:blur(7px)}
.sx-stagger {opacity:0;transform:translateY(34px)}

.sx-rise,.sx-left,.sx-right,.sx-zoom,.sx-stagger{
  transition:opacity .85s var(--ease),transform .95s var(--ease);
}
.sx-blur{transition:opacity .8s var(--ease),transform .9s var(--ease),filter .9s var(--ease)}

.sx.sx-in{opacity:1;transform:none;filter:none}

/* a staggered section lets its own children follow one after another */
.sx-stagger > * > *{opacity:0;transform:translateY(20px);
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.sx-stagger.sx-in > * > *{opacity:1;transform:none}
.sx-stagger.sx-in > * > *:nth-child(1){transition-delay:.05s}
.sx-stagger.sx-in > * > *:nth-child(2){transition-delay:.13s}
.sx-stagger.sx-in > * > *:nth-child(3){transition-delay:.21s}
.sx-stagger.sx-in > * > *:nth-child(4){transition-delay:.29s}
.sx-stagger.sx-in > * > *:nth-child(5){transition-delay:.37s}
.sx-stagger.sx-in > * > *:nth-child(6){transition-delay:.45s}

/* iPad: shorter travel */
@media (max-width:1024px){
  .sx-rise{transform:translateY(34px)}
  .sx-left{transform:translateX(-32px)}
  .sx-right{transform:translateX(32px)}
  .sx-stagger{transform:translateY(24px)}
}
/* phones: no sideways movement at all, and quicker */
@media (max-width:640px){
  .sx-rise,.sx-stagger{transform:translateY(26px)}
  .sx-left,.sx-right{transform:translateY(26px)}
  .sx-zoom{transform:scale(.975)}
  .sx-blur{filter:blur(4px);transform:translateY(18px)}
  .sx-rise,.sx-left,.sx-right,.sx-zoom,.sx-stagger,.sx-blur{
    transition-duration:.62s,.68s}
}
@media (prefers-reduced-motion:reduce){
  .sx,.sx-stagger > * > *{
    opacity:1 !important;transform:none !important;filter:none !important;
    transition:none !important}
}


/* =======================================================================
   SPACING — 2026-09-02
   Two problems, measured rather than guessed:

   1. On a phone the hero was locked to 100svh with its content bottom-
      aligned, leaving a 355px empty gap between the header and the first
      line of text — most of a screen of nothing before anything is read.
      The hero now sizes to its content with a sensible floor.

   2. Section padding ran to 140px top AND bottom, so adjacent sections put
      280px of dead space between them. Reduced across the board; the
      hierarchy is kept (a .tight section is still tighter than a normal
      one) but the whole page breathes without yawning.
   ======================================================================= */

/* ---- 1. the hero stops reserving a screen of emptiness ---- */
@media (max-width:900px){
  .hp-hero,.hero{
    min-height:auto;
    padding-top:clamp(96px,22vw,150px);
    padding-bottom:clamp(40px,10vw,64px);
    align-items:flex-start;
  }
  .hp-hero .container,.hero .container{padding-top:0;padding-bottom:0}
  .hp-hero h1,.hero h1{margin-top:6px}
}
@media (max-width:640px){
  .hp-hero,.hero{padding-top:clamp(88px,24vw,128px)}
}

/* ---- 2. sections lose the excess, at every size ---- */
.section{padding:clamp(52px,6.2vw,88px) 0}
.section.tight{padding:clamp(40px,4.6vw,64px) 0}
@media (max-width:900px){
  .section{padding:clamp(42px,7vw,60px) 0}
  .section.tight{padding:clamp(32px,5.5vw,46px) 0}
}
@media (max-width:640px){
  .section{padding:38px 0}
  .section.tight{padding:30px 0}
}


/* the city-page hero has the same flex-item shrink problem */
.hero .container{width:100%;flex:1 1 100%;max-width:var(--maxw);margin-inline:auto}
.finale .container{width:100%}


/* ---------- story column widened to the banner (2026-09-02) ------------
   Measured before: the banner sat at left 137 / 1152 wide, while the body
   text sat at left 367 / 692 — inset 230px and barely half the width.

   The column is now flush with the banner's left edge and much wider, and
   the in-article photographs run the full container width like the banner
   does.

   One deliberate limit: the TEXT stops at 900px rather than matching the
   banner's 1152. A 1152px measure is about 150 characters a line, which is
   past the point where the eye reliably finds the next line. 900px is a
   noticeably wider column that can still be read. */
.legal .article-body,
.article .article-body,
.article-body{
  max-width:900px !important;
  margin-left:0 !important;
  margin-right:0 !important;
}
.article-body figure{
  max-width:none;width:100%;
  margin-left:0;margin-right:0;
}
.article-body figure img{width:100%;height:auto}

@media (max-width:1024px){
  .article-body{max-width:none !important}
}


/* the cap was on the PARENT, not the column ---------------------------
   .article-body sits inside <div class="container narrow">, and that is
   what held the text to 692px. Widening the child could never get past it.
   The narrow container is opened up on the story page only; the legal pages
   keep their tighter measure, which suits them. */
.article .container.narrow{max-width:var(--maxw)}
.article .article-body{max-width:900px !important;margin-left:0 !important}
.article .article-body figure{width:100%;max-width:none}
@media (max-width:1024px){
  .article .article-body{max-width:none !important}
}


/* ---------- story page: parallax frames + sliding blocks (2026-09-03) ---
   Driven by story.js. The frames clip their image so the slower-moving
   photograph is revealed rather than drifting out of place; the prose
   arrives in heading-plus-paragraph blocks, alternating side. */
.article .st-frame{overflow:hidden;position:relative;display:block}
.article .st-plx{will-change:transform;display:block;width:100%}

.article .st-slide{
  opacity:0;
  transition:opacity .8s var(--ease),transform .9s var(--ease);
  will-change:transform,opacity;
}
.article .st-left {transform:translateX(-46px)}
.article .st-right{transform:translateX(46px)}
.article .st-slide.st-in{opacity:1;transform:none}

/* the first paragraph of a block leads, the rest follow */
.article .st-slide > * {opacity:0;transform:translateY(14px);
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.article .st-slide.st-in > *{opacity:1;transform:none}
.article .st-slide.st-in > *:nth-child(1){transition-delay:.05s}
.article .st-slide.st-in > *:nth-child(2){transition-delay:.12s}
.article .st-slide.st-in > *:nth-child(3){transition-delay:.19s}
.article .st-slide.st-in > *:nth-child(4){transition-delay:.26s}
.article .st-slide.st-in > *:nth-child(n+5){transition-delay:.32s}

/* phones: no sideways travel, so it can never cause a horizontal scroll */
@media (max-width:640px){
  .article .st-left,.article .st-right{transform:translateY(28px)}
  .article .st-slide{transition-duration:.6s,.66s}
}
@media (prefers-reduced-motion:reduce){
  .article .st-slide,.article .st-slide > *{
    opacity:1 !important;transform:none !important;transition:none !important}
  .article .st-plx{transform:none !important}
}


/* ---------- header nav on light pages (2026-09-03) ---------------------
   Measured by sampling the pixels behind a nav link on /menu:
   rgb(242,238,231) text on rgb(239,235,227) background = 1.03:1. Invisible.

   Cause: body.light.has-hero keeps the nav light because it assumes the
   header floats over a dark photograph. On this build it never does — the
   header ends at y125 and the hero starts at y125 on every page. So on any
   light page the nav takes the ink treatment, hero or not. */
body.light header.site .nav a,
body.light.has-hero header.site:not(.stuck) .nav a{color:#1A1815 !important}
body.light header.site .nav a.active,
body.light.has-hero header.site:not(.stuck) .nav a.active{color:#755A18 !important}
body.light header.site .nav a.active{border-bottom-color:#9C7B27 !important}
body.light header.site .nav-order,
body.light.has-hero header.site:not(.stuck) .nav-order{
  color:#755A18 !important;border-color:rgba(156,123,39,.55) !important}
body.light header.site .nav-order:hover{background:#755A18 !important;color:#F6F2EA !important}
body.light header.site .burger span{background:#1A1815}


/* ---------- contact page (2026-09-03) ----------------------------------
   Details verified from currymile.ae's own schema.org data. */
.contact-pg .lede{max-width:56ch;font-size:clamp(16px,1.8vw,20px);
  line-height:1.65;color:var(--muted);margin:14px 0 0}
.ct-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin:8px 0 40px}
.ct-card{border:1px solid var(--hair-soft);padding:26px 24px;display:flex;
  flex-direction:column;gap:9px;transition:border-color .45s var(--ease)}
.ct-card:hover{border-color:var(--gold-dim)}
.ct-lbl{font-size:11px;text-transform:uppercase;letter-spacing:.34em;color:var(--gold)}
.ct-big{font-size:clamp(17px,2vw,21px);font-weight:400;line-height:1.35;color:var(--warm-white)}
a.ct-big{text-decoration:none;border-bottom:1px solid transparent;align-self:flex-start}
a.ct-big:hover{border-bottom-color:currentColor}
.ct-addr{font-weight:500}
.ct-sub{font-size:13px;line-height:1.5;color:var(--muted-2)}
a.ct-sub{color:var(--gold);text-decoration:none}
a.ct-sub:hover{text-decoration:underline}
.ct-note{border-left:2px solid var(--gold-dim);padding:18px 22px;margin:6px 0 10px;
  font-size:15.5px;line-height:1.7;background:rgba(200,167,91,.05)}

body.light .ct-card{border-color:rgba(26,24,21,.20)}
body.light .ct-card:hover{border-color:rgba(156,123,39,.55)}
body.light .ct-big{color:#171512}
body.light .ct-sub{color:#5E584E}
body.light a.ct-sub,body.light .ct-lbl{color:#7A5F14}
body.light .ct-note{background:rgba(156,123,39,.06);border-left-color:#9C7B27}

@media (max-width:720px){.ct-grid{grid-template-columns:1fr}}


/* ---------- "View Menu" row in the city hero (2026-09-03) --------------
   The same component as the homepage city chooser, reused on the city page
   under the sub-line: name, hairline rule, circled arrow. The chooser's own
   styles are scoped to .hp-hero, so the city-page hero needs its own copy
   rather than inheriting them. */
.hero .cities{max-width:620px;margin:34px 0 0}
.hero .city{
  display:flex;align-items:center;gap:20px;
  padding:20px 2px 16px;border-top:1px solid rgba(242,238,231,.16);
  border-bottom:1px solid rgba(242,238,231,.16);
  position:relative;text-decoration:none;
  transition:border-color .5s var(--ease);
}
.hero .city .name{
  flex:0 0 auto;font-weight:300;font-size:clamp(18px,2.4vw,25px);
  text-transform:uppercase;letter-spacing:.22em;color:var(--warm-white);
  transition:color .5s var(--ease),letter-spacing .5s var(--ease);
}
.hero .city .rule{flex:1;height:1px;background:rgba(242,238,231,.16);
  position:relative;overflow:hidden}
.hero .city .rule::after{content:"";position:absolute;inset:0;background:#B08F4A;
  transform:scaleX(0);transform-origin:left;transition:transform .6s var(--ease)}
.hero .city .arrow{
  flex:0 0 auto;width:38px;height:38px;border-radius:50%;
  border:1px solid rgba(242,238,231,.22);display:grid;place-items:center;
  transition:border-color .5s var(--ease),background .5s var(--ease),transform .5s var(--ease);
}
.hero .city .arrow svg{width:13px;height:13px;stroke:var(--warm-white);
  transition:stroke .5s var(--ease)}
.hero .city:hover{border-color:rgba(176,143,74,.58)}
.hero .city:hover .name{color:#B08F4A;letter-spacing:.26em}
.hero .city:hover .rule::after{transform:scaleX(1)}
.hero .city:hover .arrow{border-color:#B08F4A;background:rgba(176,143,74,.14);transform:translateX(5px)}
.hero .city:hover .arrow svg{stroke:#B08F4A}
@media (max-width:600px){
  .hero .cities{margin-top:26px}
  .hero .city{gap:12px;padding:16px 2px 14px}
}


/* ---------- social as icons (2026-09-03) -------------------------------
   They were plain words, and all three pointed at "#". Instagram and
   Facebook are wired to the handles listed in currymile.ae's own
   schema.org data.

   TikTok is deliberately absent: tiktok.com returns HTTP 200 for handles
   that do not exist — a nonsense handle tested just now also returned 200 —
   so the account could not be verified. Add it once the client confirms it.

   44px targets so they are tappable on a phone. */
footer.site .social{display:flex;align-items:center;gap:12px;margin-top:18px}
footer.site .social a{
  width:42px;height:42px;display:grid;place-items:center;
  border:1px solid rgba(242,238,231,.20);border-radius:50%;
  color:#B0A99D;
  transition:color .4s var(--ease),border-color .4s var(--ease),
             background .4s var(--ease),transform .4s var(--ease);
}
footer.site .social a svg{width:18px;height:18px;display:block}
footer.site .social a:hover{
  color:#121211;background:#B08F4A;border-color:#B08F4A;transform:translateY(-2px);
}
footer.site .social a:focus-visible{outline:2px solid #B08F4A;outline-offset:3px}
@media (max-width:600px){
  footer.site .social a{width:44px;height:44px}
}


/* ---------- unpublished journal cards (2026-09-03) ---------------------
   The three article pages do not exist. They were <a href="#">, so they
   looked clickable and went nowhere. They are plain cards until there is
   something to open — no hover lift, no pointer. */
.post.is-unpublished{cursor:default}
.post.is-unpublished:hover{transform:none}
.post.is-unpublished .ph img{transition:none}
.post.is-unpublished:hover .ph img{transform:none}


/* ---------- header logo on light pages (2026-09-03) --------------------
   Sampled on /menu: the wordmark measured 1.15:1 against the band behind
   it — the white-wordmark file was being served onto a light background.

   Same cause as the nav colours fixed earlier: body.light.has-hero keeps
   the light artwork because it assumes the header floats over a dark
   photograph, and on this build it never does. The dark-wordmark file is
   used on ANY light page, hero or not; the dark pages keep the light one. */
body.light header.site .wordmark img,
body.light.has-hero header.site .wordmark img{content:url(logo-dark.png)}
body:not(.light) header.site .wordmark img{content:url(logo-light.png)}

/* the drawer and footer sit on dark ground on every page */
footer.site .f-brand img{content:url(logo-light.png)}


/* ---------- header states, corrected (2026-09-03) ----------------------
   History worth keeping, because I got this wrong twice in both directions:

   · The header is position:fixed, so at the top of a page with a hero it
     floats OVER the photograph and needs LIGHT text.
   · Once it condenses (.stuck) it gains a warm-white background and needs
     INK text.
   · A light page with no hero has no dark photograph under it at all, so it
     is ink from the start.

   Earlier I had briefly broken position:fixed, which put the header on the
   pale band instead — ink looked right then, and became invisible the
   moment fixed positioning was restored. These three rules cover the three
   real states rather than assuming one of them. */

/* 1. over the hero photograph — light */
body.light.has-hero header.site:not(.stuck) .nav a{color:#F2EEE7 !important;opacity:.92}
body.light.has-hero header.site:not(.stuck) .nav a.active{color:#B08F4A !important;
  border-bottom-color:#B08F4A !important}
body.light.has-hero header.site:not(.stuck) .nav-order{
  color:#B08F4A !important;border-color:rgba(176,143,74,.55) !important}
body.light.has-hero header.site:not(.stuck) .nav-order:hover{
  background:#B08F4A !important;color:#121211 !important}
body.light.has-hero header.site:not(.stuck) .wordmark img{content:url(logo-light.png)}
body.light.has-hero header.site:not(.stuck) .burger span{background:#F2EEE7}

/* 2. condensed onto the warm-white page — ink */
body.light header.site.stuck .nav a{color:#1A1815 !important;opacity:1}
body.light header.site.stuck .nav a.active{color:#755A18 !important;
  border-bottom-color:#9C7B27 !important}
body.light header.site.stuck .nav-order{
  color:#755A18 !important;border-color:rgba(156,123,39,.55) !important}
body.light header.site.stuck .wordmark img{content:url(logo-dark.png)}
body.light header.site.stuck .burger span{background:#1A1815}

/* 3. a light page with no hero — ink from the start */
body.light:not(.has-hero) header.site .nav a{color:#1A1815 !important}
body.light:not(.has-hero) header.site .nav a.active{color:#755A18 !important}
body.light:not(.has-hero) header.site .nav-order{
  color:#755A18 !important;border-color:rgba(156,123,39,.55) !important}
body.light:not(.has-hero) header.site .wordmark img{content:url(logo-dark.png)}

/* ============ the city pages are warm white pages ======================
   Dubai and Abu Dhabi now carry body.light, so the whole page is warm white
   EXCEPT the two things that must stay dark: the hero and the footer. The
   footer is already charcoal on every light page, so only the photographic
   bands need handling here.

   Rather than patch descendants one at a time (the old approach, which had
   grown to six separate `body.light .hero .x{color:#F2EEE7}` rules and still
   missed the city rows), these blocks re-declare the palette variables on
   the subtree. Anything inside them — existing or added later — inverts
   automatically and cannot be forgotten. */

/* --- the photographic bands stay dark -------------------------------
   .hero and .finale are full-bleed photographs with a dark gradient burned
   over them. On a light page their text would otherwise turn to ink and
   disappear into the photograph. .finale is included for exactly this
   reason: it is a photograph, not a content section. */
/* .band-dark is the inverse of the light band: an opt-in charcoal section on
   a warm white page. The brief asks for the Order section to return to
   charcoal so it reads as a clear step down into the warm white "What Dubai
   keeps coming back for" below it. Same mechanism as .hero/.finale. */
body.light .section.band-dark{background:#121211}
body.light .hero,
body.light .finale,
body.light .section.band-dark{
  --charcoal:#121211;
  --charcoal-2:#191817;
  --charcoal-3:#211F1D;
  --warm-white:#F2EEE7;
  --muted:#B0A99D;
  --muted-2:#8C867B;
  --gold:#B08F4A;
  --gold-dim:rgba(176,143,74,.38);
  --gold-faint:rgba(176,143,74,.16);
  --hair:rgba(242,238,231,.13);
  --hair-soft:rgba(242,238,231,.07);
  color:#F2EEE7;
}

/* --- dark cards on a warm white page --------------------------------
   .dish keeps --black as its ground so the food photography stays the
   brightest thing on the page, which makes each card a dark island. Without
   this it inherits the page's ink and renders #1A1815 on #0A0A0A — 1.12:1,
   invisible. Dubai and Abu Dhabi carry six of these each. */
body.light .dish{
  --warm-white:#F2EEE7;
  --muted:#B0A99D;
  --muted-2:#8C867B;
  --gold:#B08F4A;
  --gold-dim:rgba(176,143,74,.38);
  --hair:rgba(242,238,231,.13);
  --hair-soft:rgba(242,238,231,.07);
  color:#F2EEE7;
}


/* --- the one rule the variable swap cannot reach ----------------------
   body.light .btn-gold hard-codes its colour (#755A18 on a bronze border)
   rather than reading var(--gold), so it out-ranks the palette re-inversion
   on .hero / .finale and rendered dark bronze on a dark photograph —
   measured 2.64:1 on Dubai and 2.95:1 on Abu Dhabi. Inside those two
   photographic bands the button goes back to the light-on-dark treatment.

   Worth remembering when adding anything to .hero or .finale: the variable
   swap covers everything that paints THROUGH the palette; anything with a
   literal colour under a body.light selector needs a pair like this. */
body.light .hero .btn-gold,
body.light .finale .btn-gold,
body.light .section.band-dark .btn-gold{border-color:var(--gold);color:var(--gold)}
body.light .hero .btn-gold:hover,
body.light .finale .btn-gold:hover,
body.light .section.band-dark .btn-gold:hover{background:var(--gold);color:#121211}

/* --- keeping the finale type legible on a LIGHT overlay ----------------
   Easing the overlay so the photograph reads has a cost: the frame has
   bright areas (tiled wall, steel, the lit hood) and the small gold button
   text measured as low as 1.92:1 against them, even though the AVERAGE
   behind it was a comfortable 6.5:1. An average is the wrong test for text
   on a photograph — the worst pixel is what fails.

   The fix is local rather than global: a soft scrim that sits behind the
   text block only, so the type gets its own quiet ground while the rest of
   the picture stays as light as Jane asked for. It fades to nothing well
   before the edges, so it reads as depth in the photograph, not a panel. */
.finale .container::before{
  content:"";position:absolute;z-index:-1;
  inset:-40% -26%;
  background:radial-gradient(72% 78% at 50% 50%,
    rgba(10,10,10,.86) 0%,rgba(10,10,10,.78) 40%,
    rgba(10,10,10,.56) 66%,rgba(10,10,10,.22) 86%,rgba(10,10,10,0) 100%);
  pointer-events:none;
}

/* ================= MOST ORDERED — the six best sellers ================
   Six client photographs, in the order of popularity the brief specifies.

   The problem they arrive with: all six are the SAME shot. Same white
   marble, same gold cutlery, same cream napkin, same bowl, same angle,
   same distance. Laid out as a plain grid they read as one photo repeated
   six times and the only thing that varies is the colour of the sauce.
   The brief invites cropping and recomposition, so the layout does the work
   the photography cannot:

     · PROMINENCE FOLLOWS POPULARITY. No 1 runs across two columns and two
       rows; 2 and 3 sit beside it; 4, 5 and 6 form the lower row. Rank is
       legible from size alone, before you read a word.
     · EVERY TILE IS A DIFFERENT SHAPE, so the identical bowls are cropped
       differently and the repetition stops reading as repetition.
     · THE CAPTION IS OFF THE PHOTOGRAPH. These are bright, high-key images;
       the old dark card burned white type into the picture, which turns
       white marble to muddy grey. The name sits beneath instead.
     · The rank numeral is set in the muted gold — it is the one piece of
       information the section exists to convey. */

.ord-grid{
  display:grid;gap:clamp(10px,1.1vw,18px);
  grid-template-columns:repeat(3,1fr);
  grid-auto-rows:auto;
}
/* Every tile is a column with the photograph absorbing the slack, so the
   caption always sits on the FLOOR of its grid cell. Without this the small
   tiles kept their 4/3 photo and left ~84px of cream under the caption,
   which put Chicken Chilli's name a long way above Butter Chicken's beside
   it. aspect-ratio still sets each photo's preferred size; flex-grow just
   lets it fill whatever the row turns out to be, and object-fit:cover
   absorbs the changed ratio. */
.ord{display:flex;flex-direction:column;text-decoration:none;color:inherit}
.ord .ord-ph{flex:1 1 auto;min-height:0}
.ord-ph{
  display:block;position:relative;overflow:hidden;
  background:var(--charcoal-2);
  border:1px solid var(--hair-soft);
}
.ord-ph img{
  width:100%;height:100%;object-fit:cover;display:block;
  /* the marble is a shade cooler than this site's cream; a touch of warmth
     and saturation ties the plates to the page without touching the food */
  filter:saturate(1.06) contrast(1.03) sepia(.05);
  /* THREE things animate this image — the entrance settle, hover, and the
     scroll drift. Each owns a custom property and the transform composes
     them here, so none can overwrite another. */
  --ord-y:0px;
  --ord-s:1.085;
  transform:translate3d(0,var(--ord-y),0) scale(var(--ord-s));
  transition:--ord-s 1.4s var(--ease),filter .6s var(--ease);
}
/* a warm wash, low enough that the sauces stay true */
.ord-ph::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(150deg,rgba(176,143,74,.10),rgba(176,143,74,0) 46%,rgba(26,24,21,.10));
}
.ord:hover .ord-ph img{--ord-s:1.062;filter:saturate(1.12) contrast(1.05) sepia(.03)}

.ord-meta{display:flex;align-items:baseline;gap:12px;padding:13px 2px 0}
.ord-meta i{
  font-style:normal;font-size:11px;letter-spacing:.24em;
  color:var(--gold);font-weight:400;flex:none;
}
.ord-meta b{
  font-weight:300;font-size:clamp(14px,1.25vw,18px);letter-spacing:.05em;
  color:var(--warm-white);transition:color .4s var(--ease);
}
.ord:hover .ord-meta b{color:var(--gold)}

/* --- rank drives both position and crop --- */
/* TWO hero tiles, mirrored. No 1 sits large on the left with 2 and 3 in the
   right-hand column; No 4 then sits large on the RIGHT with 5 and 6 down the
   left. The mirror stops the grid reading as one big tile followed by a row
   of leftovers, and it gives the section a second focal point halfway down.

   Both hero tiles are flex columns: spanning two rows makes the CELL taller
   than a photo plus a caption, which otherwise leaves a band of dead cream
   underneath. The photograph takes whatever height is left instead, so each
   hero ends flush with the small tiles beside it.

   Placement is explicit rather than auto-flow — with two spanning tiles the
   browser's own packing puts them in the wrong columns. */
.ord-01 .ord-ph,.ord-04 .ord-ph{flex:1 1 auto;aspect-ratio:auto;min-height:0}
.ord-01 .ord-meta b,.ord-04 .ord-meta b{font-size:clamp(16px,1.7vw,24px)}

.ord-01{grid-column:1 / span 2;grid-row:1 / span 2}
.ord-02{grid-column:3;grid-row:1}
.ord-03{grid-column:3;grid-row:2}
.ord-04{grid-column:2 / span 2;grid-row:3 / span 2}   /* the right-hand hero */
.ord-05{grid-column:1;grid-row:3}
.ord-06{grid-column:1;grid-row:4}

.ord-02 .ord-ph,.ord-03 .ord-ph,
.ord-05 .ord-ph,.ord-06 .ord-ph{aspect-ratio:4/3}
/* nudge the framing per tile so six identical bowls never sit at the same
   spot in their frames */
.ord-02 .ord-ph img{object-position:52% 44%}
.ord-03 .ord-ph img{object-position:46% 56%}
.ord-04 .ord-ph img{object-position:50% 46%}
.ord-05 .ord-ph img{object-position:54% 54%}
.ord-06 .ord-ph img{object-position:44% 48%}

@media (max-width:900px){
  /* two columns, and the explicit desktop placement is released so the
     tiles simply flow in rank order */
  .ord-grid{grid-template-columns:repeat(2,1fr)}
  .ord-01,.ord-02,.ord-03,.ord-04,.ord-05,.ord-06{grid-column:auto;grid-row:auto}
  .ord-01,.ord-04{grid-column:span 2}
  .ord-01 .ord-ph,.ord-04 .ord-ph{aspect-ratio:16/10;flex:0 0 auto}
  .ord-02 .ord-ph,.ord-03 .ord-ph,
  .ord-05 .ord-ph,.ord-06 .ord-ph{aspect-ratio:1/1}
}
@media (max-width:520px){
  .ord-meta{padding-top:10px;gap:9px}
  .ord-meta i{font-size:10px}
}


/* Dish names stay light — reverted 6 Sep at Jane's call, back in line with
   the brief's thin-type direction. Menu item names 400, Most Ordered 300,
   category headings 200. */


/* ---- cinematic entrance for the top six ------------------------------
   Rank order, heroes leading. The tile rises and the photograph settles
   back from a slight over-scale at the same time — the settle is what
   reads as a camera coming to rest rather than a UI fade. */
.ord{
  opacity:0;
  transform:translateY(28px);
  transition:opacity .95s var(--ease),transform 1.15s var(--ease);
  will-change:transform,opacity;
}
.ord.ord-in{opacity:1;transform:none}
.ord.ord-in .ord-ph img{--ord-s:1.02;transition:--ord-s 1.7s var(--ease),filter .6s var(--ease)}
.ord.ord-in{will-change:auto}   /* released once it has arrived */

/* the property has to be registered for --ord-s to be animatable at all;
   without this it would jump rather than settle */
@property --ord-s{syntax:"<number>";inherits:false;initial-value:1.085}
@property --ord-y{syntax:"<length>";inherits:false;initial-value:0px}

@media (prefers-reduced-motion:reduce){
  .ord{opacity:1 !important;transform:none !important;transition:none !important}
  .ord .ord-ph img{--ord-s:1.02;--ord-y:0px;transition:none !important}
}


/* ---- staff photography ------------------------------------------------
   Client-supplied, AI-enhanced kitchen images. The brief for them was that
   they sit quietly in the design rather than read as standalone photographs,
   and that the enhancement be softened.

   Both are done here rather than by retouching the files: brightness and
   saturation come down, contrast comes off slightly — the AI artefacts live
   in over-saturated skin and over-sharp edges, so easing both is what makes
   them read as photography again — and a dark gradient sits over the frame
   so each image blends into the page instead of sitting on it. */
.staff{position:relative;overflow:hidden;display:block}
/* These four frames are PORTRAIT (roughly 1000x1280). Dropped into a
   full-width article column they render ~1150px tall — a full screen of
   photograph, which is exactly the "prominent standalone photograph" the
   brief asked to avoid. Each is cropped to a landscape band instead, so it
   reads as a note inside the story rather than an interruption to it.
   The crop favours the upper-middle of the frame, where the chef's hands
   and the food are, rather than the centre. */
.article-body figure.staff{aspect-ratio:16/9;max-height:62vh}
.staff img{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 38%}
/* These need to out-specify the light-page image rule
   `body.light .article-body figure img, ... , body.light .split .ph img`,
   which resets filters to none and was quietly winning at (0,3,1). Each
   selector below carries its own specificity — listing them together does
   not lower any of them. */
.staff img,
.split .ph.staff img,
.article-body figure.staff img,
body.light .article-body figure.staff img,
body.light .split .ph.staff img,
body.light .post img.staff{
  filter:brightness(.84) saturate(.86) contrast(.96);
}
.staff::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(10,10,10,.30) 0%,rgba(10,10,10,.08) 42%,rgba(10,10,10,.46) 100%);
}


/* ---- ORDER button hover, light pages ---------------------------------
   The hover rule set the background to #755A18 but a LATER rule of equal
   specificity — `body.light:not(.has-hero) header.site .nav-order` — kept
   the text at #755A18 too, both carrying !important. Equal weight means the
   later one wins, so on hover the label was bronze on bronze: 1:1, a solid
   block with no readable text. These restate the colour on hover with the
   specificity to settle it. */
body.light:not(.has-hero) header.site .nav-order:hover,
body.light header.site.stuck .nav-order:hover,
body.light header.site .nav-order:hover{
  background:#755A18 !important;
  color:#F6F2EA !important;
  border-color:#755A18 !important;
}

/* ---- staff frames: the WHOLE photograph, not a crop of it ------------
   These are portrait frames of people working. A 16:9 crop kept the face
   and cut away the hands, the pan and the food — which is the only part
   that says what the person is actually doing. So nothing is cropped: the
   image is shown complete and simply capped in height so a portrait does
   not take over the page.

   (An earlier attempt used height:100% against a parent whose height was
   still auto at layout time: one frame rendered 1174px tall and the other
   collapsed to zero. Capping the image itself avoids that entirely.) */
.article-body figure.staff{aspect-ratio:auto;max-height:none;overflow:hidden;
  display:flex;justify-content:flex-start}
.article-body figure.staff img{
  width:auto;max-width:100%;
  height:auto;max-height:min(76vh,720px);
  aspect-ratio:auto;
  object-fit:contain;
}

/* ---- the split image matches the height of the text beside it --------
   The row was align-items:center with a fixed 4/3.4 image, so the picture
   and the paragraph column ended at different heights. The image column now
   stretches and the picture fills it. */
.split{align-items:stretch}
.split .ph{display:block;height:100%;min-height:0}
.split .ph img,
.split .ph.staff img{
  width:100%;height:100%;aspect-ratio:auto;object-fit:cover;max-height:none;
}
@media (max-width:900px){
  /* stacked: no text beside it to match, so give it a sane band again */
  .split .ph img,.split .ph.staff img{height:auto;aspect-ratio:16/10}
}

/* ---- motion on the story images -------------------------------------
   A slow settle as each arrives, and a gentle lift on hover. Transform and
   opacity only; the whole thing is off under reduced-motion. */
/* settle on arrival, drift while scrolling, lift on hover — three owners,
   one composed transform, so none can clobber another */
@property --st-s{syntax:"<number>";inherits:false;initial-value:1.06}
@property --st-y{syntax:"<length>";inherits:false;initial-value:0px}
.staff img,.st-drift{--st-s:1.06;--st-y:0px;
  transform:translate3d(0,var(--st-y),0) scale(var(--st-s));
  transition:--st-s 1.8s var(--ease),filter .7s var(--ease)}
.staff.in img,.staff.sx-in img,.reveal.in.staff img,.reveal.in .st-drift{--st-s:1}
.staff:hover img{--st-s:1.03}
@media (prefers-reduced-motion:reduce){
  .staff img,.st-drift{--st-s:1 !important;--st-y:0px !important;transition:none !important}
}


/* The closing statement and the order link sit hard left, with the body
   copy above them, rather than centred in the column. */
.article .statement{text-align:left !important}
.article .order-row{justify-content:flex-start !important}


/* The story photographs are shown COMPLETE, so they must not be scaled:
   a 1.06 settle pushed each one ~17px past its frame and quietly cropped
   the very edges the full-frame treatment exists to preserve. These keep
   the drift (pure translation, nothing lost) and drop the scale. Overflow
   is visible so the drift itself cannot clip them either.
   The split image on the Dubai page is object-fit:cover and is meant to
   fill its column, so it keeps the settle. */
.article-body figure.staff{overflow:visible}
.article-body figure.staff img{--st-s:1 !important}
.article-body figure.staff img,
.article > .container.narrow.reveal img{
  transform:translate3d(0,var(--st-y),0);
}


/* The blend overlay is painted on the FRAME (inset:0). With a portrait image
   in a 900px column the frame was 900 wide and the picture only ~550, so the
   overlay carried on across ~350px of empty page as a grey band. The frame
   now hugs its image. */
.article-body figure.staff{width:fit-content;max-width:100%}

/* ---- the two story photographs, side by side -------------------------
   Both are portrait. Alone in a 900px column each one left a wide band of
   empty page beside it; as a pair they fill the measure and read as one
   moment in the kitchen rather than two unrelated pictures.

   Neither is cropped — the frames keep their own proportions, so the two
   differ in height by about 3%. They are top-aligned, which makes that
   read as a deliberate pair rather than a failed attempt at symmetry. */
.staff-pair{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(12px,1.6vw,22px);
  align-items:start;
  margin:34px 0;
}
.staff-pair figure.staff{width:100%;max-width:none;margin:0}
.staff-pair figure.staff img{
  width:100%;height:auto;max-height:none;object-fit:contain;
}
@media (max-width:640px){
  .staff-pair{grid-template-columns:1fr;gap:18px}
}


/* The drift now lives on the frame so the picture and its blend overlay move
   as one. The image itself keeps only its settle. */
figure.staff.st-drift,
.split .ph.staff.st-drift,
.article > .container.narrow.reveal.st-drift{
  transform:translate3d(0,var(--st-y,0px),0);
}
.article-body figure.staff img,
.staff-pair figure.staff img,
.article > .container.narrow.reveal img{transform:none}


/* ---- long-form body copy -------------------------------------------
   A global `p{color:var(--muted);font-weight:400}` was making every
   paragraph heavier than the 300 the rest of the site sets on <body>, and
   painting it in the muted grey meant for captions and labels. On a page
   of running text that reads both heavier and weaker than everything
   around it — the headings are 300, the paragraphs were 400.

   Scoped to the article body so captions, labels and short UI paragraphs
   elsewhere keep the muted treatment they were designed for. */
.article-body p{
  font-weight:300;
  color:#332F29;          /* soft ink — 11.7:1 on the warm white */
  font-size:18px;
  line-height:1.78;
  letter-spacing:.005em;
}
.article-body p.big{font-weight:200;letter-spacing:.012em}
.article-body h2{font-weight:200;letter-spacing:.01em}

/* .article-body p out-specifies .statement (0,1,1 vs 0,1,0), so the new
   letter-spacing above flattened the closing line's tracking from .34em to
   almost nothing. Restated here at the same weight as the rule that broke it. */
.article-body p.statement{letter-spacing:.34em;text-transform:uppercase}


/* The two sign-off lines carry a little more weight than the copy above
   them — the rest of the page sits at 200-300, so 400 reads as a close
   rather than as another paragraph. Scoped to these two lines only; the
   other .big leads stay light. */
.article-body p.big.closing-line{font-weight:400}
.article-body p.statement{font-weight:400}

/* ======================= OUR STORY — chaptered ========================
   The page was a single long column: title, photo, then everything in one
   run. Same copy, restructured so it reads as four chapters.

     · a cinematic dark opening, matching the city pages, so the story
       starts like a chapter rather than a blog post;
     · numbered chapters with the heading held in a STICKY left column, so
       you always know which part you are in while the copy scrolls;
     · the client's short standalone lines set as pull quotes rather than
       as more body copy — they were written to land, and in a plain column
       they read as stray sentences;
     · a charcoal sign-off band to close.
   Nothing here changes a word of the supplied copy. */

/* ---- opening ---- */
.os-hero{position:relative;min-height:min(66svh,620px);display:flex;align-items:flex-end;
  overflow:hidden;padding-bottom:clamp(40px,6vh,72px)}
.os-hero .bg{position:absolute;inset:0;background-size:cover;background-position:center;
  filter:brightness(.62) saturate(.9) contrast(1.04);transform:scale(1.04)}
.os-hero .grade{position:absolute;inset:0;
  background:linear-gradient(to bottom,rgba(10,10,10,.62),rgba(10,10,10,.30) 42%,rgba(10,10,10,.86))}
.os-hero .container{position:relative;z-index:2}
.os-hero .eyebrow{color:var(--gold)}
.os-hero h1{color:#F2EEE7;margin:14px 0 0}
.os-lede{margin-top:18px;font-size:clamp(16px,1.6vw,21px);font-weight:300;
  letter-spacing:.18em;text-transform:uppercase;color:rgba(242,238,231,.72)}

/* ---- standfirst ---- */
.os-intro .container{padding-top:clamp(8px,1.4vw,18px)}
.os-intro p{font-size:clamp(18px,1.55vw,21px);line-height:1.72;color:#2E2A24}

/* ---- chapters ---- */
.os-ch{padding-top:clamp(46px,5vw,74px);padding-bottom:clamp(46px,5vw,74px)}
.os-ch-dark{background:var(--charcoal-2)}
.os-grid{display:grid;grid-template-columns:clamp(240px,26vw,330px) 1fr;
  gap:clamp(30px,4.5vw,74px);align-items:start}
.os-side{position:sticky;top:calc(var(--hdr,109px) + 28px)}
.os-num{display:block;font-size:12px;letter-spacing:.42em;color:var(--gold);
  margin-bottom:14px}
.os-side h2{font-size:clamp(26px,2.6vw,38px);font-weight:200;line-height:1.16;
  letter-spacing:.008em;margin:0}
.os-copy > p{margin-bottom:22px;font-size:18px;line-height:1.78;font-weight:300;
  color:#332F29;letter-spacing:.005em}
.os-copy > p:last-child{margin-bottom:0}

/* the dish roll-call and the four beats are lists in prose — spaced a
   little wider so they read as a rhythm rather than a sentence */
/* superseded by the unified scale below — these !important declarations were
   still winning and holding the two lines at 20px/#2E2A24 */
.os-list,.os-beats{line-height:1.95}

/* ---- pull quotes ---- */
.os-pull{margin:34px 0;padding-left:22px;border-left:2px solid var(--gold-dim);
  font-family:var(--display);font-weight:200;
  font-size:clamp(23px,2.6vw,34px);line-height:1.34;letter-spacing:.008em;
  color:#1A1815}
.os-pull-gold{color:var(--gold);border-left-color:var(--gold)}
.os-closing-line{font-family:var(--display);font-weight:400;
  font-size:clamp(21px,2.2vw,29px) !important;line-height:1.4 !important;
  color:#1A1815 !important;margin-top:30px}

/* ---- sign-off ---- */
/* body.light REDEFINES --charcoal to the warm white, so var(--charcoal)
   here painted the band cream and the near-white link disappeared into it.
   Literal value, plus the palette re-inverted inside so everything in the
   band is light-on-dark. */
.os-signoff{background:#121211;padding:clamp(56px,7vw,96px) 0;
  --warm-white:#F2EEE7;--muted:#B0A99D;--muted-2:#8C867B;
  --gold:#B08F4A;--gold-dim:rgba(176,143,74,.38);
  --hair:rgba(242,238,231,.13);--hair-soft:rgba(242,238,231,.07);
  color:#F2EEE7}
.os-signoff .statement{font-size:clamp(15px,2vw,20px);font-weight:400;
  color:var(--gold);letter-spacing:.34em;text-transform:uppercase;text-align:left;margin:0}
.os-signoff .order-row{display:flex;margin-top:30px}
.os-signoff .btn-line{color:#F2EEE7 !important;border-bottom-color:rgba(176,143,74,.5)}
.os-signoff .btn-line:hover{color:#B08F4A !important;border-bottom-color:#B08F4A}

@media (max-width:900px){
  .os-grid{grid-template-columns:1fr;gap:20px}
  .os-side{position:static;top:auto}
  .os-num{margin-bottom:8px}
  .os-pull{margin:26px 0}
}


/* ================= OUR STORY — one type scale ========================
   The redesign moved the copy out of .article-body, so the typography rules
   written for that container stopped matching and the global
   `p{color:var(--muted);font-weight:400}` took back over in places. The page
   ended up with THREE different inks for running text — #2E2A24, #332F29
   and #1A1815 — and a mix of 300 and 400 weights at 18px, 20px and 21px.

   One scale now, two levels only:
     · running copy  — 18px / 300 / #332F29
     · headings, pull quotes and the sign-off — #1A1815, lighter weights,
       larger sizes. That contrast is deliberate hierarchy, not drift.
   Gold is reserved for the chapter numbers, the eyebrow and the sign-off. */

/* running copy — every paragraph on the page, one colour and one weight */
.os-intro p,
.os-copy > p,
.os-list,
.os-beats{
  font-size:18px;
  line-height:1.78;
  font-weight:300;
  color:#332F29;
  letter-spacing:.005em;
}
/* the roll-call and the four beats keep only their wider leading */
.os-list,.os-beats{line-height:1.95}

/* display level — headings and pull quotes share one ink and one weight */
.os-side h2,
.os-pull{color:#1A1815;font-weight:200}
.os-pull-gold{color:var(--gold)}

/* the closing line is the sign-off's opening half, so it matches its weight */
.os-closing-line{font-weight:400 !important;color:#1A1815 !important}

/* ---- the paired photographs, matched exactly ------------------------
   Shown at their natural ratios the two frames differed in height (573 vs
   589) because the source files differ. A shared ratio makes them a true
   pair; the crop is small and framed to keep the hands and the food. */
.staff-pair figure.staff img{
  aspect-ratio:4/5;
  height:auto;
  object-fit:cover;
}
.staff-pair figure.staff:nth-child(1) img{object-position:50% 34%}
.staff-pair figure.staff:nth-child(2) img{object-position:52% 30%}

/* both frames are the same box, so the pair matches exactly rather than
   differing by a rounded pixel */
/* aspect-ratio is computed from each frame's OWN width, and the two grid
   columns round differently by a fraction of a pixel — so the frames came
   out 459 and 460. One explicit height for both removes the rounding from
   the equation entirely. */
.staff-pair figure.staff{aspect-ratio:auto;height:min(32vw,460px);overflow:hidden}
.staff-pair figure.staff img{width:100%;height:100%;object-fit:cover}
/* the eyebrow sat at 400 while the chapter numerals were 300 — same role,
   same weight */
.os-hero .eyebrow{font-weight:300}

@media (max-width:640px){.staff-pair figure.staff{height:min(78vw,420px)}}


/* ---- menu category tabs: hover and selected use the full gold --------
   body.light .tab.active was declared twice — the later rule set #1A1815,
   so the selected tab rendered the same ink as hover and the brand gold
   never appeared at all. Both states now carry the full colour, and the
   selected tab gets a full-strength gold rule beneath it rather than the
   older, weaker #9C7B27. */
body.light .tab:hover{color:var(--gold)}
body.light .tab.active{
  color:var(--gold);
  border-bottom-color:var(--gold);
}
/* the selected tab also sits on a faint wash of the same gold, so the
   choice is legible at a glance and not only from the rule underneath */
body.light .tab.active{background:var(--gold-faint)}
.tab{transition:color .32s var(--ease),border-color .32s var(--ease),background .32s var(--ease)}


/* ============ MENU: alternating category grounds ======================
   The seven categories alternate charcoal / warm white down the page:

     1 Poppadoms & Chutneys   charcoal
     2 Starters               warm white
     3 The Classics           charcoal
     4 Curry Mile Specials    warm white
     5 Breads & Rice          charcoal
     6 Sides                  warm white
     7 Desserts & Drinks      charcoal

   menu.js builds these from menu-data.js, so there is no class in the
   markup to hang this on — they are targeted by their DATA IDS. If a
   category id changes in the data file, its ground silently changes with
   it, so these four ids are load-bearing.

   Re-declaring the palette covers everything that paints through a
   variable. It cannot reach the body.light rules that hard-code colours
   (heading, dish name, description, dividers, the six dietary tags) —
   those out-specify a variable swap, so each is restated below. */
body.light:not(.look-cream) #poppadoms,
body.light:not(.look-cream) #curries,
body.light:not(.look-cream) #breads,
body.light:not(.look-cream) #desserts{
  --charcoal:#121211;
  --charcoal-2:#191817;
  --charcoal-3:#211F1D;
  --warm-white:#F2EEE7;
  --muted:#B0A99D;
  --muted-2:#8C867B;
  --gold:#B08F4A;
  --gold-dim:rgba(176,143,74,.38);
  --gold-faint:rgba(176,143,74,.14);
  --hair:rgba(242,238,231,.13);
  --hair-soft:rgba(242,238,231,.07);
  background:#121211;
  color:#F2EEE7;
  border-color:rgba(242,238,231,.14);
}
body.light:not(.look-cream) #poppadoms h2,
body.light:not(.look-cream) #curries h2,
body.light:not(.look-cream) #breads h2,
body.light:not(.look-cream) #desserts h2{color:#F2EEE7}
body.light:not(.look-cream) #poppadoms .cat-note,
body.light:not(.look-cream) #curries .cat-note,
body.light:not(.look-cream) #breads .cat-note,
body.light:not(.look-cream) #desserts .cat-note{color:#B0A99D}
body.light:not(.look-cream) #poppadoms .mi .n,
body.light:not(.look-cream) #curries .mi .n,
body.light:not(.look-cream) #breads .mi .n,
body.light:not(.look-cream) #desserts .mi .n{color:#F2EEE7}
body.light:not(.look-cream) #poppadoms .mi:hover .n,
body.light:not(.look-cream) #curries .mi:hover .n,
body.light:not(.look-cream) #breads .mi:hover .n,
body.light:not(.look-cream) #desserts .mi:hover .n{color:#B08F4A}
body.light:not(.look-cream) #poppadoms .mi .d,
body.light:not(.look-cream) #curries .mi .d,
body.light:not(.look-cream) #breads .mi .d,
body.light:not(.look-cream) #desserts .mi .d{color:#B0A99D}
body.light:not(.look-cream) #poppadoms .mi,
body.light:not(.look-cream) #curries .mi,
body.light:not(.look-cream) #breads .mi,
body.light:not(.look-cream) #desserts .mi{border-bottom-color:rgba(242,238,231,.10)}

/* dietary marks back to their light-on-dark values */
body.light:not(.look-cream) #poppadoms .mi .tag-v,
body.light:not(.look-cream) #curries .mi .tag-v,
body.light:not(.look-cream) #breads .mi .tag-v,
body.light:not(.look-cream) #desserts .mi .tag-v,
body.light:not(.look-cream) #poppadoms .mi .tag-ve,
body.light:not(.look-cream) #curries .mi .tag-ve,
body.light:not(.look-cream) #breads .mi .tag-ve,
body.light:not(.look-cream) #desserts .mi .tag-ve{color:#7FBF8A;border-color:rgba(127,191,138,.42)}
body.light:not(.look-cream) #poppadoms .mi .tag-gf,
body.light:not(.look-cream) #curries .mi .tag-gf,
body.light:not(.look-cream) #breads .mi .tag-gf,
body.light:not(.look-cream) #desserts .mi .tag-gf{color:#8FBEDB;border-color:rgba(143,190,219,.42)}
body.light:not(.look-cream) #poppadoms .mi .tag-signature,
body.light:not(.look-cream) #curries .mi .tag-signature,
body.light:not(.look-cream) #breads .mi .tag-signature,
body.light:not(.look-cream) #desserts .mi .tag-signature{color:#B08F4A;border-color:rgba(176,143,74,.48)}
body.light:not(.look-cream) #poppadoms .mi .tag-mild,
body.light:not(.look-cream) #curries .mi .tag-mild,
body.light:not(.look-cream) #breads .mi .tag-mild,
body.light:not(.look-cream) #desserts .mi .tag-mild{color:#B0A99D;border-color:rgba(176,169,157,.36)}
body.light:not(.look-cream) #poppadoms .mi .tag-medium,
body.light:not(.look-cream) #curries .mi .tag-medium,
body.light:not(.look-cream) #breads .mi .tag-medium,
body.light:not(.look-cream) #desserts .mi .tag-medium{color:#E0A46A;border-color:rgba(224,164,106,.42)}
body.light:not(.look-cream) #poppadoms .mi .tag-hot,
body.light:not(.look-cream) #curries .mi .tag-hot,
body.light:not(.look-cream) #breads .mi .tag-hot,
body.light:not(.look-cream) #desserts .mi .tag-hot{color:#E08A7A;border-color:rgba(224,138,122,.45)}


/* The stats figures carry white-space:nowrap, and turning them into caps
   with .07em tracking made the widest of them ("99% BRITISH") wider than
   its column on a phone — pushing the whole document to 420px against a
   390px viewport. On narrow screens they wrap and the tracking eases. */
@media (max-width:640px){
  .num b{
    white-space:normal;
    letter-spacing:.04em;
    font-size:clamp(19px,5.4vw,26px);
    line-height:1.16;
  }
}


/* "Order on Curry Mile app" at 13px with .28em tracking plus 36px of padding
   each side is wider than a 390px viewport, and the button is an inline-flex
   that will not shrink — so it pushed the document 8px wide. On phones the
   button goes full width and the tracking eases. */
@media (max-width:640px){
  .order-direct .btn-gold{
    width:100%;
    justify-content:center;
    padding:16px 18px;
    letter-spacing:.16em;
    font-size:12px;
  }
  .order-direct{flex-wrap:wrap}
}


/* ================= OUR STORY: one spine =============================
   The page had THREE left edges: the hero title, intro and sign-off sat in
   a .narrow container at 310; chapter headings at 144; chapter copy at 539.
   The opening paragraph therefore lined up with nothing below it.

   Everything now hangs off the chapter grid — headings on the left column,
   running copy on the right — so the eye follows a single spine from the
   title to the sign-off. */
.os-hero .container,
.os-intro .container,
.os-signoff .container{max-width:var(--maxw)}
/* .os-hero is a flex container, so its .container was a flex ITEM sizing to
   its own content (~860px) and centring — which is why the title sat at 290
   while everything below started at 144. It has to fill the line. */
.os-hero .container{width:100%;flex:1 1 100%}

/* the standfirst drops into the copy column, exactly where every chapter
   paragraph below it begins */
.os-intro .container{
  display:grid;
  grid-template-columns:clamp(240px,26vw,330px) 1fr;
  /* COLUMN gap only. `gap` sets both axes, and since each paragraph is its
     own grid row that added ~74px between every paragraph on top of their
     own margins. The paragraphs keep their normal 22px rhythm. */
  column-gap:clamp(30px,4.5vw,74px);
  row-gap:0;
}
.os-intro .container > *{grid-column:2}

@media (max-width:900px){
  /* single column on tablet and phone, matching the chapters */
  .os-intro .container{grid-template-columns:1fr;column-gap:0;row-gap:0}
  .os-intro .container > *{grid-column:1}
}

/* .os-intro p had no bottom margin of its own — the spacing between those
   paragraphs was coming from the grid row-gap, so removing that gap butted
   them together. Same 22px rhythm as every other paragraph on the page. */
.os-intro p{margin-bottom:22px}
.os-intro p:last-child{margin-bottom:0}

/* The poppadoms photograph sits inside chapter 02, which is the charcoal
   band — so it takes the same dark blend treatment as the staff images and
   sits in the copy column at a landscape crop rather than as a portrait. */
.os-copy figure.os-fig{width:100%;height:auto;max-width:none;margin:30px 0;aspect-ratio:auto}
.os-copy figure.os-fig img{
  width:100%;height:auto;max-height:none;
  aspect-ratio:16/10;object-fit:cover;object-position:50% 56%;
}


/* ---- Download our app, in the footer --------------------------------
   Store links verified live on 8 Sep 2026 rather than assumed:
     Apple      apps.apple.com/ae/app/curry-mile/id6751896377  -> "Curry Mile App"
     Google Play play.google.com/...id=com.currymile.ordering  -> "Curry Mile"
   Both open in a new tab with rel="noopener". */
.f-app-note{margin:-4px 0 14px;font-size:12.5px;line-height:1.6;color:var(--muted-2)}
.f-app-links{display:flex;flex-direction:column;gap:10px}
.f-store{
  display:inline-flex;align-items:center;gap:11px;
  padding:9px 14px;
  border:1px solid var(--hair);
  color:var(--muted);
  transition:border-color .4s var(--ease),color .4s var(--ease),background .4s var(--ease);
}
.f-store svg{width:19px;height:19px;flex:none}
.f-store span{display:flex;flex-direction:column;line-height:1.15}
.f-store i{font-style:normal;font-size:8.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted-2)}
.f-store b{font-weight:400;font-size:13px;letter-spacing:.04em;color:var(--warm-white)}
.f-store:hover{border-color:var(--gold);color:var(--gold);background:var(--gold-faint)}
.f-store:hover b,.f-store:hover i{color:var(--gold)}

@media (max-width:1100px){
  footer.site .cols{grid-template-columns:1.4fr 1fr 1fr 1fr}
  .f-app{grid-column:1 / -1;margin-top:6px}
  .f-app-links{flex-direction:row;flex-wrap:wrap}
}
@media (max-width:640px){
  .f-app-links{flex-direction:column}
  .f-store{width:100%;max-width:250px}
}

/* The footer is charcoal on EVERY page, including the light ones — where
   body.light redefines --warm-white to ink. Using the variable here painted
   the store names ink-on-charcoal at 1.12:1. Literal values, since this
   block never appears on a light ground. */
footer.site .f-store{border-color:rgba(242,238,231,.14);color:#B0A99D}
footer.site .f-store b{color:#F2EEE7}
footer.site .f-store i{color:#8C867B}
footer.site .f-app-note{color:#8C867B}
footer.site .f-store:hover{border-color:#B08F4A;background:rgba(176,143,74,.10)}
footer.site .f-store:hover b,
footer.site .f-store:hover i,
footer.site .f-store:hover{color:#B08F4A}

/* ═══════════ Page Dubai — retours client du 14/09 ═══════════ */

/* 1 · « VIEW MENU looks too close to the description above. Maybe a little
   colour change may be enough. » C'était une ligne pleine largeur du même
   poids que le paragraphe. C'est maintenant un bouton or, détaché. */
.hero .hero-cta{margin-top:clamp(30px,4.2vw,50px)}
.hero .hero-cta .btn-gold{background:rgba(18,18,17,.34)}
body.light .hero .hero-cta .btn-gold{border-color:var(--gold);color:var(--gold)}
body.light .hero .hero-cta .btn-gold:hover{background:var(--gold);color:#121211}

/* 2 · « There is no flow here. » Le hero sombre butait sur la bande sombre :
   deux noirs voisins mais différents, donc une couture au lieu d'une suite.
   Le hero se fond maintenant EXACTEMENT sur la couleur de la bande, la bande
   perd son entrée trop creuse, et sa sortie vers le crème devient un filet
   assumé plutôt qu'une coupure. */
body.light.has-hero .hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:clamp(90px,12vh,170px);
  background:linear-gradient(180deg,rgba(18,18,17,0),#121211);
  pointer-events:none;z-index:1;
}
body.light.has-hero .hero .container{position:relative;z-index:2}
body.light .section.band-dark{
  padding-top:clamp(40px,5.2vw,74px);
  border-bottom:1px solid var(--gold-dim);
}

/* 3 · « There is a repetition of DUBAI here, maybe try and include the partner
   logos in small to give it a little depth and color. But please keep it
   small. »
   Premier essai : les logos posés directement sur le charbon. Raté, et pour une
   raison de fond : trois des quatre marques ont DÉJÀ leur propre cartouche de
   couleur (Deliveroo, Talabat, Noon) tandis que Careem est un mot vert foncé
   nu, qui disparaissait. Poser une plaque blanche derrière chacun aurait fait
   trois boîtes dans une boîte.
   La rangée entière passe donc sur une seule plaque ivoire : un seul contenant,
   quatre logos lisibles, et la couleur demandée qui ressort enfin du fond. */
.partners .partner-row{
  background:var(--warm-white);
  border:0;border-radius:3px;overflow:hidden;
}
.partner{
  display:flex;align-items:center;justify-content:center;
  padding:22px 14px;
  border-bottom:0;border-right:1px solid rgba(18,18,17,.10);
  transition:background .45s var(--ease);
}
.partner:last-child{border-right:0}
.partner:hover{background:rgba(18,18,17,.045)}
.plogo{
  height:21px;width:auto;max-width:100%;display:block;
  transition:transform .45s var(--ease);
}
.partner:hover .plogo{transform:translateY(-1px)}
/* Poids optique : un mot nu paraît plus gros qu'un logo enfermé dans un
   cartouche. Deliveroo et Careem sont nus, Talabat et Noon sont encadrés.
   (Le lockup Deliveroo turquoise sur fond clair a été fourni par le client le
   14/09 ; l'ancien cartouche turquoise à texte blanc ne tenait pas ici.) */
.plogo--deliveroo{height:21px}
.plogo--careem{height:17px}
.plogo--noon{height:24px}
@media (max-width:760px){
  .partner{padding:18px 12px}
  /* deux par ligne : la séparation verticale de la 1re colonne seulement */
  .partner:nth-child(2n){border-right:0}
  .partner:nth-child(-n+2){border-bottom:1px solid rgba(18,18,17,.10)}
  .plogo{height:19px}
  .plogo--deliveroo{height:19px}
  .plogo--careem{height:15.5px}
  .plogo--noon{height:22px}
}

/* 4 · « For order direct please include the appstore and google play logos
   here, so customers can understand immediately that this is an app. » */
.od-act{display:flex;flex-direction:column;align-items:flex-end;gap:16px}
.od-badges{display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:flex-end}
.od-badges img{height:38px;width:auto;display:block;
  transition:opacity .4s var(--ease),transform .4s var(--ease)}
.od-badges a{display:block;opacity:.92}
.od-badges a:hover{opacity:1}
.od-badges a:hover img{transform:translateY(-2px)}
@media (max-width:760px){
  .od-act{align-items:flex-start;width:100%}
  .od-badges{justify-content:flex-start}
  .od-badges img{height:34px}
}

/* 5 · (removed 14 Sep) The Order Direct box was briefly a warm white panel;
   the client asked for it back to black. It is the original charcoal box
   again — the rules above at .order-direct / .band-dark apply unchanged. */

/* 6 · Our Story hero, to the client's mock (14 Sep): title on the left over
   the window light, the man at the table on the right, the photograph close
   to natural rather than graded down. The client then supplied the WIDE
   version of the photo (1280x533), so it is one layer again — the earlier
   square-photo build blurred a second copy across the left, which showed as a
   ghosted double of the man at some widths.
   Below 820px the band turns portrait, so the crop moves onto the man and
   the title sits on a bottom scrim. */
.os-hero--window{background:#0D1A19;align-items:center;
  min-height:clamp(440px,36vw,580px);
  padding:clamp(96px,8vw,120px) 0 clamp(36px,4vw,56px)}
.os-hero--window .bg{background-size:cover;background-position:62% 42%;
  filter:none;transform:none}
.os-hero--window .grade{
  background:
    linear-gradient(to bottom,rgba(6,10,10,.50) 0,rgba(6,10,10,0) 26%),
    linear-gradient(to right,rgba(6,12,11,.62) 0,rgba(6,12,11,.36) 40%,rgba(6,12,11,0) 64%)}
.os-hero--window h1{font-size:clamp(32px,3.2vw,48px);line-height:1.14;max-width:15em}
.os-hero--window h1 .h1-break{display:block}
.os-hero--window .os-lede{margin-top:14px}
/* the muted brass eyebrow sank into the lit window panes behind it */
.os-hero--window .eyebrow{color:#CFAE66;font-weight:400;text-shadow:0 1px 14px rgba(0,0,0,.55)}
@media (max-width:819px){
  .os-hero--window{align-items:flex-end;min-height:min(78svh,620px)}
  .os-hero--window .bg{background-position:66% 50%}
  .os-hero--window .grade{background:
    linear-gradient(to bottom,rgba(6,10,10,.45) 0,rgba(6,10,10,0) 24%,
      rgba(6,10,10,0) 44%,rgba(6,10,10,.84) 100%)}
}

/* 7 · Partner row: typeset names back, brand SYMBOL underneath (client,
   14 Sep: "keep the way the names are written … the partner logo just under,
   replacing the DUBAI words … just the logo and not the full name").
   The ivory plate stays: Careem's symbol is dark green and vanishes on
   charcoal. Each .pmark is a fixed window onto the untouched logo file,
   sized in units of its own height and anchored left, so only the symbol
   shows — Deliveroo's kangaroo, Careem's smile-C, Noon's ring on its yellow
   square. Talabat's file has no symbol separate from the wordmark, so its
   small orange cartouche is shown whole. */
.partner--named{flex-direction:column;gap:11px;padding:24px 10px 22px;
  font-size:14px;text-transform:uppercase;letter-spacing:.26em;text-indent:.26em;
  color:#1A1815;opacity:1}
.partner--named .pname{display:block;line-height:1;font-weight:400}
.partner--named:hover{color:#755A18}
.pmark{--h:24px;display:block;height:var(--h);overflow:hidden;
  transition:transform .45s var(--ease)}
.pmark img{height:100%;width:auto;max-width:none;display:block}
.pmark--deliveroo{width:calc(var(--h) * .96)}
.pmark--careem{width:calc(var(--h) * .96)}
.pmark--noon{width:calc(var(--h) * 1.02);border-radius:2px}
.pmark--talabat{--h:20px;margin-block:2px}
.partner--named:hover .pmark{transform:translateY(-1px)}
@media (max-width:760px){
  .partner--named{padding:20px 8px 18px;font-size:12.5px;letter-spacing:.2em;text-indent:.2em}
  .pmark{--h:21px}
  .pmark--talabat{--h:18px;margin-block:1.5px}
}

/* 8 · Order Direct on tablet (14 Sep). The row only wraps when the offer text
   and the actions stop fitting side by side — measured at 870px — but the
   badges switched to left alignment at 760px. From 761 to 870 the button sat
   on the left and the badges stayed right-aligned under its far end. The box
   now stacks deliberately at 880px and below, and the badges start on the
   button's left edge from the same width. */
@media (max-width:880px){
  .order-direct{flex-direction:column;align-items:flex-start}
  .od-act{align-items:flex-start;width:100%}
  .od-badges{justify-content:flex-start}
}


/* 9 · MENU PREVIEW: ?look=cream (client, 14 Sep: "can we use the colour used
   behind READY TO ORDER for all the menu items and sections. I still can't
   decide which one will look the best."). Opt-in only: menu.html?look=cream
   adds body.look-cream before the page paints, the four charcoal category
   rules above stand down (they are scoped :not(.look-cream)), and every
   category card takes the exact ground of the "Ready to order?" box — a 7%
   to 2% brass wash over warm white, #F0EADC at the top to #F4F0E6 at the
   foot. Without the parameter the page is unchanged.
   Contrast on the darker top, measured: ink 14.8, descriptions 7.3, dietary
   tags 5.3-6.0, bronze 4.54 (AA). To adopt it for good, add look-cream to
   the <body> class; to drop it, delete this block and the script in menu.html. */
body.light.look-cream .menu-book{
  background:linear-gradient(180deg,rgba(156,123,39,.07),rgba(156,123,39,.02)),#F6F2EA;
  border-left-color:rgba(156,123,39,.34);
  border-right-color:rgba(156,123,39,.34);
  border-bottom-color:rgba(156,123,39,.34);
  box-shadow:0 22px 44px -34px rgba(90,70,20,.30);
}

/* 10 · App Store and Google Play badges at the SAME visible height (client,
   14 Sep). Apple's SVG is the badge edge to edge; Google's PNG (646x250)
   carries 41px of transparent padding on every side, so its black badge is
   only 168/250 of the image. At equal image heights Google read a third
   smaller. The PNG is scaled by 250/168 and pulled back by its padding with
   negative margins, so the visible badges match and the gap stays 12px.
   Both files untouched. */
.od-badges{--bh:38px}
.od-badges img[src*="google-play"]{
  height:calc(var(--bh) * 250 / 168);width:auto;
  max-width:none; /* the global img max-width squeezed it ~13% narrower */
  margin:calc(var(--bh) * -41 / 168);
}
@media (max-width:760px){ .od-badges{--bh:34px} .od-badges img{height:var(--bh)} }

/* 11 · Store badges CENTRED under the "Order on Curry Mile app" button
   (client, 14 Sep). .od-act shrinks to the button's width and the badge row
   centres inside it, so the pair sits on the button's centre line whether the
   box is side by side (desktop), stacked with the button at its own width
   (641-880px), or stacked with a full-width button (phones). */
.od-act{align-items:stretch}
.od-badges{justify-content:center}
@media (max-width:880px){
  .od-act{width:auto;align-items:stretch}
  .od-badges{justify-content:center}
}
@media (max-width:640px){
  .od-act{width:100%}
}

/* 12 · Dubai hero: "View Menu" button lowered (Jane, 14 Sep). The gap under
   the paragraph was 30-50px; it now reads as a separate step rather than a
   continuation of the copy. Only dubai.html uses .hero-cta. */
.hero .hero-cta{margin-top:clamp(48px,6.2vw,84px)}

/* 13 · Partner row on BLACK, matching the Order Direct box above it (Jane,
   14 Sep): the same faint brass wash and gold hairline instead of the ivory
   plate, warm-white names turning gold on hover. Deliveroo teal, Talabat
   orange and Noon yellow all hold on charcoal; Careem's symbol is dark green
   (#004F3F-ish) and vanished, so it is shown as a white reversed mark via CSS
   filter — the file is untouched. */
.band-dark .partners .partner-row{
  background:linear-gradient(180deg,rgba(176,143,74,.08),rgba(176,143,74,.03));
  border:1px solid var(--gold-dim);border-radius:0;
}
.band-dark .partner{border-right-color:rgba(242,238,231,.10)}
.band-dark .partner:hover{background:rgba(176,143,74,.07)}
.band-dark .partner--named{color:#F2EEE7}
.band-dark .partner--named:hover{color:#B08F4A}
/* Careem stays in its own green (Jane, 14 Sep) — the white reversed mark
   that was here was removed at her request. */
@media (max-width:760px){
  .band-dark .partner:nth-child(-n+2){border-bottom-color:rgba(242,238,231,.10)}
}

/* 14 · Closing "Tonight, we're having a curry." on phones and tablets
   (Jane, 14 Sep: "isn't this section too big for a mobile view?"). The band
   was 78svh (~660px on a phone) while the photo is drawn with `contain` to
   keep the whole 16:9 frame — so on a 390px screen the picture was a 219px
   strip floating in ~440px of black. Below 901px the band now takes the
   photograph's own 16:9 height, never less than 400px so the heading and
   button fit, and the photo covers it: no black bands. Desktop is unchanged
   (whole frame, contain). Also applies to the unlinked abu-dhabi.html. */
@media (max-width:900px){
  .finale{min-height:max(56.25vw,400px);padding-block:56px}
  .finale .bg{background-size:cover}
  /* the text scrim's ellipse was cut off by its own box, so in the shorter
     band it showed as a hard-edged dark rectangle; closest-side makes it
     reach zero exactly at the box edge */
  .finale .container::before{
    inset:-38% -24%;
    background:radial-gradient(closest-side,
      rgba(10,10,10,.84) 0%,rgba(10,10,10,.74) 45%,
      rgba(10,10,10,.42) 75%,rgba(10,10,10,0) 100%);
  }
}

/* 15 · Closing band on laptop and desktop (Jane, 14 Sep: "lower the text and
   the button a bit"). Three changes, 901px and up:
   · the heading + button block sits ~65px lower (the flex box still centres
     it, the extra top padding pushes the centre down);
   · the text scrim fades to zero at its own edges — its ellipse was clipped
     by its box and painted a hard-edged dark rectangle across the photo;
   · the photo covers the band. At 88vh the band is a little wider than the
     16:9 frame on most laptop screens, so `contain` left thin black strips
     down both sides; cover trims ~1-2% top and bottom instead. */
@media (min-width:901px){
  .finale{padding-top:clamp(96px,15vh,150px)}
  .finale .bg{background-size:cover}
  .finale .container::before{
    inset:-46% -18%;
    background:radial-gradient(closest-side,
      rgba(10,10,10,.84) 0%,rgba(10,10,10,.74) 45%,
      rgba(10,10,10,.42) 75%,rgba(10,10,10,0) 100%);
  }
}

/* 16 · Order band FLOW (Jane, 14 Sep: "something is not looking right, there
   is no flow"). Two fully framed boxes stacked one under the other read as
   two unrelated panels. The Order Direct box keeps its frame; the partner
   row below loses its own box and becomes an open strip: the label is set
   centred between two gold hairlines, as a divider that hands the eye down
   from the box, and the four partners are separated by hairlines only. Brief
   intact: charcoal ground, gold as hairlines, no fills. */
.band-dark .partners{margin-top:clamp(34px,4vw,54px)}
.band-dark .partners .lbl{
  display:flex;align-items:center;gap:22px;
  margin-bottom:clamp(8px,1vw,14px);text-align:center;
  color:#B0A99D;
}
.band-dark .partners .lbl::before,
.band-dark .partners .lbl::after{content:"";flex:1;height:1px;
  background:linear-gradient(90deg,rgba(176,143,74,0),rgba(176,143,74,.45))}
.band-dark .partners .lbl::after{
  background:linear-gradient(90deg,rgba(176,143,74,.45),rgba(176,143,74,0))}
.band-dark .partners .partner-row{background:none;border:0}
.band-dark .partner{border-right-color:rgba(242,238,231,.09);padding-block:18px 14px}
.band-dark .partner:hover{background:none}
@media (max-width:760px){
  .band-dark .partners .lbl{gap:14px}
  .band-dark .partner:nth-child(-n+2){border-bottom-color:rgba(242,238,231,.09)}
}

/* 17 · Dubai hero "View Menu" more prominent (client, 14 Sep: "should remain
   smaller or a little more prominent … maybe a little colour change may be
   enough"). Thin gold type on a gold hairline all but disappeared on the
   photograph. Warm white label on a faint brass wash inside the gold frame
   now reads as the page's primary action; hover fills brass. Same size and
   position. */
body.light .hero .hero-cta .btn-gold{
  color:#F2EEE7;border-color:#B08F4A;background:rgba(176,143,74,.18);
  font-weight:400;
}
body.light .hero .hero-cta .btn-gold:hover{background:#B08F4A;color:#121211}

/* 18 · Dubai hero "View menu": smaller and not in capitals (Jane, 14 Sep).
   Sentence case at 15px with near-normal tracking; padding cut from
   17/36 to 12/24. Keeps the warm white label, brass wash and gold frame. */
body.light .hero .hero-cta .btn-gold{
  padding:12px 24px;gap:10px;
  font-size:15px;letter-spacing:.02em;text-transform:none;
}
body.light .hero .hero-cta .btn-gold svg{width:12px;height:12px}

/* 19 · Menu hero placed like the Our Story hero (Jane, 15 Sep). On phones
   and tablets the shared mobile hero rule top-aligns content, so "Our Menu"
   sat right under the logo with an empty photograph beneath. Now, as on Our
   Story: a taller band, the text anchored to the bottom, and a bottom scrim
   for legibility. On laptop/desktop the band keeps its height and the block
   is centred in the space BELOW the fixed header instead of the full band. */
@media (max-width:900px){
  .hero.menu-hero{align-items:flex-end;min-height:min(78svh,620px);
    padding-top:96px;padding-bottom:clamp(36px,6vw,56px)}
  body.light .hero.menu-hero .grade{background:
    linear-gradient(to bottom,rgba(6,10,10,.50) 0,rgba(6,10,10,.22) 24%,
      rgba(6,10,10,.42) 44%,rgba(6,10,10,.90) 100%)}
}
@media (min-width:901px){
  .hero.menu-hero{padding-top:clamp(96px,8vw,120px)}
}

/* 20 · Footer on phones was WIDER than the screen (found 15 Sep). The
   `max-width:1100px` rule (4 columns) sits later in this file than the
   `max-width:640px` one-column rule, so on phones it won: brand + three link
   columns forced ~409px, and every page scrolled sideways by 19px at 390 and
   49px at 360. Restated after both: brand full width, then the link columns
   two by two, then the app block full width. */
@media (max-width:640px){
  footer.site .cols{grid-template-columns:1fr 1fr;gap:30px 24px}
  footer.site .f-brand,footer.site .f-app{grid-column:1 / -1}
}

/* 21 · Device QA pass (15 Sep) — 10 pages x 19 devices measured, then:
   · menu button: the burger is 26x16, far under a 44px touch target. An
     invisible 44px hit area is added around it; the icon looks the same.
   · Dubai hero on phones: the fixed header is 101-109px tall but the hero
     began its content at 88-94px, so the top of "DUBAI" ran under it.
   · 320px phones: the stats pair ("Thousands") and the menu-card heading
     rule pushed the page 18px / 8px wider than the screen.
   · Contact phone/email links grow to a comfortable tap height.
   · Footer store-badge captions 8.5px -> 9.5px. */
.burger::before{content:"";position:absolute;inset:-14px -9px}
@media (max-width:640px){
  .hero:not(.menu-hero){padding-top:128px}
  a.ct-big{padding-block:8px}
}
@media (max-width:360px){
  .num{padding-inline:10px}
  .num b{font-size:clamp(20px,6.4vw,24px)}
  .menu-book .head .line{width:min(130px,40%)}
}
.f-store i{font-size:9.5px}
/* menu card headings on phones: .head is a flex ROW (heading + gold rule),
   so a two-line heading wrapped centred inside its own box ("Poppadoms &" /
   "   Chutneys") with the rule floating beside it. Stacked and left-aligned
   below 640px, the rule sitting under the heading. */
@media (max-width:640px){
  .menu-book .head{flex-direction:column;align-items:flex-start;gap:0}
  .menu-book .head h2{text-align:left}
  .menu-book .head .line{margin:12px 0 0;background:linear-gradient(90deg,#B08F4A,transparent)}
}

/* 21 · Floating WhatsApp button, bottom-RIGHT, every page (client, 17 Sep;
   moved from bottom-left the same day at Jane's request).
   Injected by site.js. WhatsApp's own green so it is recognised at a glance;
   56px on desktop, 52px on phones, clear of the iPhone home bar. Sits under
   the header drawer (880) and modals (960), above page content. */
.wa-float{position:fixed;right:max(20px,env(safe-area-inset-right));
  bottom:max(20px,calc(env(safe-area-inset-bottom) + 12px));z-index:850;
  width:56px;height:56px;border-radius:50%;display:grid;place-items:center;
  background:#25D366;color:#fff;text-decoration:none;
  box-shadow:0 10px 26px -8px rgba(0,0,0,.45);
  transition:transform .3s ease,box-shadow .3s ease}
.wa-float svg{width:29px;height:29px}
.wa-float:hover{transform:translateY(-3px);box-shadow:0 14px 30px -8px rgba(0,0,0,.5)}
.wa-float:focus-visible{outline:2px solid #B08F4A;outline-offset:3px}
@media (max-width:640px){ .wa-float{width:52px;height:52px;right:16px;bottom:max(16px,calc(env(safe-area-inset-bottom) + 10px))} .wa-float svg{width:27px;height:27px} }
@media (prefers-reduced-motion:reduce){ .wa-float{transition:none} .wa-float:hover{transform:none} }

/* 22 · MENU PAGE GROUND darkened to #E5DCCA (client, 17 Sep: "I like the
   updated color, but can the background be made a little darker so the menu
   boxes can be seen a little clearer" — approved 21 Sep, the recommended
   shade of the three in "Curry Mile — Menu background proposal 17 Sep 2026").
   The BOXES do not change: they keep the approved cream wash, but it is now
   restated over an explicit #F6F2EA so it no longer inherits the darker
   ground (the wash is semi-transparent). Same for the "Ready to order?" box,
   which must keep matching the menu boxes. The category bar takes the new
   ground so the sticky bar matches the page as it scrolls.
   Scoped to body.light.look-cream, so only menu.html is affected —
   ?look=dark and every other page are untouched. */
body.light.look-cream{background:#E5DCCA}
body.light.look-cream .tabs{
  background:#E5DCCA;
  border-top-color:rgba(26,24,21,.12);
  border-bottom-color:rgba(26,24,21,.12);
}
body.light.look-cream .menu-book,
body.light.look-cream .order-direct{
  background:linear-gradient(180deg,rgba(156,123,39,.07),rgba(156,123,39,.02)),#F6F2EA;
}
body.light.look-cream .order-direct{border-color:rgba(156,123,39,.45)}

/* 23 · The real menu has 17 categories (22 Sep), not the 7 this bar was
   built for: 17 tabs come to well over 3000px, so on a desktop the bar
   scrolled sideways and most categories were simply out of sight. From
   1024px up it now WRAPS to centred rows instead. Below that it keeps
   scrolling, which is the right behaviour on a phone. */
@media (min-width:1024px){
  .tabs .container{flex-wrap:wrap;justify-content:center;overflow-x:visible}
  .tab{padding:13px 18px 11px;font-size:11.5px;letter-spacing:.14em}
  .tab.active{border-bottom-width:2px}
}

/* 24 · DISH PHOTOGRAPH IN THE ROW, Deliveroo-style (client, 22 Sep).
   The client's 50 photographs used to appear only after a tap, in the modal.
   They now sit in the list itself: name and description left, price, then a
   square photograph at the end of the row — the arrangement their Deliveroo
   menu uses, in this site's language (square corners, hairline, no shadow).
   Only 54 of 122 dishes have a photograph, so `.mi` without `.has-ph` keeps
   the original two-part row and the column stays tidy. */
.mi.has-ph{align-items:flex-start;gap:clamp(14px,1.6vw,22px)}
.mi .mi-txt{flex:1;min-width:0}
.mi .mi-ph{
  flex:none;width:clamp(72px,7.4vw,104px);align-self:flex-start;
  border:1px solid var(--hair-soft);overflow:hidden;display:block;
  background:rgba(255,255,255,.03);
}
.mi .mi-ph img{
  /* ⚠ height:auto is load-bearing. The <img> carries width/height attributes
     (240x240) so the browser reserves the space before the file loads; those
     attributes become CSS, and with width:100% set here the 240px HEIGHT
     survived — the thumbnails rendered 104x240, tall and cropped, instead of
     square. aspect-ratio only takes over once height is auto. */
  display:block;width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;
  transition:transform .6s var(--ease),filter .6s var(--ease);
  filter:brightness(.94) saturate(.97);
}
.mi:hover .mi-ph{border-color:var(--gold-dim)}
.mi:hover .mi-ph img{transform:scale(1.04);filter:none}
/* the price sits between the text and the photograph, so it needs its own
   breathing room rather than hugging the image */
.mi.has-ph .price{padding-left:clamp(10px,1.2vw,18px)}
body.light .mi .mi-ph{background:rgba(26,24,21,.04);border-color:rgba(26,24,21,.14)}
body.light .mi .mi-ph img{filter:none}

@media (max-width:640px){
  .mi .mi-ph{width:78px}
  .mi.has-ph{gap:12px}
  .mi.has-ph .price{padding-left:8px}
}
@media (prefers-reduced-motion:reduce){
  .mi .mi-ph img{transition:none}
  .mi:hover .mi-ph img{transform:none}
}

/* 25 · MENU PAGE: no hero photograph (client, 22 Sep). The menu opened on a
   full-bleed stock plate; it now opens on the page's own ground so the first
   thing seen is the menu itself. The photo and its gradient are hidden rather
   than deleted from menu.html, so restoring them is one rule.
   The hero type was warm white for a dark photo (block at line 664), which
   would be invisible on cream — it is restated in ink here, measured:
   #1A1815 on #E5DCCA = 13.7:1, the note text #4A453D = 7.6:1, the eyebrow and
   rule in bronze #816620 = 4.6:1. The section also loses its 74svh minimum,
   since there is no image to give height to. */
body.light.look-cream .hero.menu-hero{
  min-height:0;
  background:#E5DCCA;
  padding-top:clamp(120px,14vw,168px);
  padding-bottom:clamp(26px,4vw,48px);
  align-items:flex-start;
}
body.light.look-cream .hero.menu-hero .bg,
body.light.look-cream .hero.menu-hero .grade{display:none}
body.light.look-cream .hero.menu-hero .container,
body.light.look-cream .hero.menu-hero h1{color:#1A1815}
body.light.look-cream .hero.menu-hero .eyebrow{color:#816620}
body.light.look-cream .hero.menu-hero .menu-note{
  color:#4A453D;border-left-color:rgba(129,102,32,.55);
}
@media (max-width:900px){
  body.light.look-cream .hero.menu-hero{
    min-height:0;padding-top:clamp(104px,26vw,140px);padding-bottom:22px;
  }
}

/* 25b · Two things the flat menu hero exposed.
   · `body.light.has-hero .hero::after` paints a 90-170px gradient down to
     #121211 at the foot of every light hero — it existed to blend the dark
     photograph into the dark band below it. With no photograph it was a black
     smear across the cream, so it goes on this page only.
   · The header sits over the hero and only takes its ink treatment once
     "stuck". Over a cream hero the white wordmark and the Order button were
     nearly invisible from the first pixel, so the menu page gets the stuck
     treatment immediately: dark wordmark, ink nav, bronze Order. */
body.light.look-cream .hero.menu-hero::after{display:none}
body.light.look-cream header.site:not(.stuck) .wordmark img{content:url(logo-dark.png) !important}
/* ⚠ !important is required: line ~1441 sets the nav to warm white with
   !important for `body.light.has-hero header.site:not(.stuck)`, which the
   menu page still matches (it has a hero, just no photograph in it). Measured
   before the fix: nav links rgb(242,238,231) on a cream ground. */
body.light.look-cream header.site:not(.stuck) .nav a{color:#1A1815 !important;opacity:1}
body.light.look-cream header.site:not(.stuck) .nav a.active{color:#755A18 !important}
body.light.look-cream header.site:not(.stuck) .nav a.active{border-bottom-color:#9C7B27 !important}
body.light.look-cream header.site:not(.stuck) .nav-order{
  color:#755A18 !important;border-color:rgba(156,123,39,.5) !important;
}
body.light.look-cream header.site:not(.stuck) .burger span{background:#1A1815 !important}

/* 26 · Photo credit line under the menu (22 Sep). Required by the CC BY /
   CC BY-SA licences on the borrowed drink photographs — it is a legal notice,
   so it must stay readable, not a whisper: 5.9:1 on the cream ground. It
   disappears with the borrowed images, once Curry Mile send their own. */
.photo-credit{
  max-width:900px;margin:clamp(26px,4vw,44px) auto 0;
  font-size:11.5px;line-height:1.7;letter-spacing:.02em;color:#6E685E;
}
.photo-credit a{color:#755A18;text-decoration:underline;text-underline-offset:2px}
body:not(.light) .photo-credit{color:#8C867B}
body:not(.light) .photo-credit a{color:#B08F4A}

/* 25c · MENU HERO: the client's own photograph (23 Sep). Block 25 took the
   stock plate out; this brings a photo back, but Curry Mile's own shot
   (Chicken Tikka Main, from their marble shoot) and NOT full-bleed: the flat
   cream hero and its ink type stay exactly as block 25 set them, and the
   photo occupies the right-hand side, fading into the cream through a mask
   so the headline never sits on the picture. Phones: a band under the text,
   fading upward. Remove this block to return to the flat hero. */
body.light.look-cream .hero.menu-hero{position:relative;overflow:hidden}
body.light.look-cream .hero.menu-hero .container{position:relative;z-index:2}
body.light.look-cream .hero.menu-hero .bg{
  display:block;position:absolute;top:0;bottom:0;right:0;left:auto;
  width:min(56%,980px);height:auto;
  background-size:cover;background-position:50% 55%;
  transform:none !important;
  -webkit-mask-image:linear-gradient(to right,transparent 0%,rgba(0,0,0,.55) 22%,#000 46%);
          mask-image:linear-gradient(to right,transparent 0%,rgba(0,0,0,.55) 22%,#000 46%);
}
@media (min-width:901px){
  /* second mask fades the top out behind the header, so the bronze Order
     button keeps its cream ground (it vanished on the photo, 24 Sep) */
  body.light.look-cream .hero.menu-hero .bg{
    -webkit-mask-image:linear-gradient(to right,transparent 0%,rgba(0,0,0,.55) 22%,#000 46%),
                       linear-gradient(to bottom,transparent 0,transparent 96px,#000 190px);
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(to right,transparent 0%,rgba(0,0,0,.55) 22%,#000 46%),
                       linear-gradient(to bottom,transparent 0,transparent 96px,#000 190px);
            mask-composite:intersect;
  }
}
@media (min-width:901px){
  body.light.look-cream .hero.menu-hero{min-height:clamp(440px,38vw,620px)}
}
@media (max-width:900px){
  body.light.look-cream .hero.menu-hero{padding-bottom:calc(58vw + 10px)}
  body.light.look-cream .hero.menu-hero .bg{
    top:auto;bottom:0;left:0;right:0;width:100%;height:62vw;
    background-position:50% 50%;
    -webkit-mask-image:linear-gradient(to bottom,transparent 0%,#000 30%);
            mask-image:linear-gradient(to bottom,transparent 0%,#000 30%);
  }
}
/* 25c (cont.) · 901–1240px: the menu note reaches ~55% of the width, so the
   photo narrows to keep clear of the text (it overlapped at 1024, 24 Sep). */
@media (min-width:901px) and (max-width:1240px){
  body.light.look-cream .hero.menu-hero .bg{width:42%}
}
@media (min-width:901px) and (max-width:1100px){
  body.light.look-cream .hero.menu-hero .bg{width:35%}
}

/* 27 · ORDER DIRECT box on the Dubai page (client, 25 Sep): "ORDER DIRECT in
   smaller text and 25 AED OFF YOUR FIRST ORDER a little bigger — the other way
   around." The two sizes are swapped on .od-offer only; the Menu page's
   "Ready to order?" box uses the same component and is left as it was. */
.order-direct.od-offer .t{gap:10px}
.order-direct.od-offer .t b{
  font-size:14.5px;letter-spacing:.3em;
}
.order-direct.od-offer .t span{
  font-family:var(--sans);font-weight:400;
  font-size:clamp(20px,2.6vw,30px);letter-spacing:.2em;line-height:1.25;
}

/* 28 · DISH POPUP shows the WHOLE photo (client, 26 Sep: "when a menu is
   clicked the image is not full"). The card image was forced to 16:10 with
   object-fit:cover, which cut the top and bottom off every square dish photo.
   Now the photo keeps its own shape (square for the photoshoot), is never
   cropped, and is capped in height so the name, price and description still
   fit on a laptop screen; any spare width shows the card's own cream. */
.modal .card .pic{display:flex;justify-content:center;background:#F3EEE6}
.modal .card .pic img{
  display:block;width:auto;max-width:100%;height:auto;
  max-height:min(520px,56svh);aspect-ratio:auto;object-fit:contain;
}

/* 29 · JOURNAL ARTICLE scroll motion (26 Sep). Driven by assets/article.js;
   everything here is scoped to body.is-article.am-on, which article.js only
   sets when the visitor has NOT asked for reduced motion. */
.am-progress{position:fixed;top:0;left:0;right:0;height:3px;z-index:1200;
  background:linear-gradient(90deg,#9C7B27,#C9A85A);transform-origin:0 50%;transform:scaleX(0);pointer-events:none}
body.is-article.am-on .article-body .am-fig{overflow:hidden;clip-path:inset(0 18% 0 18%);transition:clip-path 1.4s cubic-bezier(.2,.7,.1,1)}
body.is-article.am-on .article-body .am-fig.am-in{clip-path:inset(0 0 0 0)}
body.is-article.am-on .article-body .am-fig img{transform-origin:50% 60%;will-change:transform;filter:none}
body.is-article .article-body .am-h{position:relative;padding-bottom:18px}
body.is-article.am-on .article-body .am-h.reveal{opacity:1;transform:none}
body.is-article .am-h-mask{display:block;overflow:hidden}
body.is-article .am-h-in{display:block}
body.is-article.am-on .am-h .am-h-in{transform:translateY(105%);transition:transform 1s cubic-bezier(.2,.7,.1,1)}
body.is-article.am-on .am-h.am-in .am-h-in{transform:none}
body.is-article .am-rule{position:absolute;left:0;bottom:0;height:1px;width:72px;background:#9C7B27}
body.is-article.am-on .am-h .am-rule{transform:scaleX(0);transform-origin:0 50%;transition:transform 1.1s .35s cubic-bezier(.2,.7,.1,1)}
body.is-article.am-on .am-h.am-in .am-rule{transform:scaleX(1)}
body.is-article .article-body p.am-punch{font-family:var(--display);font-weight:300;
  font-size:clamp(24px,3vw,34px);line-height:1.3;color:#1A1815;margin:34px 0}
body.is-article .article-body p.am-spell{font-family:var(--display);font-weight:300;
  font-size:clamp(24px,3.4vw,38px);line-height:1.3;color:#755A18;letter-spacing:.01em;margin:34px 0}
body.is-article.am-on .article-body p.am-punch.reveal,
body.is-article.am-on .article-body p.am-spell.reveal{opacity:1;transform:none}
body.is-article .am-w{display:inline-block}
body.is-article.am-on .am-punch .am-w{opacity:0;transform:translateY(.55em);filter:blur(4px);
  transition:opacity .7s ease,transform .8s cubic-bezier(.2,.7,.1,1),filter .7s ease}
body.is-article.am-on .am-spell .am-w{opacity:0;transform:translateY(-.9em) rotate(-4deg);
  transition:opacity .6s ease,transform .9s cubic-bezier(.3,1.5,.5,1)}
body.is-article.am-on .am-in .am-w{opacity:1;transform:none;filter:none}

/* 30 · FOOD PHOTOS IN TRUE COLOUR (Jane, 26 Sep: "quality of the image in the
   website is not the same as the one I provided"). The Our Story pappadam
   figure carries the .staff class, so it inherited the staff-photo grade —
   brightness(.84) saturate(.86) contrast(.96) plus a dark gradient overlay —
   which greyed the client's photo. Food photos are shown exactly as supplied;
   the staff/kitchen portraits keep their grade. Same for the Journal
   article's opening photo (.article-body figure img had brightness(.86)). */
.os-copy figure.os-fig img,
body.light .os-copy figure.os-fig img,
.article-body figure.staff.os-fig img,
body.light .article-body figure.staff.os-fig img,
body.is-article .article-body figure img{filter:none !important}
.os-copy figure.os-fig::after,
.staff.os-fig::after{display:none !important}
.os-copy figure.os-fig img{aspect-ratio:auto;object-fit:contain}

/* 31 · JOURNAL CARD photos in full colour (Jane, 26 Sep). The cards were
   dimmed to brightness(.82) and only brightened on hover; they now show the
   photo exactly as supplied at all times. The slow zoom on hover stays. */
.post img,.post:hover img,
body.light .post img,body.light .post:hover img,
body.light .post img.staff,.post.lead img{filter:none !important}
.post.lead .ph.staff::after,.post .ph.staff::after{display:none !important}

/* 32 · JOURNAL ARTICLE extras for the curry-house guide (26 Sep): heat line,
   "Order it if / Have it with" labels, and the comparison table. */
body.is-article .article-body p.am-heat{display:flex;align-items:center;gap:14px;margin:-4px 0 26px;font-size:15px}
body.is-article .am-heat .am-k{font-size:11.5px;letter-spacing:.3em;text-transform:uppercase;color:#755A18}
body.is-article .am-heat .am-chilli{font-size:20px;letter-spacing:.12em}
body.is-article .article-body p.am-kv{padding-left:18px;border-left:2px solid rgba(156,123,39,.55);margin-bottom:14px}
body.is-article .article-body p.am-kv strong{font-weight:500;color:#1A1815;margin-right:.35em}
body.is-article .am-table{width:100%;border-collapse:collapse;margin:30px 0 34px;font-size:16.5px}
body.is-article .am-table th{text-align:left;font-weight:400;font-size:11.5px;letter-spacing:.28em;text-transform:uppercase;color:#755A18;padding:0 0 12px;border-bottom:1px solid rgba(156,123,39,.55)}
body.is-article .am-table td{padding:14px 0;border-bottom:1px solid rgba(26,24,21,.12);vertical-align:top}
body.is-article .am-table td:last-child{font-family:var(--display);font-size:20px;color:#1A1815;text-align:right;padding-left:16px}
body.is-article.am-on .am-table.reveal{opacity:1;transform:none}
body.is-article.am-on .am-table tbody tr{opacity:0;transform:translateX(-14px);transition:opacity .6s ease,transform .7s cubic-bezier(.2,.7,.1,1)}
body.is-article.am-on .am-table.am-in tbody tr{opacity:1;transform:none}
body.is-article.am-on .am-table.am-in tbody tr:nth-child(2){transition-delay:.08s}
body.is-article.am-on .am-table.am-in tbody tr:nth-child(3){transition-delay:.16s}
body.is-article.am-on .am-table.am-in tbody tr:nth-child(4){transition-delay:.24s}
body.is-article.am-on .am-table.am-in tbody tr:nth-child(5){transition-delay:.32s}
body.is-article.am-on .am-table.am-in tbody tr:nth-child(6){transition-delay:.40s}
body.is-article.am-on .am-heat .am-chilli{display:inline-block;transform:scale(.6);opacity:0;transition:transform .6s cubic-bezier(.3,1.6,.5,1),opacity .4s ease}
body.is-article.am-on .am-heat.am-in .am-chilli{transform:none;opacity:1}
body.is-article.am-on .article-body p.am-heat.reveal{opacity:1;transform:none}
body.is-article .am-table th:last-child{text-align:right}
/* 33 · links inside Journal articles (cross-links between the three posts) */
body.is-article .article-body a.am-link{color:#755A18;text-decoration:underline;text-decoration-color:rgba(156,123,39,.5);text-underline-offset:3px;transition:text-decoration-color .3s}
body.is-article .article-body a.am-link:hover{text-decoration-color:#755A18}

/* 34 · Delivery partners on ONE row above phone width (Jane, 26 Sep: Noon
   dropped to its own line). .partner had min-width:150px and the row could
   wrap, so at ~1000-1100px the four letter-spaced names didn't fit and Noon
   wrapped under the others. Above 760px the row no longer wraps and the four
   share the width equally, with the lettering tightened a touch between
   761-1200px so the longest name (DELIVEROO) still fits. Phones keep 2 x 2. */
@media (min-width:761px){
  .partners .partner-row{flex-wrap:nowrap}
  .partners .partner{flex:1 1 0;min-width:0}
  .partners .partner:last-child{border-right:0}
}
@media (min-width:761px) and (max-width:1200px){
  .partners .partner--named{letter-spacing:.18em;text-indent:.18em;font-size:13px;padding-inline:6px}
}
