/* ============================================================
   GRUB MONKEYS — CORRECTIONS LAYER
   ------------------------------------------------------------
   Every contrast correction and layout fix applied on top of the
   design files lives here, and this file is linked LAST on every page.
   It used to sit at the end of
   interactive-diner.css, which worked only while that was the final
   stylesheet; new-motion.css and final-detail-pass.css now load after
   it, and two corrections silently lost the cascade to equal-specificity
   rules in final-detail-pass.css.

   KEEP THIS LINK LAST. If another stylesheet is added after it, these
   corrections can be overridden again and the contrast failures come
   back without any visible error.

   Reference values, all measured rather than estimated:
     Sorta White #F0EFE9 on Monkey Red #EB0000 ....... 4.02:1  (fails)
     Pure white  #FFFFFF on Monkey Red #EB0000 ....... 4.63:1  (passes)
     Monkey Red  #EB0000 on Sorta White #F0EFE9 ...... 4.02:1  (fails)
     --gm-red-ink #DC0000 on Sorta White ............. 4.51:1  (passes)
     --gm-red-ink #DC0000 on counter cream #F3F0E7 ... 4.56:1  (passes)
   ============================================================ */

/* ============================================================
   CONTRAST — AA corrections for this stylesheet's components.
   These live here rather than in styles.css because interactive-diner.css
   loads second: an equal-specificity rule in styles.css would lose the
   cascade. Sorta White on Monkey Red is 4.02:1 at these small sizes;
   pure white on the same red is 4.63:1 and passes without touching the
   brand colour.
   ============================================================ */
.gm-session-chip,
.gm-fortune-group>span,
.gm-fortune-machine::before{
  color:#FFFFFF;
}

/* Remaining AA corrections, resolved against measured render paths.
   Sorta White on Monkey Red is 4.02:1; pure white on the same red is 4.63:1.
   Monkey Red as text on Sorta White is likewise 4.02:1; --gm-red-ink (#DC0000)
   is 4.51:1. Only genuinely red-backed elements are targeted — the plain
   .loc-row list sits on a light surface and is deliberately left alone; only
   .loc-row.featured is red. */
.matchbook-inside span,
.story-origin-poster .origin-copy span,
#motelKeytag #keyName,
#motelKeytag #keyNum,
.loc-row.featured .loc-row-tag,
.loc-row.featured .loc-row-address,
.loc-row.featured .loc-row-name,
.gm-juke-select[aria-pressed="true"],
.gm-photobooth-trigger,
.btn-ticket.on-dark,
.gm-tray-ticket span{
  color:#FFFFFF;
}

.gm-fortune-copy .gm-machine-code,
.loc-row.featured .loc-link,
.loc-row.featured .loc-link.outline{
  color:var(--gm-red-ink,#DC0000);
}

/* =========================================================
   WHAT SHOULD I ORDER? — RANDOM MENU RECOMMENDATION UPGRADE
   Appetite scales the number of real menu picks.
   ========================================================= */
.gm-hunger-guide{
  display:block;
  color:rgba(240,239,233,.82);
  font-size:.5rem;
  line-height:1;
  letter-spacing:.11em;
  text-transform:uppercase;
  font-weight:800;
}

.gm-fortune-machine.is-dispensing{
  padding-bottom:var(--gm-fortune-card-space,255px);
}

.gm-fortune-result-meta{
  margin-top:7px;
  font-size:.52rem;
  line-height:1;
  font-weight:900;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--gm-id-red);
}

.gm-fortune-card ul{
  gap:8px;
}

.gm-fortune-card li{
  display:grid;
  grid-template-columns:76px minmax(0,1fr);
  gap:9px;
  align-items:start;
}

.gm-fortune-card li span{
  display:inline-block;
  padding-top:2px;
  font-size:.48rem;
  line-height:1.15;
  letter-spacing:.1em;
  font-weight:900;
  text-transform:uppercase;
  color:var(--gm-id-red);
}

.gm-fortune-card li b{
  min-width:0;
  font-size:.78rem;
  line-height:1.28;
  font-weight:800;
}

.gm-fortune-machine[data-pick-count="4"] .gm-fortune-card{
  min-height:255px;
}

