/* ==========================================================================
   DIRECTION D — "In-house" (built to match test A - sheet1_es_inhouse.pdf)
   Source Serif 4 Display (headers, dish names) + Source Sans 3 (apparatus).
   Rust-red accent carries the logo and section headers; the list itself
   stays quiet — black dish names, grey descriptions, no rules between
   columns. One long pull-quote essay grounds each spread.
   ========================================================================== */

:root{
  --base: 4mm;
  --mt: 9mm; --mb: 20mm; --ml: 9mm; --mr: 9mm;
  --col-gap: 9mm;

  --t1: 15pt;    /* group / section header (small caps) */
  --t2: 10pt;    /* dish name          */
  --t3: 9pt;     /* description        */
  --t4: 8pt;     /* apparatus / extras / bracket note — floor, never smaller */
  --price: 9pt;
  --cap: 10pt;   /* default caption size; theme.capSize overrides it
                    at runtime, and a single caption can override that
                    again with its own inline font-size */  /* the ONE caption size — every italic text block */
  --essay: 14pt; /* centred pull-quote size — matches page-1 welcome quote (.essay-intro) so every section's closing pull-quote reads the same size; .essay.wide (wine page 2-col body) pinned separately below, not tied to this */

  --ink: #14110f;
  --ink-2: #3a3532;
  --ink-3: #6b625c;
  --accent: #a32e1c;
  --frame: var(--accent);   /* section enclosure — follows the accent */
  --rule: #c9c0b8;
  --note: #85504a;  /* grey/red tint for descriptive statements (group notes, essays) — distinct from both plain ink and the bright accent */
  --veg: #5c7a4d;   /* muted olive green — dietary dots only, kept out of the red/ink accent system */
}

@font-face{font-family:SS4;src:url(../../fonts/SS4-txt-400.ttf);font-weight:400}
@font-face{font-family:SS4;src:url(../../fonts/SS4-txt-600.ttf);font-weight:600}
@font-face{font-family:SS4;src:url(../../fonts/SS4-txt-700.ttf);font-weight:700}
@font-face{font-family:SS4;src:url(../../fonts/SS4-txt-400i.ttf);font-weight:400;font-style:italic}
@font-face{font-family:SS4Disp;src:url(../../fonts/SS4-disp-400.ttf);font-weight:400}
@font-face{font-family:SS4Disp;src:url(../../fonts/SS4var.ttf);font-weight:600}
@font-face{font-family:SS4DispI;src:url(../../fonts/SS4Ivar.ttf);font-weight:400;font-style:italic}
@font-face{font-family:SSans;src:url(../../fonts/SSans3-400.ttf);font-weight:400}
@font-face{font-family:SSans;src:url(../../fonts/SSans3-600.ttf);font-weight:600}
@font-face{font-family:SSans;src:url(../../fonts/SSans3-400i.ttf);font-weight:400;font-style:italic}



*{margin:0;padding:0;box-sizing:border-box}
body{font-family:SS4;color:var(--ink);font-size:var(--t3);
     -weasy-hyphens:none;hyphens:none;text-align:left}

/* ---- masthead: big wordmark lockup left (logo + tagline stacked,
   tagline centred under the logo's own width), big section/page marker
   right (label, then page count + language tags below it, same lockup
   logic, mirrored). Phone/Instagram moved down into the footer, folded
   into the same line as the allergen text — languages stay up here. --- */
/* two independently baseline-aligned rows — row 1: logo sits on the same
   line as CARTA; row 2: tagline sits on the same line as the page count
   and language tags. Matches Richard's Illustrator layout exactly (verified
   by pixel-measuring both PDFs): each row's two halves share a bottom edge,
   rather than the old single flex row that vertically centered the whole
   2-line brand block against the whole 2-line cartatag block. */
.mast{margin-bottom:3mm}
.mast-row1,.mast-row2{display:flex;justify-content:space-between;align-items:flex-end}
.mast .mast-col{width:48mm;flex-shrink:0}
.mast .logo{width:48mm;height:auto;display:block}
.mast .logo .st0,.mast .logo .st1{fill:var(--accent) !important}
.mast .tagline{display:block;
               font-family:SSans;font-size:15pt;
               color:var(--ink);letter-spacing:.0975em; /* tracked out just
               enough that "el gastrolibanés" as one run reaches exactly as
               far right as "gastrolibanés" used to when the two words were
               flex-spread apart — solved by measuring the logo's own ink
               edges pixel-by-pixel, not estimated from font metrics */
               margin-left:2.05mm; /* the logo SVG's own path has ~2mm of empty
               space before the "B" stroke begins — this offset lines the
               tagline's left edge up with the logo's ink on that side */
               white-space:nowrap;hyphens:none;-weasy-hyphens:none}
