/* ==========================================================================
   tokens.css — SOURCE. Brand tokens for Board & Bean (sandwich, coffee
   & snack counter). Palette grounded in the shop's own materials: kraft
   counter paper, chalkboard order-boards, mustard, and order-ticket mono
   type. Do NOT touch the two alias blocks below — they're what make
   base.css and components.css work without edits.
   ========================================================================== */

:root {
  /* ============ BRAND TOKENS — Board & Bean ============ */
  --ink:          #2b241d;   /* roasted-coffee brown-black body text */
  --paper:        #f4eee0;   /* unbleached kraft counter paper */
  --paper-alt:    #e9dcbf;   /* deeper kraft, alt sections */
  --board:        #1f1a15;   /* chalkboard dark, used for --ink on dark sections */
  --accent-raw:       #c1830f; /* mustard */
  --accent-raw-hover: #a06d0a;
  --pickle:       #55632f;   /* fresh/veg green, used sparingly for tags */
  --muted:        #756a58;
  --border-raw:   #d8c79b;

  --font-display: 'Anton', 'Arial Narrow', sans-serif;      /* deli-signage stencil */
  --font-body:    'Karla', system-ui, sans-serif;            /* warm, humanist */
  --font-mono:    'IBM Plex Mono', 'Courier New', monospace; /* order-ticket prices */

  --radius:       0.3rem;
  --radius-lg:    0.4rem;

  /* ============ STRUCTURAL TOKENS — reusable as-is ============
     --container-pad has a clamp() floor so it doesn't collapse on
     narrow viewports; --nav-height feeds scroll-padding-top so anchor
     jumps don't land under the sticky header. */
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.5rem;
  --space-6:  2rem;
  --space-7:  3rem;
  --space-8:  4rem;

  --container-max:   72rem;
  --container-pad:   clamp(1.5rem, 6vw, 5rem);
  --nav-height:       4.5rem;

  /* ============ REQUIRED ALIAS — base.css focus-ring depends on this ============
     Every token file MUST define --accent, or focus rings silently
     fall back to the browser default instead of the brand colour. */
  --accent:        var(--accent-raw);
  --accent-hover:  var(--accent-raw-hover);

  /* ============ GENERIC ALIAS LAYER — kept for kit consistency ============
     No admin/calendar pages ship with this build (no booking system),
     but the alias block is kept so this tokens.css stays drop-in
     compatible with admin.html / calendar-help.html if a booking
     widget is ever added later. Keep every name on the left; only the
     values change per client. */
  --color-accent:        var(--accent);
  --color-accent-hover:  var(--accent-hover);
  --color-bg:            var(--paper);
  --color-bg-alt:        var(--paper-alt);
  --color-text:          var(--ink);
  --color-text-muted:    var(--muted);
  --color-border:        var(--border-raw);
  --color-white:         #ffffff;
  --color-error:         #b3261e;
  --color-success:       #15803d;

  --space-1-alt: var(--space-1);
  --text-sm:     0.875rem;
}
/* ==========================================================================
   base.css — SOURCE. Reset + element defaults. Reusable as-is across
   every project — don't edit per client.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Fix: sticky/fixed nav needs scroll-padding-top equal to its height,
     set once globally, or every anchor jump (native fragment nav,
     scrollIntoView, tab links) lands its target underneath the nav. */
  scroll-padding-top: var(--nav-height);
}

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--paper);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.15;
  font-weight: 600;
}

img, picture, svg, video { display: block; max-width: 100%; }

/* Opt-in, not opt-out: lists default to no markers because most lists
   in a landing page are nav/primitive lists, not real numbered/bulleted
   content. Pages with genuine step lists must opt back in explicitly
   per list (e.g. `ol.help-steps { list-style: decimal; }`) — otherwise
   the numbers silently vanish while the text still reads fine, which
   is easy to miss in review. */
ul, ol { list-style: none; padding: 0; }

a { color: inherit; text-decoration: none; }

button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }

/* Fix: some shared layout classes (e.g. .stack, .cluster) set
   display:flex on their own children — that silently beats the
   browser's own [hidden] { display:none } default on any element that
   also carries one of those classes. This override makes [hidden]
   actually win regardless of what else is applied alongside it. */
[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* No skip-to-content link by default — these are simple one-pagers.
   Add one explicitly only if a specific project asks for it. */
/* ==========================================================================
   layout.css — SOURCE. Generic layout primitives. Reusable as-is,
   rarely needs edits. Before writing fresh flex/grid for a new section,
   check this file first.

   Canonical breakpoints, used everywhere in this file and components.css:
     max-width: 640px   mobile
     max-width: 960px   tablet & down
     min-width: 961px   desktop & up
   ========================================================================== */

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  /* Fix: --container-pad has a clamp() floor in tokens.css so this
     never collapses to near-zero on narrow viewports. */
  padding-inline: var(--container-pad);
}