@media(max-width:640px){
  .gm-fortune-card li{
    grid-template-columns:64px minmax(0,1fr);
    gap:7px;
  }
  .gm-fortune-machine[data-pick-count="4"] .gm-fortune-card{
    min-height:275px;
  }
}

/* ============================================================
   COMPACT JUKEBOX SELECTOR
   The shell is now roughly half its original desktop width; keep every
   selector/function, but arrange the four choices as a readable 2×2 deck.
   ============================================================ */
#gmJukeboxPlayer .gm-juke-selector{
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:4px;
  margin:1px 0 5px;
}
#gmJukeboxPlayer .gm-juke-select{
  min-height:34px;
  padding:4px 5px;
  border-width:1px;
  font-size:.48rem;
  line-height:1.15;
  letter-spacing:.045em;
}
#gmJukeboxPlayer .gm-juke-select::before{
  top:4px;
  right:4px;
  width:5px;
  height:5px;
}
#gmJukeboxPlayer .gm-juke-selection-note{
  font-size:.43rem;
  line-height:1.35;
  letter-spacing:.055em;
}

/* Re-applied: the order status card is pinned bottom-right of .order-band,
   which clips; at bottom:12px its last 3px was shaved on phones. */
@media(max-width:900px){
  .gm-order-status{ bottom:20px; }
}

/* Re-applied: the appetite guide sits on the red machine at 8px / 0.82 alpha
   for 4.02:1. Full-opacity white reaches 4.63:1. */
.gm-hunger-guide{
  color:#FFFFFF;
}

/* ============================================================
   TAIL SECTIONS — RECLAIM RESERVED-BUT-UNPAINTED SPACE
   ============================================================ */

/* .order-band carries flex-wrap:wrap from its original row layout
   (justify-content:space-between, align-items:flex-end). Inside
   .proof-order-combo it is switched to flex-direction:column, but the
   wrap was never reset. A column flex container with a definite height
   wraps into COLUMNS, so the counter tray and the order-status toast
   were pushed into a second column beginning past the band's right edge
   and clipped away by overflow:hidden -- at 1440 the tray started 278px
   beyond that edge. They painted nothing at any width measured (1440,
   1280, 1100, 900, 390) yet still reserved ~300px of flow height, which
   set the combo row height and, through align-items:stretch, forced the
   review noticeboard to 906px for a 106px quote. Scoped to the combo so
   the standalone band on the menu page keeps its original wrapping. */
.proof-order-combo > .order-band{
  flex-wrap:nowrap;
}

/* With the band no longer inflated by invisible content, stop stretching
   the noticeboard to match it: size it to the quote it actually holds
   and centre it in the row. Only above the 1050px breakpoint, where the
   combo is still two columns. */
@media(min-width:1051px){
  .proof-order-combo{
    align-items:center;
  }
}

/* Gallery: 84px of padding at each end plus a 60px trailing gap under
   the polaroid strip. The 48px chin on each polaroid is the caption
   area of the photo frame, so that stays -- only the section padding
   and the strip's trailing gap come down. */
.social{
  padding-top:clamp(38px,4.4vw,58px);
  padding-bottom:clamp(30px,3.4vw,44px);
}
.social-strip{
  padding-bottom:26px;
}

/* Footer trims removed: the footer was redesigned in the Aug 22 refinement
   pass, which sets its own tagline padding, columns, gap and grid padding.
   The old .foot-tagline and .foot-grid trims here were written against the
   previous footer and, loading last, would have overridden the new one. */
.franchise-teaser-home .fr-teaser{
  padding-top:24px;
  padding-bottom:24px;
}

/* Remaining slack in the red panel is the spacing between its blocks --
   the tray's leading margin and the band's flex gap. Everything below
   the tray is the kitchen-status readout, which does paint, so the panel
   is not padded out any further. */
@media(min-width:1051px){
  .proof-order-combo > .order-band{
    gap:6px;
  }
  .proof-order-combo .gm-counter-tray{
    margin-top:12px;
  }
}

/* ============================================================
   "HUNGRY YET?" SIGN MOVED UNDER THE NOTICEBOARD
   ============================================================ */

/* The sign and its approach rail were the last two blocks of the red
   panel. Moved into the reviews column so the panel gets shorter and the
   space under the cropped noticeboard is used. .reviews was a flex row
   holding a single board; it now stacks board, rail and sign. */