.mast .ct-label{font-family:SS4Disp;font-weight:600;font-size:24pt;
              color:var(--accent);font-variant:small-caps;letter-spacing:.02em;
              line-height:1}
.mast .ct-num{font-family:SSans;font-size:10pt;color:var(--ink-3);
              letter-spacing:.06em;display:flex;
              justify-content:flex-end;align-items:baseline}
/* language tags: active language (the one the preview/PDF is currently set
   to) shown in accent red; the other two stay grey. ESP/ENG are live
   buttons (editor.js's setPreviewLang) — click either to redraw the whole
   preview in that language, then "Descargar PDF" prints what's showing.
   AR has no menu data behind it yet, so it's shown but not clickable. */
.mast .langs{margin-left:1.5mm;padding-left:1.5mm;border-left:.6pt solid var(--rule)}
.mast .langs.no-sep{margin-left:0;padding-left:0;border-left:none}
.lang{color:var(--ink-3);font-weight:400}
.lang.active{color:var(--accent);font-weight:600}
.lang+.lang{margin-left:1.5mm}
.lang[data-lang-btn]{cursor:pointer;-webkit-tap-highlight-color:transparent}
.lang[data-lang-btn]:hover{color:var(--accent)}
.lang[data-lang-btn]:focus-visible{outline:1.5px solid var(--accent);outline-offset:2px;border-radius:2px}
.lang.lang-disabled{cursor:default;opacity:.55}
.lang.lang-disabled:hover{color:var(--ink-3)}
.mast-rule{border-top:.6pt solid var(--rule);margin:.5mm 0}

/* ---- list ----------------------------------------------------------------
   fixed N-up columns, one group per column — but split into two grid ROWS
   (head row: title+tagline, body row: the items) rather than one flex
   column each. Grid row-tracks size to the tallest cell in that row, so
   every column's item list starts on the same line no matter how long any
   one column's title/tagline runs. ------------------------------------- */
.cols{display:grid;column-gap:var(--col-gap);grid-auto-rows:min-content;
      align-items:start;grid-auto-flow:row dense}
.cols-1{grid-template-columns:1fr}
.cols-2{grid-template-columns:1fr 1fr}
.cols-3{grid-template-columns:1fr 1fr 1fr}
.col-head{grid-row:1}
/* ---- SECTION ENCLOSURE ---------------------------------------------------
   .col-frame is an EMPTY grid item spanning both rows of one column, drawn
   behind the .col-head/.col-body cells that occupy the same two cells.
   Two things this depends on, both easy to break:
     - .cols sets align-items:start, which collapses an empty grid item to
       zero height — hence the explicit align-self:stretch here;
     - overlapping grid items only works with an explicit grid-column on all
       three (set inline by the JS from the column index) — auto-placement
       would push head/body into fresh columns instead.
   Because the row-2 track sizes to the tallest column body, every frame on
   a page ends on the same line. That alignment is the real fix for ragged
   column bottoms; the box just makes it visible. -------------------------- */
.framed{--pad-x:7.4mm;--pad-t:3.1mm;--pad-b:2.6mm;--pad-r:4mm;column-gap:4mm}
.framed .col-frame{grid-row:1 / span 2;align-self:stretch;
                   border:1pt solid var(--frame);
                   border-radius:4.5mm;margin-top:var(--pad-t);z-index:0}
.framed .col-head,.framed .col-body{position:relative;z-index:2;
                   padding-left:var(--pad-x);padding-right:var(--pad-r)}
/* the frame ends exactly at the grid's bottom edge, so the body carries the
   bottom inset as real padding — a negative margin on the frame would hang
   it outside the grid box and collide with the footer. */
.framed .col-body{padding-bottom:var(--pad-b);z-index:1}
/* title punches through the frame's top edge — white knockout behind the
   small-caps head, negative margin so its ink still starts flush with the
   item names below it. */
.framed .col-head h2{display:inline-block;background:#fff;
                     padding:0 2.2mm;margin-left:-2.2mm}
.framed .grp{margin-bottom:0}
/* switched-off frame: the box still occupies exactly the same space and the
   head/body keep their padding, so toggling it moves nothing on the page —
   only the rule itself disappears. */
.framed .col-frame.frame-off{border-color:transparent}
.framed .modrow .plus-hang{left:-3.6mm}
.col-body{grid-row:2}
.grp{margin-bottom:calc(1.7*var(--base))}