.section          { padding-block: var(--space-8); }
.section--alt     { background: var(--paper-alt); }
.section--dark    { background: var(--ink); color: var(--paper); }

.stack            { display: flex; flex-direction: column; }
.stack > * + *     { margin-top: var(--space-4); }
.stack--tight > * + * { margin-top: var(--space-2); }
.stack--loose > * + * { margin-top: var(--space-7); }
/* Fix: margin-top does nothing to inline elements. A footer link list
   built from bare <a> tags inside .stack collapses onto one line
   without this — markup is correct, display:inline just ignores
   margin-top. */
.stack > a        { display: block; }

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-7);
  align-items: center;
}
@media (max-width: 960px) {
  .split { grid-template-columns: 1fr; }
}

.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space-6);
}

.grid-fixed-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
}
@media (max-width: 960px) {
  .grid-fixed-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .grid-fixed-3 { grid-template-columns: 1fr; }
}
/* ==========================================================================
   components.css — Nav/button/card/form/tab mechanics carried over
   unmodified from the kit (they're reusable as-is). Colours, radius,
   and the signature elements below are specific to Board & Bean.
   ========================================================================== */

/* base.css sets h1–h4 to font-weight:600 for every kit build - correct
   for a font like Fraunces that ships that weight, but Anton (this
   build's display face) only has 400. Requesting 600 here would
   force the same faux-bold blur as the buttons had. Reset it here
   rather than editing the shared base.css. */
h1, h2, h3, h4 { font-weight: 400; }

/* ---------- Nav ----------
   Fix: .nav__bar and .nav__panel are BOTH children of .nav__inner, a
   single shared flex row — not siblings of it. */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--border-raw);
}
.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--nav-height);
  position: relative; /* .nav__panel anchors to this */
}
.nav__logo {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.35rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.nav__logo span { color: var(--accent); }
.nav__bar {
  display: none;
  gap: var(--space-6);
  font-weight: 600;
  font-size: 0.95rem;
}
.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: var(--space-2);
  color: var(--ink);
}
.nav__toggle svg { width: 1.5rem; height: 1.5rem; }
.nav__panel {
  display: none;
  flex-direction: column;
  gap: var(--space-1);
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--paper);
  border-bottom: 1px solid var(--border-raw);
  padding: var(--space-4) 0;
}
.nav__panel.is-open { display: flex; }
/* Fix: scoping plain nav links to :not(.btn) keeps the CTA button
   looking like a button regardless of load order/specificity. */
.nav__panel a:not(.btn) {
  padding: var(--space-2) var(--container-pad);
  font-weight: 500;
}
.nav__panel .btn { margin-inline: var(--container-pad); }

@media (min-width: 961px) {
  .nav__bar { display: flex; align-items: center; }
  .nav__toggle { display: none; }
  .nav__panel { display: none !important; }
}

/* ---------- Buttons ----------
   Fix: inline-flex without justify-content:center pins a full-width
   button's label to the left in a flex column — centering is baked
   into the default, not re-added per variant. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius);
  /* Fix: Anton only ships a single (400) weight. Requesting 700 here
     has no real weight to draw from, so the browser faux-bolds by
     stretching the glyph outlines - that's what reads as blurry.
     Anton is already heavy/condensed by design; 400 is correct. */
  font-weight: 400;
  font-family: var(--font-display);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 0.9rem;
  border: 1.5px solid transparent;
  text-align: center;
}
.btn--primary {
  background: var(--accent);
  color: var(--color-white);
}
.btn--primary:hover { background: var(--accent-hover); }
.btn--outline {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}
.btn--outline:hover { background: var(--ink); color: var(--paper); }
.btn--block { width: 100%; }

/* ---------- Cards ----------
   Fix: a single box-shadow gives the card's offset "behind" effect —
   not a second independently-curved shape, which drifts out of sync
   with the card's own corners and leaks a hairline of background
   colour through anti-aliasing at the seam. */
.card {
  background: var(--color-white);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: 0.35rem 0.35rem 0 var(--accent);
}

/* ---------- Forms ----------
   Fix: inputs/textareas in a flex or grid layout size to their own
   intrinsic width by default — width:100% plus min-width:0 (guards
   overflow in a tight grid track) is required on every field. */
.field { margin-bottom: var(--space-4); }
.field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: var(--space-2);
}
.field input,
.field textarea,
.field select {
  width: 100%;
  min-width: 0;
  padding: var(--space-3);
  border: 1.5px solid var(--border-raw);
  border-radius: var(--radius);
  background: var(--color-white);
}
.field input:focus,
.field textarea:focus { outline: none; border-color: var(--accent); }
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
@media (max-width: 640px) {
  .field-row { grid-template-columns: 1fr; }
}

/* ---------- Tabs ----------
   Fix (progressive enhancement): panels are visible (stacked) by
   default; only .js — added inline in <head> before anything else
   runs — gates the collapse to a tab view. Used here for the menu
   board (Sandwiches / Coffee / Snacks). */