.proof-order-combo > .reviews{
  flex-direction:column;
  justify-content:center;
  gap:0;
}

.proof-order-combo > .reviews > .order-hungry-bridge{
  margin-top:14px;
}

.proof-order-combo > .reviews > .diner-sign--compact{
  margin-top:6px;
}

/* On the red panel the sign sat on a translucent dark tint. Against the
   grey column that tint is nearly invisible, so give it the red ground
   it used to borrow from its parent. */
.proof-order-combo > .reviews > .diner-sign--compact{
  background:var(--gm-red);
}

/* The rail alternated white and grey to read as stitching on red; on the
   grey column the grey segments disappear, so alternate against red. */
.proof-order-combo > .reviews > .order-hungry-bridge span:nth-child(even){
  background:var(--gm-red);
}

/* The ghost wordmark hangs off bottom:-12vh, which was harmless while it
   was (wrongly) in flow and the jukebox section was 1090px tall. Now that
   it is absolute again and the section is 542px, that offset pushed it
   108px into the gallery below. Pinned to the section's own bottom edge.
   Below 901px the existing rule already insets it, so this is scoped. */
@media(min-width:901px){
  .juke-ghost-code{
    bottom:0;
  }
}


/* The franchise teaser's halftone is a fixed 110px tall at top:-25px,
   sized for a taller teaser than this one (~95px). It reached 23px above
   the section and lapped 14px into the counter spread above. Sized to the
   teaser instead of a fixed height so the dot field still fills the band
   but its box stays inside the section -- overflow:hidden would have
   hidden the overhang while leaving the box overlapping. */
.franchise-teaser-home .retro-halftone--franchise{
  top:0;
  height:100%;
}

/* ============================================================
   COUNTER SPREAD — AA CORRECTIONS
   Measured against the spread's own cream ground (#F3F0E7) and the
   featured row's red, all at the small sizes these actually render.
   ============================================================ */

/* The session chip was forced to pure white further up this file, which
   was right while it sat on Monkey Red. In the counter head it sits on
   cream, where white measured 1.14:1 -- effectively invisible. Its
   border follows currentColor, so the ink recolours both. */