/* two-groups-stacked-per-column pages (cervezas+zumos | cócteles+sin
   alcohol): same grid technique, but each cell is a whole group (head+
   body together), so the divider between the stacked groups lands on the
   same line in both columns, regardless of which top group is taller. */
.stack-grid{grid-template-columns:1fr 1fr;row-gap:calc(1.4*var(--base))}

/* ---- red title block: always its own visual unit, clearly separated
   from the list underneath it. -------------------------------------------*/
.ghead{margin-bottom:calc(1.3*var(--base))}
.ghead h2{font-family:SS4Disp;font-weight:600;font-size:var(--t1);color:var(--accent);
        font-variant:small-caps;letter-spacing:.02em;line-height:1.2;
        margin-bottom:0}
.ghead .note{font-family:SSans;font-style:italic;font-size:var(--t4);
           color:var(--ink-3);margin-top:.2mm}
.ghead .note.placeholder{color:#b9b0a8}
.ghead .subtitle{font-family:SSans;font-size:var(--t4);color:var(--ink-3);
               text-transform:uppercase;letter-spacing:.08em;margin-top:.2mm}

.it{margin-bottom:calc(.95*var(--base));break-inside:avoid}
/* food pages only (main, breakfast) — doubled breathing room between
   plates, per Richard's request. Drinks/coffee/wine keep the tighter
   original spacing (.food-cols marks main+breakfast's item grid only). */
.food-cols .it{margin-bottom:calc(1.62*var(--base))}
/* café page: short columns, so its plates get even more air and the framed
   boxes reach the foot of the page instead of stopping halfway down. */
.airy-cols .it{margin-bottom:calc(2.4*var(--base))}
.it .n{position:relative;display:flex;align-items:center;gap:2mm;font-family:SS4Disp;
       font-weight:600;font-size:var(--t2);line-height:1.25;color:var(--ink)}
.it .n .name{flex:1 1 auto}
.it .n .pr{font-family:SSans;font-weight:600;font-size:var(--price);
           color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.it .n .u{font-size:var(--t4);color:var(--ink-3)}
.it .v{font-style:italic;color:var(--ink-2);font-family:SS4}
.it .d{font-size:var(--t3);line-height:1.3;color:var(--ink-3);margin-top:.6mm;max-width:92%}

/* ---- allergen reference numbers, in square brackets, reading against
   the numbered key in the footer. Printed right after a dish's
   description; for description-less items (most drinks/coffee) they
   follow the title itself instead, inside .n .name. Styled to read as
   plain description text — same font, weight, size and colour as .d —
   regardless of which line they land on, per Richard. */
.it .d .allg, .it .n .allg{font-family:SS4;font-weight:400;font-size:var(--t3);
             font-style:normal;color:var(--ink-3);margin-left:.9mm;white-space:nowrap}

/* ---- dietary dots: base shape shared everywhere it appears (dish
   items + legend key), colour only — positioning is scoped separately
   below since the two contexts need opposite behaviour. --------------- */
.tag-dot{display:inline-block;width:2mm;height:2mm;border-radius:50%;flex-shrink:0}
.tag-dot.vegan{background:var(--veg)}
.tag-dot.vegetarian{background:none;border:1.1pt solid var(--veg)}

/* dish items: hanging bullet OUTSIDE the text column, to the left of the
   dish name — not an inline/flex element, so the name always starts
   flush with the red column title above it (same left edge), exactly
   like a hanging-indent bullet list. Positioned absolutely against
   .it .n (position:relative), so it never affects the text's own layout
   or width. Omitted entirely for meat items (the default, unmarked)
   rather than rendered invisible, since it no longer needs to reserve
   any space. ------------------------------------------------------------ */
.it .n .tag-dot{position:absolute;left:-4mm;top:50%;transform:translateY(-50%)}

/* ---- two-tone dish names: the proprietary / namesake word keeps full ink
   weight, the generic food word steps back to the description grey. Only
   fires where the data already records a `namesake`. ---------------------- */
.house-mark{color:var(--accent)}
.it .nm-key{font-weight:600;color:var(--ink)}
.it .nm-gen{font-weight:400;color:var(--ink-3)}

/* ---- mark cluster: a dish can carry BOTH the house mark and a dietary
   mark. They hang together in one right-aligned group outside the text
   column, so 0, 1 or 2 marks all leave the dish name flush with the section
   title above it. Order is fixed — house mark first — and the legend lists
   them in the same order. height:1.25em is one line box of .n, so the
   cluster centres on the FIRST line of a name that wraps. ---------------- */
.it .n .marks{position:absolute;right:100%;margin-right:1.3mm;
              top:0;height:1.25em;
              display:flex;align-items:center;
              gap:.8mm;white-space:nowrap}
.it .n .marks .tag-dot{position:static;top:auto;left:auto;transform:none}

/* ---- legend: small key explaining the dots. Lives inside .footblock,
   directly above .foot's own rule — food pages only (main, breakfast),
   cleared on drinks/coffee/wine pages by the running-element reset in
   the foot() macro. No rule of its own — the footer's rule below it
   is enough. ------------------------------------------------------- */
.legend{font-family:SS4Disp;font-weight:600;font-size:var(--t2);color:var(--ink);
        display:flex;align-items:center;gap:5mm;margin-bottom:1.5mm}
.legend .key{display:flex;align-items:center;gap:1.8mm;white-space:nowrap}

/* ---- add-ons: full-size items (not the small italic .extras line),
   separated from the group's regular items by a rule, "+" in accent red -- */
.addons{margin-top:calc(1*var(--base));padding-top:calc(.7*var(--base));
        border-top:.6pt solid var(--rule)}

.new{display:inline-block;font-family:SSans;font-weight:600;font-size:8pt;
     letter-spacing:.08em;text-transform:uppercase;color:var(--accent);
     border:.5pt solid var(--accent);border-radius:.5mm;padding:.3mm 1.4mm;
     margin-bottom:.8mm}

.mods{margin-top:.6mm}
.extras{margin-top:calc(.5*var(--base))}

/* ---- modrow: one "+" modifier/addon per row — same font size as the
   description text directly above it (var(--t3)), price right-aligned
   to the same edge as the dish's own price above it (both are flex rows
   of equal width), "+" hanging outside the text at the same position as
   the dietary dot (-4mm), so pluses and dots line up in one column.
   Used by both .mods (per-item modifiers) and .extras (group-level
   footnote list) — wine's "Selección de la casa" note reuses .mods but
   not .modrow, so it's untouched by any of this. --------------------- */
.modrow{position:relative;display:flex;align-items:baseline;gap:2mm;
        font-family:SSans;font-weight:600;font-size:var(--t3);color:var(--accent);
        line-height:1.3;hyphens:none;-weasy-hyphens:none}
.modrow + .modrow{margin-top:.4mm}
.modrow .plus-hang{position:absolute;left:-4mm;top:50%;transform:translateY(-50%)}
.modrow .mod-name{flex:1 1 auto}
.modrow .mod-sub{font-style:italic;font-weight:400}
.modrow .mod-price{font-variant-numeric:tabular-nums;white-space:nowrap}

/* ---- extras band: full-width titled strip of add-ons, spread across
   three columns beneath a page's main groups (e.g. especialidades ->
   toum, tarator, extra pan...). Same red-title/subtitle language as any
   other group header, so it reads as a proper section, not a footnote. */
.eband{margin-top:calc(1.6*var(--base));padding-top:calc(1*var(--base))}
.eband-grid{display:grid;grid-template-columns:1fr 1fr 1fr;column-gap:var(--col-gap);
            row-gap:calc(.6*var(--base))}
.eb-it{display:flex;align-items:baseline;gap:2mm;font-family:SS4Disp;font-weight:400;
       font-size:var(--t3);line-height:1.25;color:var(--ink);break-inside:avoid}
.eb-n{flex:1 1 auto}
.eb-sub{font-style:italic;color:var(--ink-3);font-family:SS4;font-size:var(--t4)}
.eb-p{font-family:SSans;font-weight:400;font-size:var(--price);color:var(--ink);
      white-space:nowrap;font-variant-numeric:tabular-nums}

/* ---- wine rows: name/region/desc on the left, copa/botella prices
   stacked and right-aligned on the right — same right-aligned-price logic
   as every other item on the menu, just stacked two-high. Keeps the
   description clear of the prices and shaves a line off every row, so
   the wines page runs shorter and the footer sits further from the text. */
.wine .region{font-style:italic;color:var(--ink-3);font-size:var(--t4)}
.wine .wine-row{display:flex;justify-content:space-between;align-items:flex-start;gap:3mm}
.wine .wine-main{flex:1 1 auto;min-width:0}
.wine .wine-price{flex:0 0 22mm;display:flex;flex-direction:column;align-items:flex-end;
                   gap:.5mm;margin-top:.3mm}
.wine .wp{display:flex;align-items:baseline;gap:1.5mm;white-space:nowrap}
.wine .wp-l{font-family:SSans;font-size:var(--t4);color:var(--ink-3)}
.wine .wp-v{font-family:SSans;font-weight:600;font-size:var(--price);color:var(--ink);
            font-variant-numeric:tabular-nums}
.wine .house .name{color:var(--accent)}

/* ---- subgroups (wine Blancos/Tintos) & sidebar (teas -> cafe_blanc) ---- */
.subgrp{margin-bottom:calc(1*var(--base))}
.subgrp h3{font-family:SSans;font-weight:600;font-size:var(--t4);color:var(--accent);
           text-transform:uppercase;letter-spacing:.08em;margin-bottom:calc(.5*var(--base));
           margin-top:calc(.9*var(--base))}
.sidebar{margin-top:calc(1.1*var(--base))}
.sidebar .n{font-style:italic}

/* ---- essay: centred pull-quote, once per section — no top/bottom rule,
   spacing alone (padding) sets it apart from the lists around it -------- */
/* ---- captions: one style for every italic text block on the page, whether
   it sits under the masthead, under the columns, or under a wine group.
   Same face, same size, same colour, same measure — the only thing that
   changes is which slot it is dropped into. ------------------------------ */
.cap{font-family:SS4DispI;font-style:italic;font-size:var(--cap);color:var(--note);
     line-height:1.32;text-align:center;max-width:176mm;margin:0 auto;
     hyphens:none;-weasy-hyphens:none}
.cap p+p{margin-top:calc(.45*var(--base))}
.cap-top{margin-bottom:calc(.75*var(--base))}
.cap-bot{margin-top:calc(.95*var(--base))}
.cap-wine{margin-top:calc(.9*var(--base));text-align:left;max-width:none}

.essay{font-family:SS4DispI;font-style:italic;font-size:var(--essay);color:var(--note);
       line-height:1.35;text-align:center;max-width:150mm;
       margin:calc(1*var(--base)) auto calc(.8*var(--base));
       padding:calc(.5*var(--base)) 0}
.essay p+p{margin-top:calc(.6*var(--base))}

/* ---- intro pull-quote: page 1 only, above the column headers — the
   "how to enjoy Beirutina" welcome line. Bigger than the regular
   pull-quotes, sits right under the masthead instead of mid-page. */
.essay-intro{font-size:14pt;max-width:170mm;margin:0 auto calc(.8*var(--base));padding:calc(.2*var(--base)) 0}

/* wide variant: full-width two-column intro (used to introduce a page,
   e.g. the wines page), not a centred pull-quote — font-size pinned at
   10pt on purpose, decoupled from --essay, so growing the pull-quote
   size doesn't reflow the wine page. */
.essay.wide{max-width:none;column-count:2;column-gap:var(--col-gap);
            text-align:left;font-size:10pt;line-height:1.3;margin:0 0 calc(.8*var(--base));
            padding:0 0 calc(.5*var(--base));border-top:none}
.essay.wide p+p{margin-top:calc(.4*var(--base))}

/* ---- wines page: Lebanese wines above Spanish wines, full width — no
   rule between the two blocks, spacing alone separates them ------------- */
/* wines carry no hanging dietary marks, so their body doesn't need the
   7.4mm hang the food columns use — spend it on the right instead, where
   the copa/botella block was colliding with the frame. */
.framed.wines-full .col-head,.framed.wines-full .col-body{padding-left:4mm;padding-right:4mm}
.wines-full{margin-bottom:calc(.3*var(--base))}
.wines-full + .wines-full{margin-top:calc(1.6*var(--base))}

.wines-full .subgrp{margin-bottom:calc(.6*var(--base))}
.wines-full .subgrp .wrow{display:flex;flex-wrap:wrap;column-gap:var(--col-gap)}
.wines-full .subgrp .wrow .it{flex:0 0 calc(50% - var(--col-gap)/2);margin-bottom:calc(.6*var(--base))}
.wines-full .subgrp h3{column-span:all}
.essay.wide{margin-bottom:calc(.5*var(--base))}
/* foot-of-page variant of .essay.wide — same two-column 10pt setting, just
   pushed down off the framed columns above it. Fills the space short pages
   leave with text that already exists in the data. */
/* single centred block, not the two-column setting — one measured column
   sitting on the page's own centre line under the framed columns. */
.essay.wide.essay-foot{column-count:1;max-width:158mm;
        margin:calc(1.5*var(--base)) auto 0;text-align:center}

/* ---- footblock: the running element extracted into the @page bottom-left
   margin box (see @page above) — pinned to the same spot on every page,
   not content-anchored. Holds the legend (food pages only) + the always-
   on allergen/VAT line. -------------------------------------------------- */
.footblock{position:running(footblock);padding-bottom:5mm}
.foot{border-top:.6pt solid var(--rule);padding-top:1.5mm;font-family:SSans;font-size:var(--t4);
      color:var(--ink-3);display:flex;justify-content:space-between;gap:6mm;line-height:1.4}
/* right side: VAT notice (bold) with phone/Instagram stacked below it,
   both right-aligned — contact details live here now, not merged into
   the allergen line on the left. ---------------------------------------- */
.foot .vatblock{display:flex;flex-direction:column;align-items:flex-end;gap:.6mm}
.foot .vat{font-style:italic;font-weight:600;white-space:nowrap}
.foot .contact{font-style:normal;white-space:nowrap}
/* the 14-number key replaces the generic allergen disclaimer when
   theme.allergensOn — same slot, same size, just longer text, so it
   takes whatever room the disclaimer already had rather than a new
   budget of its own. flex:1 so it can wrap against the vatblock's
   width instead of the .foot row's full width. */
.foot .allergen-key{flex:1 1 auto;max-width:78%}

/* names must never break */
.it .n, .ghead h2, .sect{hyphens:none;-weasy-hyphens:none}

/* ==========================================================================
   PUBLIC VIEWER CHROME — full-viewport horizontal carousel around the menu
   pages. Reuses screen-base.css verbatim for the actual page content (.mast,
   .grp, .it, .foot, etc. — same simulated-paper design as the editor's
   preview and the real print pipeline); everything in this file is the
   surrounding chrome: the carousel stage, the vertical page rail, and the
   language toggle. Namespaced "vw-" so nothing collides with the menu's own
   classes or with editor.css's "ed-" chrome (this file replaces editor.css
   for the viewer build — see build_viewer.py).

   Same two-color-systems note as editor.css: the SIMULATED PAPER (.page)
   always renders as white paper with the menu's own ink/accent, literal in
   both themes. The CHROME around it (stage background, rail, toggle) is
   tokenized and adapts to the viewer's light/dark preference.
   ========================================================================== */

:root {
  --vw-bg: #e9e4dd;
  --vw-panel: #ffffff;
  --vw-border: #ddd5cb;
  --vw-text: #14110f;
  --vw-text-muted: #6b625c;
  --vw-rail-hover: #f4f0ea;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --vw-bg: #1b1917;
    --vw-panel: #242220;
    --vw-border: #3c362f;
    --vw-text: #f2ede6;
    --vw-text-muted: #b6aa9d;
    --vw-rail-hover: #2a2723;
  }
}
:root[data-theme="dark"] {
  --vw-bg: #1b1917;
  --vw-panel: #242220;
  --vw-border: #3c362f;
  --vw-text: #f2ede6;
  --vw-text-muted: #b6aa9d;
  --vw-rail-hover: #2a2723;
}

html, body { height: 100%; margin: 0; }
body {
  /* Vertical scroll is a deliberate escape hatch for #vw-deskbar's
     min-height:max-content case (see above) — on a very short/wide window
     the rail can end up taller than the viewport, and rather than shrink it
     we let the page scroll to it. Horizontal stays locked: the carousel's
     own swipe/pinch handling on #vw-stage owns that axis and must not
     fight a native scrollbar. */
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--vw-bg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  color: var(--vw-text);
}

#vw-app {
  display: flex;
  flex-direction: row;
  height: 100vh;
  height: 100dvh; /* see editor.css's identical note: dvh excludes mobile browser chrome, vh is the fallback */
  background: var(--vw-bg);
}

