/* The venue page, aligned with the native iOS venue screen.
   ios/VegEats/Views/Native/VenueDetailView.swift is the source of truth for
   every number here; Riley worked through the differences on 2026-10-11 and
   signed off on the result.

   THIS SHEET IS LINKED FROM THE VENUE PAGE ONLY, and that is deliberate
   rather than tidy. `footer{border-top:0}` and `footer .shell{padding-left:
   80px}` below are venue-page rules, and style.css is shared with the home
   page, the city pages, the cities list and the closed-venue stub, all of
   which have a footer. Appending these rules to style.css would have
   restyled four page types nobody reviewed.

   It loads AFTER style.css, so these rules win on equal specificity. Where
   a base rule is more specific, the selector below matches it exactly
   rather than raising a number -- see the phone gutter, which lost to
   `html:not(.embed) .shell:has(h1.vtitle)` for an evening.

   The structural half of the same work is sidedish/venue_native.py. */
/* ===== aligned with ios/VegEats/Views/Native/VenueDetailView.swift =====
   VE's spacing scale: s1 4, s2 8, s3 12, s4 16, s5 24, s6 32, s7 48, s8 64. */

/* Every number Riley has tuned is a variable, so the next change is one
   line rather than a hunt through the cascade. */
:root{--tier-gap:36px;--toggle-above:24px;--toggle-below:24px;--first-head-trim:0;--band-top:28px;--foot-above:32px;--gutter-phone:24px}

/* 9 + 12. HOURS ON ITS OWN ROW, with "Closed for good?" beside it. */
/* ALIGNED ON THE BASELINE, NOT THE BOX (Riley, 2026-10-11). The two sit on
   one line at different sizes, 15px for the status and 13px for the
   question, so centring their boxes leaves the smaller text riding high:
   `align-items:center` lines up the middles of two unequal boxes, which is
   not the same as lining up the text. Baseline does that, and both keep a
   ~36px tap target from padding instead of min-height, which baseline
   alignment would otherwise fight. */
.vhours{display:flex;align-items:baseline;flex-wrap:wrap;gap:0 16px;
  margin:2px 0 0}