.counter-order-head .gm-session-chip{
  color:var(--gm-grey,#3A3A3A);
}

/* Monkey Red on this cream is 4.07:1; --gm-red-ink is 4.56:1. */
.counter-kicker,
.counter-diner-context > span{
  color:var(--gm-red-ink,#DC0000);
}

/* #82776C on the same cream is 3.84:1. Held in the same warm grey
   family, darkened to 4.79:1. */
.counter-detail-line{
  color:#736858;
}

/* The live open/closed readout inherits the grey ink, which is 2.45:1
   against the featured row's red. White reaches 4.63:1. */
.loc-row.featured .loc-live-status,
.loc-row.featured .loc-live-status b{
  color:#FFFFFF;
}

/* Same story as the session chip: the tray ticket was forced to white
   for the red panel, and the counter spread puts the tray on cream,
   where white measured 1.14:1. */
.diner-counter-spread .gm-tray-ticket span{
  color:var(--gm-grey,#3A3A3A);
}

/* Sorta White on Monkey Red is 4.02:1 at this size; pure white is 4.63:1. */
.irl-handle-board__title{
  color:#FFFFFF;
}

/* Monkey Red on Sorta White is 4.02:1; --gm-red-ink is 4.51:1. */
.receipt-trio-head > span{
  color:var(--gm-red-ink,#DC0000);
}

/* ============================================================
   TEAM POSTER FRAME
   ============================================================ */

/* The uncropped-poster frame in styles.css pins the ratio to 1122/1402,
   the portrait founder artwork it was written for. It selects on
   img[src*="founder-"], so the new square team poster (1254x1254) matched
   it too and was letterboxed -- roughly 65px of empty cream above and
   below. Matched to the square artwork. The image inside is positioned,
   so the frame needs a real ratio to size against; aspect-ratio:auto
   collapses it to 8px. Update this if the poster's shape changes. */
.story-origin-poster.story-origin-photo:has(img[src*="founder-team-poster"]){
  aspect-ratio:1 / 1;
}

/* ============================================================
   LIVE CSS TEAM BOARD — AA CORRECTIONS
   All three sit on Sorta White at normal-text sizes (12.48px and
   9.28px), so 4.5:1 applies rather than the large-text threshold.
   ============================================================ */

/* #117F82 on Sorta White is 4.16:1; --gm-teal-ink is 4.74:1. */
.team-live-brand__tag{
  color:var(--gm-teal-ink,#00776A);
}

/* Monkey Red on Sorta White is 4.02:1; --gm-red-ink is 4.51:1. The star
   divider is decorative and would be exempt, but it is real text in the
   accessibility tree and the ink is visually indistinguishable here. */
.team-person__eyebrow,
.team-live-divider > b{
  color:var(--gm-red-ink,#DC0000);
}

/* ============================================================
   LIVE CSS TEAM BOARD — NAMES SIZED TO THE BOARD, NOT THE VIEWPORT
   ============================================================ */

/* The names use viewport units -- clamp(2.55rem,5.5vw,5.2rem) for the
   founder and clamp(1.22rem,2.55vw,2.3rem) for the other two -- but the
   board sits in the story's narrow right column, about 378px wide at a
   1440 viewport, so each name column is roughly 117-143px. 5.5vw is 79px
   of display type in a 143px column. Measured at 1440, the founder name
   ran 141px past its own column and straight across the next one, and
   the other two overflowed 53px each: all three names overlapped.
   Sized against the board instead so the type tracks the space it
   actually occupies. Below 921px the board is a single full-width
   column and already fits, so this is scoped above that. */
@media(min-width:921px){
  .team-live-people{
    container-type:inline-size;
    container-name:gmteam;
  }
  /* Ceiling raised from 1.35rem: the story column widened (--max
     alignment) and pushed .team-live-people from ~393px up to a
     629px plateau at 1440px+ viewports, but this cap was never
     revisited, so the name sat frozen at its old size across that
     entire 60% of extra board width. 2.2rem is that same 5.5cqw
     ratio carried through to the new plateau -- checked for clean
     wrapping at 921/1000/1100/1101/1150/1280/1440/1728. */
  /* Sized down 9% from the previous pass -- the names read clustered
     against the divider lines at the board's new width and plateau. */
  .team-person__name{
    font-size:clamp(.56rem, 5cqw, 2rem);
    hyphens:none;
  }
  /* Re-tuned after the board was widened and the founder name asked to be
     larger. Their clamp(2.9rem,5.9vw,5.75rem) is still viewport-based and
     would overflow again, but the intent is honoured here: 10.6cqw is close to the
     largest value that still fits at every width tested (1920, 1600, 1440,
     1280, 1150, 1101, 1000, 900, 768, 600, 390, 360), and takes the name
     from 27.3px to 41.6px at 1440. 12cqw starts overflowing at 1000.
     Their line-height and letter-spacing are adopted as authored.

     Ceiling raised again for the same reason as .team-person__name above --
     4.2rem carries the 10.6cqw ratio through to the board's new 629px
     plateau instead of freezing at the old ~393px one. */
  /* Same 9% reduction as .team-person__name above. */
  .team-person--founder .team-person__name{
    font-size:clamp(.82rem, 9.6cqw, 3.8rem);
    line-height:.92;
    letter-spacing:.018em;
  }
}

/* On phones the two non-founder names (Afridi, Hisham) sit at the base
   rule's floor -- clamp(1.22rem,2.55vw,2.3rem) in styles-interactive.css,
   where 2.55vw is under the 1.22rem floor at every real phone width, so
   they render at exactly 19.52px regardless of device. Raised in six
   steps: ~17% to 1.43rem (22.88px), +5% to 1.5rem (24px), +5% to 1.575rem
   (25.2px), +5% to 1.654rem (26.46px), +8% to 1.786rem (28.58px), +5%
   again to 1.875rem (30px). Desktop/tablet (≥921px) are untouched --
   they're on the cqw-based sizing above, a separate rule this doesn't
   affect. */
@media(max-width:560px){
  .team-person__name{
    font-size:clamp(1.875rem, 2.55vw, 2.3rem);
  }

  /* Mueen's name (styles-interactive.css) is clamp(3rem,13.5vw,4.7rem)
     here -- fluid across the phone range, not floor-pinned like the two
     names above, so all three clamp values are scaled by the same 1.05
     to give a true 5% increase at every width instead of just one point.
     48px -> 50.4px at 320px, 52.65px -> 55.3px at 390px. */
  .team-person--founder .team-person__name{
    font-size:clamp(3.15rem, 14.175vw, 4.935rem);
  }
}

/* The brand lockup has the same problem: clamp(2rem,4.6vw,4.6rem) is
   66px at a 1440 viewport, and the name sits in a 152px cell inside the
   378px board. Measured scrollWidth 271 against clientWidth 152, so
   "GRUB MONKEYS" rendered as "GRUB MONKE". Sized against the lockup.

   Ceiling raised from 2.4rem for the same reason as the two rules above:
   .team-live-brand plateaus at 629px now too, and 4.75rem carries the
   12cqw ratio through to that width instead of the old ~320px one. */
@media(min-width:921px){
  .team-live-brand{
    container-type:inline-size;
    container-name:gmteambrand;
  }
  .team-live-brand__name{
    font-size:clamp(1rem, 12cqw, 4.75rem);
  }
}

/* ============================================================
   CHROME DINER PANEL — AA CORRECTIONS
   ============================================================ */

/* The eyebrow is brand teal on the red panel: #00DDC2 on #EB0000 is
   2.67:1 at 9.92px, which is normal text needing 4.5:1. Teal cannot
   reach that against this red at any usable lightness -- the closest
   tint that clears it, #F0FFFC, sits exactly on 4.50 and has already
   lost the teal identity. White reaches 4.63:1 with margin, so the
   accent is carried by the flanking rules rather than the type. */
.gm-chrome-panel__eyebrow b{
  color:#FFFFFF;
}

/* Sorta White at 0.9 alpha on the same red composites to 4.02:1 at
   10.88px. Full white is 4.63:1. */
.gm-chrome-panel__footer p{
  color:#FFFFFF;
}

/* ============================================================
   MENU ROWS — LET THE DISH NAME SHRINK
   ============================================================ */

/* .menu-row .name is flex:0 0 auto, so it cannot shrink at all. At 360px
   the row is 320px wide but its contents need 358px: dot 7 + name 231 +
   leader 16 + price 64, plus three 11px gaps. The price was pushed 31px
   past the row and 11px past the viewport, which made the whole menu page
   scroll sideways on small phones. Allowing the name to shrink lets it
   wrap instead; the strengthened price alignment and its 58px minimum are
   left exactly as authored. */
body[data-page="menu"] .menu-row .name{
  flex:1 1 auto;
  min-width:0;
}

/* ============================================================
   FRANCHISE REEL — AA CORRECTION
   The reel moved out of its own .gm-fr-vibe section and into a phone
   mockup inside the hero, so these follow the .gm-fr-phone names. The
   old badge and controls-label rules are dropped: neither element
   exists in the new markup.
   ============================================================ */

/* The <video> fallback copy inherits the grey ink and sits on the near
   black screen at 1.66:1. It only renders when the browser cannot play
   video at all, which is precisely when it has to be readable. */
body[data-page="franchise"] .gm-fr-phone__video{
  color:var(--gm-white,#F0EFE9);
}

/* Paired with gm-corrections.js: when the reel cannot be used, the
   controls are disabled and the screen is dimmed slightly so the poster
   reads as a still rather than a paused video. */
.gm-fr-phone__screen.is-unavailable{
  filter:grayscale(.35);
}

/* A note kept from the previous layout, because the lesson outlives the
   markup: the reel's screen label reads as a contrast failure to a sweep
   that resolves backgrounds by walking up for the first opaque
   background-color. The bar behind it paints itself with a
   background-IMAGE gradient, which that walk skips, so the sweep
   attributes the section's cream to the label and scores brand teal at
   1.5:1. Against the bar that actually renders it is 7.63:1 to 10.45:1.
   Recolouring it to --gm-teal-ink would have dropped it to 2.42-3.31:1.
   Check the painted background before "fixing" anything on that bar. */

/* ============================================================
   FOOTER SMALL TEXT — AA CORRECTIONS
   The footer was rebuilt in the Aug 22 refinement pass. Its supporting
   copy is Sorta White at low alpha over the charcoal ground, which
   composites well below AA at these sizes. Alphas raised to clear 4.5:1
   while keeping the tiered hierarchy: links brightest, then the parent
   brand line, then the copyright.
     0.32 composites to rgb(116,116,114) .... 2.43:1
     0.60 composites to rgb(167,167,163) .... 4.71:1
   ============================================================ */
.foot-links a{
  color:rgba(240,239,233,.72);
}
.foot-parent{
  color:rgba(240,239,233,.62);
}
.foot-bottom{
  color:rgba(240,239,233,.60);
}
.foot-social a{
  color:rgba(240,239,233,.72);
}

/* Roadside sign actions -- CALL DINER / GET DIRECTIONS
   Text-only links styled at .56rem, ~17px tall on mobile: under the 24px
   minimum touch target, on a phone-call CTA. Padding grows the tappable
   box; the equal negative margin cancels it back out of the flex row's
   layout, so neither the text position nor the gap to the neighbouring
   link changes -- only the hit area does. */
.roadside-actions a{
  display:inline-block;
  padding:6px 7px;
  margin:-6px -7px;
}

/* Jukebox coin token -- covers the "SELECT" label
   .coin-token's position is defined three times in styles-base.css: a base
   rule, an animation-only rule, and a "compact" variant whose surrounding
   @media(min-width:861px) block closes two rules early, leaking it out to
   apply at every width unconditionally. That compact rule (top:-20px) wins
   the cascade everywhere and puts the coin directly over the right half of
   "25¢ / SELECT" -- measured 19x18px of overlap on the 72x18px label,
   identical at 390px and 1440px. Left as a small negative offset so the
   coin still reads as hovering at the slot, just clear of the label above
   it. */
.coin-token{
  top:1px !important;
}

/* Jukebox vinyl-rack button -- hidden behind the player panel
   .vinyl-rack is not inside .gm-jukebox-shell; it lives in
   .juke-vinyl-field, a sibling that spans the whole .jukebox-section
   (copy text and jukebox graphic together, position:absolute;inset:0).
   Its left:52%/top:56% is a position within that combined area, which
   only clears the graphic once the section's copy+graphic columns sit
   side by side at a wide enough width. Measured: overlapping up to
   1100px (e.g. 40x146px at 1024px), clear from 1152px on -- so this is
   scoped to stop just below that boundary and leaves anything at
   1152px+ untouched. */
@media(max-width:1100px){
  /* First attempt was two different fixes: reposition below the graphic
     under 861px (where copy stacks above it, leaving no free space
     beside it), and shift left within 861-1100px on the theory that the
     side-by-side layout there leaves room beside the panel instead.
     It doesn't: measured gap between the copy column and the player
     panel is only 70-72px at 861-900px (rack is 132px wide) and doesn't
     open up past ~125px until closer to 1000px, and shifting left far
     enough to clear the panel walked the card into the "Monkey Jukebox"
     heading text instead. Below the whole section, where both the
     870-page and side-by-side layouts have already stopped needing that
     horizontal space, is the one spot that holds at every width in this
     range. */
  body[data-page="home"] .jukebox-section{
    padding-bottom:200px;
  }
  /* .vinyl-rack's own transform is translate(-50%,-50%) rotate(-3deg) --
     built to centre the card ON its top/left point. bottom:24px alone
     does not account for that: the existing -50% Y-translate still
     shifts the card up by half its own height afterwards. Keeping
     top+translate as the positioning model, just retargeting the centre
     point, is what actually respects that. */
  .vinyl-rack{
    top:calc(100% - 90px) !important;
    bottom:auto !important;
    left:50% !important;
    transform:translate(-50%,-50%) rotate(-3deg) !important;
  }
}

/* Homepage Hall of Fame "HOUSE PICK" stamp -- behind the heading
   .retro-stamp--hof anchors bottom-right of .sig-head (right:8%;bottom:4px),
   which puts it directly under the last word of "Hall Of Fame." at every
   width from 768px up -- the heading spans nearly the full container, so
   its own bottom edge sits right where the stamp does. Confirmed
   unreadable by screenshot (only "OU P..." visible through the letters).
   Moved to align with the "02 Fan Favourites" row above the heading
   instead, where that label's own text ends well short of the stamp's
   position (up to 511px of clear space measured at 768px) and the
   nearby decorative spark cluster doesn't reach it either. */
.retro-stamp--hof{
  top:2px !important;
  bottom:auto !important;
  right:6% !important;
}

/* "SERVED / 10 LAKH+ / CUSTOMERS" milestone card — CUSTOMERS was cut off
   The card gives .matchbook-inside a fixed band (top/bottom insets inside a
   fixed-height card) and clips it with overflow:hidden. The three lines plus
   their gaps need 2-6px more than that band offers, depending on breakpoint,
   so the last line lost its descenders or vanished entirely -- worst on
   phones, where the card is smallest, but present at every width.

   The room comes from the bottom inset, not from shrinking the type: that
   inset reserves a strip for the "AND COUNTING" line, which sits at
   bottom:8px and needs roughly half of what was set aside. Reclaiming part
   of it, and tightening the row gap by a pixel, leaves real headroom rather
   than landing exactly on the limit the way the original values did. */
.matchbook-deco--stat .matchbook-inside{
  bottom:16px;
  gap:4px;
}
@media(max-width:560px){
  .matchbook-deco--stat .matchbook-inside{
    bottom:14px;
    gap:3px;
  }
}

/* FRANCHISE FORM — bring the enquiry card into the site's own "retro plate"
   family (review board, roadside location card, CRT TV frame all share this:
   a recessed dark fill, a heavy light frame, the brand's offset red drop-
   shadow). The card previously sat at a 5% white tint on a section that is
   already that same dark grey, so it read as a plain, ungrounded form next
   to a page full of diner signage. */
.fr-form{
  background:#2f2f2f;
  border:4px solid var(--gm-white);
  box-shadow:10px 12px 0 var(--gm-red);
}
.fr-form-title{
  display:flex;
  align-items:center;
  gap:10px;
}
.fr-form-title::before{
  content:"";
  width:26px;
  height:3px;
  background:var(--gm-red);
  flex:none;
}
.fr-form-title em{ font-style:normal; color:var(--gm-red); }
.fr-input, .fr-select, .fr-textarea{
  background:rgba(240,239,233,.09);
}
@media(max-width:860px){
  .fr-form{ box-shadow:6px 7px 0 var(--gm-red); }
}

/* FOOTER — brand panel was stretching to match the two link columns'
   height (default grid stretch), which the unbordered link columns don't
   show but the bordered brand panel does: a ~100px empty gap between its
   last line of text and the bottom of its own box. Size it to its content
   instead; the columns are unaffected since grid items default to stretch
   individually unless overridden. */
.foot-brand-panel{ align-self:start; }

/* FIND NEAREST DINER — a button-triggered lookup, not an auto-prompt on
   page load: asking for location the instant someone lands on the page
   reads as pushy and gets reflexively declined, while a labelled button
   makes the value clear before the permission prompt appears. */
.loc-nearest{
  max-width:var(--max);
  margin:0 auto 28px;
  padding:0 var(--pad-x);
  display:flex;
  align-items:center;
  gap:16px;
  flex-wrap:wrap;
}
.loc-nearest-btn{
  background:transparent;
  border:2px solid var(--gm-grey);
  color:var(--gm-grey);
  font-family:inherit;
  font-weight:700;
  font-size:0.78rem;
  letter-spacing:0.04em;
  text-transform:uppercase;
  padding:12px 20px;
  cursor:pointer;
  transition:border-color var(--gm-motion-fast),color var(--gm-motion-fast);
}
.loc-nearest-btn:hover:not(:disabled){ border-color:var(--gm-teal); color:var(--gm-teal); }
.loc-nearest-btn:disabled{ opacity:0.5; cursor:default; }
.loc-nearest-status{
  font-size:0.8rem;
  color:rgba(58,58,58,0.6);
  margin:0;
}
.loc-nearest-status.is-success{ color:var(--gm-teal-ink); font-weight:700; }
.loc-nearest-status.is-error{ color:var(--gm-red-ink); }
@media(max-width:600px){
  .loc-nearest{ flex-direction:column; align-items:flex-start; gap:10px; }
}

/* LOCATIONS — the sticky photo panel wasn't sticking at all, at any
   scroll position, not just near the last row. Measured directly: its
   viewport position tracked scroll 1:1 the entire way down, exactly as
   if position were static.

   Cause: .locations has overflow:hidden (to clip the oversized "KARNATAKA"
   watermark text, which is deliberately 110% wide and would otherwise
   cause horizontal bleed/scroll). Any ancestor with overflow other than
   visible becomes the containing block position:sticky measures against
   -- and because .locations itself never independently scrolls (the
   whole section just moves with the page, like any block element), the
   panel's "stuck" calculation saw no scroll delta to react to and never
   engaged, in any browser, on any device, regardless of screen height.
   This is why it read as "loses the picture on the last row" -- the
   panel was never actually sticking; it was simply sitting at its
   natural position, which happens to still overlap the viewport for the
   first row or two and then scrolls away like any other content.

   Fix: the watermark only overflows horizontally (width:110%), so only
   the X axis needs clipping. overflow-x:clip contains that bleed without
   establishing a scroll container on the Y axis, which is what sticky
   positioning actually depends on here. */
.locations{
  overflow:visible;
  overflow-x:clip;
}

/* With sticky now genuinely engaging, the second half of the original
   symptom still applies once you reach the last row: a position:sticky
   element can never stick past the bottom edge of its containing block,
   and that block currently ends exactly where the list ends, with no
   slack reserved for the panel's own height. Reserved height (measured,
   desktop widths 861-1920px): panel height 460-519px + 96px sticky
   offset. A flat 560px bottom reserve covers that range with a small
   margin, so the panel now stays fully docked through the last row and
   only releases once you've scrolled past it. Only needed at the width
   where the sticky/grid layout is active -- below 860px the section
   switches to a static stacked layout with no sticky panel, so this
   would just be dead space there. */
@media(min-width:861px){
  .loc-list{ padding-bottom:560px; }
}

/* .fr-form is reused by the v2 enquiry section, so this stacking-context
   rule still applies; the .fr-perks/.fr-grid/.fr-void-watermark rules
   that used to sit here were removed with the section 02+ rebuild. */
body[data-page="franchise"] .fr-form{
  position:relative;
  z-index:1;
}

/* FRANCHISE HERO — entrance choreography.
   This is above the fold, so it fires on load like the homepage hero's
   own line-reveal (a scroll-triggered IntersectionObserver would be
   wrong here -- there's no scroll distance for it to trigger on). Both
   sides of the hero animate together -- copy and phone -- so it reads
   as one considered entrance rather than text moving while the media
   panel just pops in static. */
body[data-page="franchise"] .line-mask{ overflow:hidden; display:block; }
body[data-page="franchise"] .line-mask span{
  display:block;
  transform:translateY(115%);
  animation:frLineReveal .7s var(--gm-ease-editorial) forwards;
}
body[data-page="franchise"] .line-mask:nth-of-type(1) span{ animation-delay:.16s; }
body[data-page="franchise"] .line-mask:nth-of-type(2) span{ animation-delay:.28s; }
@keyframes frLineReveal{ to{ transform:translateY(0); } }

body[data-page="franchise"] .fr-hero-in{
  opacity:0;
  transform:translateY(10px);
  animation:frHeroRise .5s var(--gm-ease-editorial) forwards;
}
body[data-page="franchise"] .fr-hero-in--code{ animation-delay:.04s; }
body[data-page="franchise"] .fr-hero-in--sub{ animation-delay:.52s; }
@keyframes frHeroRise{ to{ opacity:1; transform:translateY(0); } }

body[data-page="franchise"] .gm-fr-phone{
  opacity:0;
  transform:scale(.96);
  animation:frPhoneIn .6s var(--gm-ease-editorial) .18s forwards;
}
@keyframes frPhoneIn{ to{ opacity:1; transform:scale(1); } }

body[data-page="franchise"] .gm-fr-hero-controls{
  opacity:0;
  transform:translateY(8px);
  animation:frHeroRise .45s var(--gm-ease-editorial) .6s forwards;
}

@media(prefers-reduced-motion:reduce){
  body[data-page="franchise"] .line-mask span,
  body[data-page="franchise"] .fr-hero-in,
  body[data-page="franchise"] .gm-fr-phone,
  body[data-page="franchise"] .gm-fr-hero-controls{
    animation:none!important;
    opacity:1!important;
    transform:none!important;
  }
}