.tabs__list { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-6); }
.tabs__tab {
  padding: var(--space-2) var(--space-5);
  border-radius: 999px;
  border: 1.5px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-weight: 400;
  font-size: 0.9rem;
}
.tabs__tab[aria-selected="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
.tab-panel + .tab-panel { margin-top: var(--space-6); }
.js .tab-panel:not(.is-active) { display: none; }

/* ---------- Scroll reveal ----------
   Fix: the hidden starting state is added by reveal.js itself, never
   unconditionally in CSS — a failed script can never permanently
   hide content. */
.reveal-pending { opacity: 0; transform: translateY(1rem); }
.reveal-pending.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s ease, transform 0.5s ease;
}

/* ==========================================================================
   SIGNATURE ELEMENT — the torn ticket edge.
   A zig-zag clip-path standing in for a sheet torn off an order pad.
   Used exactly twice: once under the hero photo, once on top of the
   menu board — the two places on the page that most read as "counter
   paper". Left everywhere else alone on purpose.
   ========================================================================== */
.torn-edge {
  position: relative;
  clip-path: polygon(
    0% 0%, 100% 0%, 100% 96%,
    96% 100%, 92% 96%, 88% 100%, 84% 96%, 80% 100%,
    76% 96%, 72% 100%, 68% 96%, 64% 100%, 60% 96%,
    56% 100%, 52% 96%, 48% 100%, 44% 96%, 40% 100%,
    36% 96%, 32% 100%, 28% 96%, 24% 100%, 20% 96%,
    16% 100%, 12% 96%, 8% 100%, 4% 96%, 0% 100%
  );
}
/* Same tear, flipped to the top edge — used once, on the menu board,
   as if the board were the ticket just torn off the pad. */
.torn-edge--top {
  position: relative;
  clip-path: polygon(
    0% 4%, 4% 0%, 8% 4%, 12% 0%, 16% 4%,
    20% 0%, 24% 4%, 28% 0%, 32% 4%, 36% 0%,
    40% 4%, 44% 0%, 48% 4%, 52% 0%, 56% 4%,
    60% 0%, 64% 4%, 68% 0%, 72% 4%, 76% 0%,
    80% 4%, 84% 0%, 88% 4%, 92% 0%, 96% 4%, 100% 0%,
    100% 100%, 0% 100%
  );
}

.menu-board .tabs__tab { border-color: var(--paper); color: var(--paper); }
.menu-board .tabs__tab[aria-selected="true"] { background: var(--accent); border-color: var(--accent); color: var(--board); }

/* ---------- Menu board ----------
   Structural risk: the menu isn't a grid of cards, it's an order-
   ticket-style price list — dotted leaders running from item name to
   price, prices set in mono type like a receipt. */
.menu-board {
  background: var(--board);
  color: var(--paper);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6) var(--space-6);
}
.menu-list { list-style: none; padding: 0; }
.menu-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  border-bottom: 1px dashed rgba(244, 238, 224, 0.2);
}
.menu-item:last-child { border-bottom: none; }
.menu-item__name { font-weight: 700; white-space: nowrap; }
.menu-item__desc {
  color: rgba(244, 238, 224, 0.6);
  font-size: 0.85rem;
  margin-left: var(--space-2);
}
.menu-item__leader {
  flex: 1;
  border-bottom: 1px dotted rgba(244, 238, 224, 0.35);
  transform: translateY(-0.3rem);
  min-width: 1rem;
}
.menu-item__price {
  font-family: var(--font-mono);
  font-weight: 500;
  white-space: nowrap;
}

/* ---------- Tags ----------
   Small stamp-like labels for dietary/fresh call-outs — used sparingly. */
.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pickle);
  border: 1px solid var(--pickle);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  margin-left: var(--space-2);
}
/* The menu board is dark (chalkboard); the plain --pickle green
   doesn't clear contrast against it, so tags brighten inside it. */
.menu-board .tag { color: #9dbf74; border-color: #9dbf74; }

/* ---------- Map embed ----------
   Plain framed rectangle, matching the border/radius treatment used
   on photos elsewhere - the torn-ticket signature stays reserved for
   the hero and menu board, not repeated here. */
.map-embed {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1.5px solid var(--border-raw);
  aspect-ratio: 4 / 3;
}
.map-embed iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------- Social links ----------
   Generic, non-trademarked glyphs (not the brand logos themselves) —
   a circle outline holding a simple pictogram, in the site's own ink
   colour rather than each platform's brand colour. */
.social-links { display: flex; gap: var(--space-3); }
.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 999px;
  border: 1.5px solid var(--ink);
  color: var(--ink);
}
.social-link:hover { background: var(--ink); color: var(--paper); }
.social-link svg { width: 1.2rem; height: 1.2rem; }
.section--dark .social-link { border-color: var(--paper); color: var(--paper); }
.section--dark .social-link:hover { background: var(--paper); color: var(--ink); }