.vhours .closed-ask{margin:0;padding:9px 0;background:none;border:0;
  line-height:1.2;
  font:inherit;font-size:13px;color:var(--ink-3,#6b6862);cursor:pointer;
  text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:rgba(107,104,98,.45)}
.vhours .closed-ask:hover{color:var(--ink,#1c1b19)}
.vhours .hopen{display:inline-flex;align-items:center}
.vhours .opener{display:inline-flex;align-items:baseline;gap:5px;
  min-height:0;padding:9px 0;background:none;border:0;font:inherit;
  font-size:15px;font-weight:500;line-height:1.2;cursor:pointer;color:inherit}
.vhours .caret{font-size:9px;opacity:.55;line-height:1}

/* 4. ACTIONS AS TILES, matched to `tile()` number for number:
      width 92 fixed, 9 vertical inside, 4 between icon and word, radius 12,
      VE.band behind, 12px Medium, 8 between tiles, 16 above the row.
      --band on the web is #f4f5f0, which IS VE.band (0xF4F5F0), so the
      token is the right thing to use and the rgba() I had guessed is not.
      The icon is size 15 in an 18-tall slot, so 15px of glyph with 1.5
      above and below rather than a stretched 18. */
.acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
/* flex:0 0 92px, NOT width:92px. A flex item shrinks by default, so a
   plain width is a starting size the row is free to compress, and the
   tiles changed size with how many of them there were. The native
   `.frame(width: 92)` does not negotiate, and its comment says why: "One
   fixed size, whatever else is in the row: a venue with no website does
   not stretch its other two." */
.acts a{display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:4px;flex:0 0 92px;padding:9px 0;border-radius:12px;
  background:var(--band,#f4f5f0);color:var(--ink,#1c1b19);text-decoration:none;
  font-family:var(--font-brand);font-weight:var(--font-weight-medium,500);
  font-size:12px;line-height:1.2;border:0}
/* THE HOVER IS A FILL, AND THE OLD UNDERLINE HAS TO BE TURNED OFF
   (Riley, 2026-10-11: "the highlights on the buttons when hovering over
   the website, directions, phone button are weird"). style.css:857 gives
   `.acts a:hover` a `box-shadow: 0 1.5px 0 var(--ink)` -- the right thing
   when these were plain underlined links, and its comment explains it is
   a shadow rather than a thicker border so hovering moves nothing. On a
   filled tile with a 12px radius it draws a hard dark bar across the
   bottom edge, outside the curve. Changing the background was not enough;
   the shadow had to be named and cleared. */
.acts a:hover{background:var(--band-deep,#ecede7);box-shadow:none}
.acts a svg{width:15px;height:15px;display:block;margin:1.5px 0}
.acts a span{display:block}

/* 5. FOOD/DRINKS AS ONE BAND-FILLED PILL, 3px inside, live tab filled. */
.mtabs{display:inline-flex;gap:3px;padding:3px;border-radius:999px;
  background:var(--band,#f4f5f0);border:0;width:max-content;max-width:100%}
.mtabs .mtab{display:inline-flex;align-items:center;gap:6px;padding:8px 16px;
  border-radius:999px;text-decoration:none;border:0;color:var(--ink,#1c1b19);
  font-size:14px;font-weight:500;background:none}
.mtabs .mtab em{font-style:normal;opacity:.7;font-weight:500}
/* THE GREEN STAYS, AND HIDING IT WAS A STRAIGHT MISTAKE (2026-10-11).
   This block used to fill the live tab with `var(--ink)` and set
   `.mhl{display:none}`, on the strength of VenueDetailView's
   `.background(on ? VE.ink : .clear)`. That function's OWN DOCSTRING, one
   line above the code, says "the tab that is on fills brand green" -- so
   the native file contradicts itself and I copied the half that was wrong,
   on the file I had been treating as the source of truth all evening.
   style.css records why the green is right: it is the comp's legend-row
   fill, "already the site's way of saying this one, not those", and `.mhl`
   carries the intro Riley asked for by name -- the green renders at full
   width and shrinks onto the live half so it does not flash in.
   So: no rules here for `.is-on` or `.mhl`. style.css already has them,
   `.mtab.is-on` is `background:none;color:#fff`, and the white label rides
   on the green panel behind it (`.mhl` z-index 0, `.mtab` z-index 1). */
.mtabs .mtab .ti{width:13px;height:13px}

/* 1. THE COUNT ON ITS OWN LINE, 4px under the heading. */
.tier-h em{display:none}
.tier-count{margin:4px 0 0;font-size:16px;line-height:1.35;font-weight:400;
  color:var(--ink-body,#3a382f)}

/* 7 + 8. NO RULES BETWEEN DISHES, AND THE NATIVE RHYTHM.
   Padding on the TOP only: then the gap between two dishes is exactly 27,
   the last dish adds no trailing space, and a tier's 32 is really 32. */
.dish{padding:27px 0 0;border-bottom:0}
.dish:last-child{border-bottom:0}
section.tier .dish:first-of-type{padding-top:28px}

/* THE TIER GAP IS ONE NUMBER NOW. It was 44, spread across two rules that
   both had to be found to change it: `.tier{padding-top:var(--s6)}` is 32
   and `.tier-h{margin-top:var(--s3)}` is 12. The native screen adds the
   same two (section 32 + heading 12), and Riley called 44 too big on the
   web, where the heading is larger and carries a count line under it. Both
   are zeroed and replaced by --tier-gap, so it is one edit. */
.tier{padding-top:0}
.tier-h{margin-top:0}
section.tier{margin-top:var(--tier-gap)}

/* SUPERSEDED NOTE, kept because the reasoning still applies to the first
   tier: the web and VE scales are identical, 4/8/12/16/24/32/48/64.
   `.tier{padding-top:var(--s6)}` is 32 and `.tier-h{margin-top:var(--s3)}`
   is 12, so a tier already opens 44 under the one before it, which is what
   the native screen does (section .padding(.top,32) + heading
   .padding(.top,12)). A margin-top of 32 on top of that made it 76. The web
   and VE scales are identical, 4/8/12/16/24/32/48/64, so the sheet needs no
   help here. Only the FIRST tier differs: native opens it at 12, not 32. */
/* THE FIRST VISIBLE TIER. Measured 2026-10-11: this was 48px under the
   pill, because `section.tier{margin-top:var(--tier-gap)}` (36) and this
   rule's own padding-top (12) BOTH applied. Two properties, one gap, and
   reading the CSS did not show it; a browser did.

   `.svc-first` is set by the strip's script. :first-of-type cannot be used
   on its own here: the service filter hides whole tiers, so the first tier
   a reader sees is usually not the first one in the document. Both are
   listed so a page with no services, or a reader with no JavaScript, still
   gets the right first tier. */
.menu-panel > section.tier:first-of-type,
.menu-panel > section.tier.svc-first{
  margin-top:var(--toggle-below);padding-top:0}
.menu-panel > section.tier:first-of-type > .tier-h,
.menu-panel > section.tier.svc-first > .tier-h{
  margin-top:var(--first-head-trim)}
/* ...and a tier that follows a visible one keeps the full gap. */
.menu-panel > section.tier.svc-first ~ section.tier:not(.svc-first){
  margin-top:var(--tier-gap);padding-top:0}

/* ABOVE AND BELOW THE PILL. Two rules contribute above it and neither is
   on .menubar: `.band{padding-bottom:var(--s4)}` is 16 and
   `.menubar{padding-top:var(--s5)}` is 24, so the pill sat 40 below the
   header. Both are named here. */
.band{padding-bottom:0}
/* THE GAP HANGS ON THE PILL, NOT ON ITS WRAPPER (Riley, 2026-10-11: "the
   food and drinks toggle is overlapping the website directions and phone
   buttons"). It was on `.menubar`, and `.menubar` IS NOT ALWAYS THERE:
   the builder wraps the toggle in one only when there is something to sit
   beside it, so on The Grain Cafe and Lil' Vegerie `nav.mtabs` is a direct
   child of `.menucol.tabbed` and the padding had nothing to land on.
   Measured at 900px: Kyushu `acts>pill=24`, Grain and Vegerie `acts>pill=0`
   -- the toggle flush against the action tiles, which reads as overlapping
   them. Riley first supposed the allergen chips caused it and then found it
   on a page with none, which is what ruled the wrapper in.
   `.mtabs` always exists when there is a toggle at all, so the number goes
   there and the wrapper keeps nothing of its own. */
.menubar{padding:0;gap:0}
.mtabs{margin-top:var(--toggle-above)}

/* 13. THE QUESTION BOX, AS THE NATIVE ONE. Riley, 2026-10-11. `AskBox`:
       13.5pt Book, 2pt line spacing, 14 horizontal / 11 vertical inside, a
       14pt radius, the ask tint behind it and a 1px ask edge. The page had
       replaced that box with "a plain indented line ... marked by the ask
       colour as a rule down its left edge", which is the thing being undone.
       The palette already exists here and --ask-ink is an exact match for
       the native askInk, #6a4a76.

       ABOVE IT IS 16, NOT 4, AND I HAD ONLY HALF OF IT. The box carries
       `.padding(.top, VE.s1)` = 4 of its own, and the CALL SITE in
       VenueDishRow adds `.padding(.top, VE.s3)` = 12 on top. Reading the
       component alone gives 4 and a box that sits almost against the
       description above it. Below stays 3, which is the box's own, and is
       deliberately tighter than the dish row's 12: its own comment says a
       hard edge reads closer than a line of text. */
/* OPTION C (Riley, 2026-10-13, lane DSN): white inside, a dashed grey
   outline and body-ink text, matching the build panel's ask pill (whose
   #d2d4cd went faint around a box this size, hence #c4c6bf). Every box
   opens with one bold lead word, written by sidedish/ask_lead.py. */
.dish-ask{margin:16px 0 3px;padding:11px 14px;border-radius:14px;
  background:#fff;border:1px dashed #c4c6bf;
  color:var(--ink-body,#1a1c16);font-size:13.5px;line-height:1.55}
.dish-ask b{color:var(--ink-body,#1a1c16);font-weight:var(--font-weight-medium,500)}

/* ABOVE THE VENUE NAME (Riley, 2026-10-11). On a venue page the breadcrumb
   is `display:none` (html:not(.embed) .band:has(h1.vtitle) .crumbs), so the
   only thing over the title is the band's own 40px top padding. That one
   number is the whole gap. */
html:not(.embed) .band:has(h1.vtitle){padding-top:var(--band-top)}

/* 15. THE FOOTER. No rule over it, and the native screen's own numbers:
       12.5px Book in ink-3, 32 above (legalFoot .padding(.top, VE.s6)). The
       sheet had a border-top, 48 of padding and 64 of margin. */
footer{border-top:0;margin-top:var(--foot-above);padding-top:0;font-size:12.5px;
  line-height:1.5;color:var(--ink-3,#6b6862)}
.legal-foot{margin-top:12px;max-width:none}

/* THE FOOTER NEVER LINED UP WITH THE PAGE, AND I MADE IT WORSE.
   The content column gets its 80px gutter from
   `html:not(.embed) .shell:has(h1.vtitle)`. The footer's own .shell holds
   no h1, so it never matched that rule and sat on the base 24px: out of
   line with the dish names by 56px on desktop, from the day it shipped.
   Then my phone-gutter fix zeroed `.shell` padding and moved the gutter
   onto the :has() selector, which the footer also does not match, so on a
   phone it lost its last 24 and ran into the screen edge. Both fixed by
   giving the footer the same numbers as the column it sits under. */
footer .shell{max-width:1760px;padding-left:80px;padding-right:80px;
  box-sizing:border-box}

/* 11. NO RULES IN "OTHER VEGAN OPTIONS NEARBY" either. Riley, 2026-10-11.
       Same treatment the dish list just got: `.near a` carried a
       border-bottom and `:first-child` a border-top, so a three-item list
       was four lines. Padding drops from var(--s4) 16 to 12 top-only, so
       the rows close up now that nothing separates them. */
.near a{border-bottom:0;padding:12px 0 0}
.near a:first-child{border-top:0;padding-top:4px}

/* 8. THE PHONE GUTTER IS THE HEADER BAR'S, 24px (Riley, 2026-10-11: match
      the logo and Sign Up). `.bar{padding:var(--s4) var(--s5)}` under 700px
      is 24 at the sides, and the native screen's own gutter is VE.s5 = 24
      too, so all three agree at one number.

      THE BREAKPOINT MOVES TO 700 TO MATCH THE BAR. Mine was 640 and the
      bar's is 700, so between those two widths the logo sat at 24 while the
      content below it was still at the desktop 80.
   10. NO MAP ON A PHONE. Riley, 2026-10-11. The native screen has no map on
       the venue view either; Directions is a tile that hands off to Maps.
       Hiding the whole rail-block, not just #minimap, so the block's own
       spacing goes with it. NOTE FOR THE REAL BUILDER: display:none still
       downloads minimap.js and whatever tiles it asks for, so the page
       builder should also skip the script under this width rather than
       paint something nobody sees. */
@media (max-width:700px){
  /* THE PHONE GUTTER WAS 80px AND MY 24 LOST ON SPECIFICITY.
     `html:not(.embed) .shell:has(h1.vtitle){padding-left:80px}` carries no
     media query, so the desktop gutter applied to a 390px screen, and a
     plain `.shell{padding:0 24px}` could not beat it. Matching the selector
     is what wins, not raising the number. */
  html:not(.embed) .shell:has(h1.vtitle){
    padding-left:var(--gutter-phone);padding-right:var(--gutter-phone)}
  /* EVERY shell, not just the one with the title: the footer is a .shell
     too, and zeroing them all is what pushed its text off the screen. */
  .shell,footer .shell{
    padding-left:var(--gutter-phone);padding-right:var(--gutter-phone)}
  .band,.menucol{padding-left:0;padding-right:0}
  /* FOUND IT: 64px of it was .with-rail's own padding-bottom.
     `display:contents` neutralises that box, but that rule lives inside
     @media (min-width:1021px), so on a phone .with-rail is a REAL grid box
     carrying padding-bottom:var(--s8) = 64 AND, from the max-width:1080
     rule that makes it one column, a row gap of var(--s7) = 48. Neither is
     visible on desktop, which is why reading the desktop cascade kept
     giving me the wrong answer. The footer's own margin is the whole gap
     now. */
  .with-rail{padding-bottom:0;gap:var(--s6)}
  footer{margin-top:18px}
  .rail-block:has(> .minimap){display:none}
  #minimap{display:none}
}

/* THE DIRECTIONS GLYPH, DRAWN FROM THE SHEET (Riley, 2026-10-11: "what
   happened to the direction icon it looks broken").

   The icon it replaces is INLINE SVG baked into 92,239 pages, and the
   honest fix is to rewrite them -- `sidedish/venue_native.py` now emits
   this same arrow, so the next page build does exactly that. But every
   page change re-bundles all 4,096 shards and that is a 6.6 GB publish,
   about an hour, for one wrong glyph. The same pixels come out of the
   stylesheet in a minute, so this draws it here and hides the baked-in
   one until the markup catches up.

   WHY THE OLD ONE WAS BROKEN, and only a rendering showed it: it copied
   SF Symbol `arrow.triangle.turn.up.right.diamond`, whose diamond spans
   the full 16-unit box and leaves ~7px of arrow once the tile draws it at
   15px. It rendered as a blob. Its arrowhead also ended at x=10.6 while
   the arm stopped at 10.2.

   Keyed on the href because that is what the link IS -- a maps URL --
   rather than on the word "Directions", which is a label and is the kind
   of vocabulary test this project does not allow. When the pages are next
   rebuilt the rule still holds: the mask and the inline SVG are the same
   artwork, so hiding one and painting the other is the same picture. */
.acts a[href*="maps."] svg{display:none}
.acts a[href*="maps."]::before{
  content:"";display:block;width:15px;height:15px;margin:1.5px 0;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2016%2016%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.6%22%20stroke-linejoin=%22round%22%20stroke-linecap=%22round%22%3E%3Cpath%20d=%22M3.2%2013.4V8.2a2.4%202.4%200%200%201%202.4-2.4h5.2%22/%3E%3Cpath%20d=%22M8.6%203.4%2011%205.8%208.6%208.2%22/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2016%2016%22%20fill=%22none%22%20stroke=%22%23000%22%20stroke-width=%221.6%22%20stroke-linejoin=%22round%22%20stroke-linecap=%22round%22%3E%3Cpath%20d=%22M3.2%2013.4V8.2a2.4%202.4%200%200%201%202.4-2.4h5.2%22/%3E%3Cpath%20d=%22M8.6%203.4%2011%205.8%208.6%208.2%22/%3E%3C/svg%3E") center/contain no-repeat}

/* THE "CLOSED?" PANEL ANCHORS TO THE HOURS ROW. The button cannot hold an
   absolutely positioned child of its own, so the panel is appended to
   `.vhours` and positioned against it. Everything else it inherits from
   `.hrspop`, which is the hours dropdown, so the two are the same object
   to a reader. */
.vhours{position:relative}
.clpop{left:auto;right:auto;min-width:230px}
.clpop .clpop-body{display:flex;flex-direction:column;gap:6px;padding:2px 0 0}
.clpop .vopt{display:block;width:100%;text-align:left;padding:9px 11px;
  border-radius:9px;border:1px solid var(--rule,#e3e3e0);background:none;
  font:inherit;font-size:13.5px;color:var(--ink,#1c1b19);cursor:pointer}
.clpop .vopt:hover{background:var(--band,#f4f5f0);border-color:var(--ink-3,#6b6862)}
.vhours .closed-ask.is-done{text-decoration:none;cursor:default;opacity:.75}

/* ROOM ABOVE THE FOLD CONTROL (Riley, 2026-10-11: "the show all dishes
   that are not vegan button needs padding above it"). It sat directly
   under the tier's own count line with only the summary's 8px below it
   for company. */
.tier-fold > summary{margin-top:18px}

/* THE FROST BEHIND A POPUP, BUILT FROM THE NATIVE ONE (Riley, 2026-10-11,
   twice: "i'm not seeing the frosted glass ... please look at ios app for
   reference"). The first attempt washed the WHOLE viewport in
   rgba(255,255,255,.55) over a 6px blur, which is the wrong way round and
   reads as a flat white fade rather than glass.

   `HoursViews.Frost` is `.ultraThinMaterial` with `Color.white.opacity(0.3)`
   over it: a HEAVY blur under a LIGHT wash. And `hoursPopLayer` does not
   cover the screen -- its own comment says the frost runs "from just under
   the tapped line (so the name and status stay sharp) to the venue's last
   row", with "its edges feathered rather than cut". So the masthead, the
   venue name and the line you tapped all stay sharp, and only what is
   below goes soft. `top` is set from the anchor by the script that opens
   the panel.

   The feather is two gradients intersected, which is the nearest CSS has
   to the native `.mask(RoundedRectangle(14).padding(4).blur(5))`. */
.sd-frost { position: fixed; left: 0; right: 0; bottom: 0; top: 0;
  z-index: 21; border-radius: 14px 14px 0 0;
  background: rgba(255,255,255,.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0, #000 7px),
    linear-gradient(to right, transparent 0, #000 10px,
                    #000 calc(100% - 10px), transparent 100%);
  mask-image:
    linear-gradient(to bottom, transparent 0, #000 7px),
    linear-gradient(to right, transparent 0, #000 10px,
                    #000 calc(100% - 10px), transparent 100%);
  -webkit-mask-composite: source-in; mask-composite: intersect;
  animation: frostIn .22s ease-out; }
.sd-frost.leaving { animation: frostOut .16s ease-in forwards; }
@media (prefers-reduced-motion: reduce) {
  .sd-frost, .sd-frost.leaving { animation: none; }
}

/* A4: THE TOPIC IN THE H1, THE ANSWER UNDER IT, THE VISIBLE DATE.
   sidedish/venue_native.py `intro()` writes the markup. The H1 reads "Vegan
   options at <Name>" to a crawler and a screen reader; to a person the name
   is still the title, and "Vegan options at" is a small line over it.
   (If the eyebrow is ever unwanted, swap it for the visually-hidden clip
   pattern: position:absolute;width:1px;height:1px;overflow:hidden;
   clip:rect(0 0 0 0);white-space:nowrap. The H1 text is unchanged either
   way.) */
h1.vtitle .kicker{display:block;font-size:12.5px;line-height:1.3;
  font-weight:var(--font-weight-medium,500);letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3,#6b6862);margin:0 0 6px}
.band .answer{margin:14px 0 0;max-width:62ch;font-size:15.5px;line-height:1.55;
  color:var(--ink-body,#3a382f)}
.band .updated-line{margin:8px 0 0;font-size:12.5px;line-height:1.4;
  color:var(--ink-3,#6b6862)}

/* Lane PF: the closed page's "Still looking for vegan food?" container at the
   foot of an open venue page. On desktop the shell is a two-column grid (menu
   | map and rail), so the container spans both rather than sitting in the
   menu column. Everything else about `.usp` is style.css's, unchanged. */
@media (min-width:1021px){
  html:not(.embed) .shell:has(> .band h1.vtitle) > .usp{grid-column:1 / -1}
}

/* 16. BUILD-YOUR-OWN PANELS (lane DSN, Riley 2026-10-13). A quiet panel
   under a chain dish, one row per step, every choice a pill: vegan, then
   ask, then not vegan. Markup: sidedish/build_panel.py. Values are the
   -final previews' (docs/lanes/DSN-SETTLED.md). */
.bld{max-width:var(--measure,42em);font-family:var(--font-brand)}
.bld .dot{width:8px;height:8px;margin:0 6px 0 0;flex:0 0 auto}
.bsame p{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink-3,#6e7566)}
.bsame b{font-weight:var(--font-weight-medium,500);color:var(--ink-2,#3e5215)}
.bld-a{margin:14px 0 3px;padding:19px 14px 19px 21px;border-radius:14px;
  background:var(--band,#f4f5f0)}
.bld-a.bsame{padding:14px 14px 14px 21px}
.bstep{display:grid;grid-template-columns:76px minmax(0,1fr);column-gap:10px;
  padding:0}
.bstep + .bstep{margin-top:22px}
.bk{font-size:12.5px;line-height:26px;font-weight:var(--font-weight-medium,500);
  color:var(--ink-3,#6e7566)}
.bchips{display:flex;flex-wrap:wrap;gap:6px}
.bc{display:inline-flex;align-items:center;padding:3px 10px 3px 8px;
  border-radius:999px;background:#fff;border:1px solid rgba(62,82,21,.12);
  font-size:13px;line-height:18px;color:var(--ink-body,#1a1c16)}
/* NOT VEGAN: the same pill, pushed back. Background, border and dot at 0.5;
   the text at 0.65 so it keeps 5.2:1 against the faded pill (a flat
   opacity:0.5 would leave it at 3.3:1). */
.bc-no{background:rgba(255,255,255,.5);border-color:rgba(62,82,21,.06);
  color:color-mix(in srgb,var(--ink-body,#1a1c16) 65%,transparent)}
.bc-no .dot{opacity:.5}
/* ASK: white pill, neutral grey dashed border, purple dot, muted "ask". */
.bc em{font-style:normal;margin-left:5px;font-size:11.5px;color:var(--ink-3,#6e7566)}
.bc-dash{border:1px dashed #d2d4cd}
/* "+N not vegan": phones only; build_fold.js opens the step on tap. */
.bc-more{display:none;font:inherit;font-size:13px;cursor:pointer}
.bfold{display:contents}
@media (max-width:700px){
  .bc-more{display:inline-flex;font-size:12.5px}
  .bfold{display:none}
  .bv.is-open .bfold{display:contents}
  .bv.is-open .bc-more{display:none}
  .bld-a{padding:16px 12px 16px 17px}
  .bld-a.bsame{padding:12px 12px 12px 17px}
  .bstep{grid-template-columns:62px minmax(0,1fr);column-gap:8px}
  .bk{font-size:12px}
  .bc{font-size:12.5px;padding:2px 9px 2px 7px}
}

/* Riley 2026-10-15: no visible "Updated <date>" line; the date stays in the page's JSON-LD dateModified and the sitemap. */
.band .updated-line{display:none!important}