/* ---- stage: the current page, centered, filling all available space --- */
#vw-stage {
  flex: 1 1 auto;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  touch-action: none; /* our own JS owns every gesture here (swipe, pinch, pan) — pan-y
                          blocks pinch-zoom outright, so nothing short of "none" works */
}

#vw-track {
  display: flex;
  width: 100%;
  height: 100%;
  will-change: transform;
  transition: transform .38s cubic-bezier(.4, 0, .2, 1);
}
.vw-slide {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* .page itself gets sizing here; its typography comes from screen-base.css's
   own `body{...}` rule (reused verbatim), same as the editor build. */
.page {
  width: 210mm;
  height: 297mm;
  background: var(--vw-panel);
  box-shadow: 0 8px 28px rgba(0,0,0,.22);
  padding: var(--mt) var(--mr) var(--mb) var(--ml);
  display: flex;
  flex-direction: column;
  position: relative;
}
.page .page-body { flex: 1 1 auto; }
/* pinned to the very bottom of the SHEET, always. Two halves to this: the
   footer is absolute so nothing above it can push it, and .page is a FIXED
   297mm box (see below) so `bottom` really is the A4 edge — with the old
   min-height, overflowing content grew the box and the footer drifted down
   with it. Anchoring from the top instead was tried and rejected: the layout
   box then ends past 297mm and paged media emits a blank extra sheet.
   The 9mm inset is --mt, not --mb, on purpose: the gap under the last footer
   line equals the gap above the masthead, so the sheet reads symmetrically.
   Content that runs long overflows past the footer (and trips the
   .ed-overflow warning) rather than moving it. */
.page .footblock { position: absolute; left: var(--ml); right: var(--mr);
                   bottom: var(--mt); padding-bottom: 0; }

/* content ran past the physical A4 page — same safety-net flag as the
   editor build, so an overflow bug is visible here too, not silently cut. */
.page.ed-overflow { box-shadow: 0 0 0 2.5px #c0392b, 0 8px 28px rgba(0,0,0,.22); }
.page.ed-overflow::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 297mm;
  border-top: 1.5px dashed #c0392b;
}

/* ---- prev/next arrows, overlaid on the stage edges --------------------- */
.vw-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid var(--vw-border);
  background: var(--vw-panel);
  color: var(--vw-text);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,.14);
  transition: opacity .15s ease, transform .15s ease;
}
.vw-arrow:hover:not(:disabled) { transform: translateY(-50%) scale(1.06); }
.vw-arrow:disabled { opacity: .25; cursor: default; }
#vw-prev { left: 16px; }
#vw-next { right: 16px; }

/* ==========================================================================
   FLOATING NAV CHROME — one shared visual identity, two arrangements.
   Desktop: a single floating vertical bar (#vw-deskbar) docked at the right
   edge, holding the logo, page nav (icon+title), zoom control and language
   toggle, stacked top to bottom. Phone: the same controls split into two
   floating bars (#vw-topbar, #vw-bottombar) for thumb reach — top bar carries
   language+zoom, bottom bar carries icon-only page tabs. Both arrangements
   share the same rounded-corner/shadow "pill card" — .vw-floatbar — and the
   same .vw-navitem / .vw-zoomctl / .vw-langtoggle component styling, so a
   change to one visual language (radius, shadow, colors) only needs to
   happen once here. CSS media queries alone decide which arrangement is
   visible at the current width — both live in the DOM always.
   ========================================================================== */

.vw-floatbar {
  background: var(--vw-panel);
  border: 1px solid var(--vw-border);
  border-radius: 22px;
  box-shadow: 0 10px 30px rgba(0,0,0,.18), 0 2px 8px rgba(0,0,0,.10);
}

/* ---- desktop: one unified vertical bar --------------------------------- */
#vw-deskbar.vw-floatbar-vert {
  flex: 0 0 auto;
  align-self: center;
  width: 208px;
  /* Match the printed page's own on-screen height at 100% zoom (set as a
     px custom property by fitPagesToStage() on load/resize) — but never go
     below what the rail's own content (logo + 7 rows + zoom + languages)
     needs. On a very short/wide window the target can undershoot that
     minimum; min-height wins then, so the rail keeps its full, uncramped
     size and simply extends past the viewport — body scrolls to reach it. */
  height: var(--deskbar-target-h, auto);
  min-height: max-content;
  margin: 16px 16px 16px 0;
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
}
.vw-barlogo { flex: 0 0 auto; padding: 2px 6px 4px; display: flex; justify-content: center; }
.vw-barlogo svg { width: 100%; height: auto; display: block; }
/* mobile top bar: logo sits inline in a row, not stacked full-width like the
   desktop bar's own logo block above — fixed height, width follows. */
.vw-barlogo-inline { flex: 0 0 auto; padding: 0; }
.vw-barlogo-inline svg { width: auto; height: 22px; display: block; }
.vw-bardivider { flex: 0 0 auto; height: 1px; background: var(--vw-border); margin: 0 4px; }
.vw-bardivider-v { flex: 0 0 auto; align-self: stretch; width: 1px; background: var(--vw-border); margin: 0 4px; }

/* ---- page nav: icon badge + title, shared markup rendered into both the
   desktop list (label visible) and the phone bottom bar (label hidden via
   .vw-floatbar-horiz below) — see .vw-navlabel display rule further down. */
.vw-navlist { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 2px; }
.vw-navitem {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 8px;
  border-radius: 12px;
  border: none;
  background: transparent;
  color: var(--vw-text-muted);
  font: 600 12.5px/1.25 -apple-system, sans-serif;
  text-align: left;
  cursor: pointer;
}
.vw-navitem:hover { background: var(--vw-rail-hover); }
.vw-navitem.active { background: var(--vw-rail-hover); color: var(--vw-text); }
.ic-wrap {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  border: 1px solid var(--vw-border);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .12s ease, border-color .12s ease;
}
.vw-navitem.active .ic-wrap { background: var(--accent); border-color: var(--accent); }
.vw-navicon { width: 25px; height: 25px; fill: none; stroke: var(--vw-text-muted); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.vw-navitem.active .vw-navicon { stroke: #fff; }
.vw-navlabel { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- zoom control: shared by the desktop bar and the phone top bar ----- */
.vw-zoomctl { display: flex; align-items: center; justify-content: center; gap: 2px; }
.vw-zoomctl button {
  border: none;
  background: transparent;
  color: var(--vw-text);
  font: 700 14px/1 -apple-system, sans-serif;
  border-radius: 999px;
  cursor: pointer;
  padding: 9px 10px;
}
.vw-zoomctl button:hover:not(:disabled) { background: var(--vw-rail-hover); }
.vw-zoomctl button:disabled { opacity: .3; cursor: default; }
.vw-zoomctl .vw-zoompct { font: 700 11px/1 -apple-system, sans-serif; font-variant-numeric: tabular-nums; padding: 9px 8px; min-width: 3.6em; }

/* ---- language toggle: shared control, now rendered as perfect circles —
   same 30px diameter as the .ic-wrap page-icon badges, so ES/EN/AR read as
   the same family of round chips as the pictograms next to them. --------- */
.vw-langtoggle { display: flex; align-items: center; justify-content: center; gap: 4px; }
.vw-langtoggle button {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--vw-text-muted);
  font: 700 11px/1 -apple-system, sans-serif;
  letter-spacing: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.vw-langtoggle button.active { background: var(--accent); color: #fff; }
.vw-langtoggle button:disabled { opacity: .5; cursor: default; }
.vw-langtoggle button:disabled:hover { background: transparent; }

/* ---- phone: two floating bars, fixed, SAME width as each other, edge to
   edge of the screen (not auto-width centered pills) — matched radius/
   shadow to the desktop bar above ("to match iPhones"). #vw-stage reserves
   room for both via padding, set in the media query below, so the auto-fit
   page scale never sizes a page underneath either bar. --------------------- */
#vw-topbar.vw-floatbar-horiz,
#vw-bottombar.vw-floatbar-horiz {
  display: none;
  position: fixed;
  left: 14px;
  right: 14px;
  z-index: 20;
  align-items: center;
  padding: 8px 14px;
}
/* Top band: fixed height set to exactly 2x the shared .vw-floatbar radius
   (22px), so its left/right ends are true semicircles — a real capsule/pill,
   not a rounded rectangle — instead of relying on button padding to happen
   to add up close to that. Bottom band keeps the SAME radius (inherited,
   unchanged) but stays taller/auto-height for its icon+label nav rows, so
   its ends stay a gentler curve by comparison — that's intentional. */
#vw-topbar.vw-floatbar-horiz { top: 14px; justify-content: space-between; gap: 10px; height: 44px; padding: 0 14px; }
#vw-bottombar.vw-floatbar-horiz { bottom: 14px; justify-content: space-between; gap: 2px; padding: 8px 14px; }
#vw-bottombar .vw-navitem { flex: 1 1 0; min-width: 0; flex-direction: column; padding: 6px 2px; border-radius: 14px; gap: 3px; }
#vw-bottombar .vw-navlabel { display: block; font-size: 8.6px; letter-spacing: .01em; max-width: 100%; }
#vw-bottombar .ic-wrap { width: 30px; height: 30px; }

@media (max-width: 640px) {
  #vw-deskbar.vw-floatbar-vert { display: none; }
  #vw-topbar.vw-floatbar-horiz,
  #vw-bottombar.vw-floatbar-horiz { display: flex; }
  #vw-stage { padding-top: 78px; padding-bottom: 92px; }
  .vw-arrow { width: 38px; height: 38px; font-size: 19px; }
}
@media (min-width: 641px) {
  #vw-topbar.vw-floatbar-horiz,
  #vw-bottombar.vw-floatbar-horiz { display: none !important; }
}
