/* Capy design tokens. Additive: legacy tokens stay live until migration ends.
   Colors are OKLCH; source handoff hex values remain beside each token. */
:root {
  --pt-scrim: oklch(23.463% 0.021 156.521 / .38); /* modal backdrop */
  --pt-forest-900: oklch(23.968% 0.033 160.772); /* #10241A */
  --pt-forest-800: oklch(28.317% 0.044 152.997); /* #17301F */
  --pt-forest-700: oklch(32.972% 0.050 155.482); /* #1E3D2A */
  --pt-forest-600: oklch(41.245% 0.070 152.509); /* #2A5638 */
  --pt-olive-500: oklch(53.360% 0.092 140.651); /* #4E7A46 */
  --pt-moss-400: oklch(64.946% 0.077 135.930); /* #7A9A6B */
  --pt-cream-50: oklch(98.522% 0.011 89.720); /* #FDFAF2 */
  --pt-cream-100: oklch(95.903% 0.020 87.513); /* #F7F1E3 */
  --pt-cream-200: oklch(92.671% 0.028 86.647); /* #EFE6D2 */
  --pt-cream-300: oklch(87.893% 0.037 86.174); /* #E2D6BC */
  --pt-app-bg: oklch(98.774% 0.005 95.098); /* #FCFBF7 */
  --pt-gold-500: oklch(71.343% 0.123 81.556); /* #C99A3C */
  --pt-channel-delivery-border: #D9A441; /* card border of a delivery order on the Delivery y retiro board */
  --pt-channel-pickup-border: #6F9DB8; /* card border of a pickup order */
  --pt-gold-400: oklch(79.773% 0.121 85.587); /* #E0B75A */
  --pt-clay-600: oklch(51.306% 0.078 53.030); /* #8A5A3B */
  --pt-ink-900: oklch(23.463% 0.021 156.521); /* #16211A */
  --pt-success: oklch(52.601% 0.097 149.161); /* #3E7A4B */
  --pt-warning: oklch(68.122% 0.129 72.001); /* #C98A2E */
  --pt-danger: oklch(51.734% 0.137 33.521); /* #A8442F */
  --pt-info: oklch(51.696% 0.076 238.936); /* #3B6E8F */
  --pt-neutral: oklch(61.899% 0.022 154.614); /* #7C8A80 */
  --pt-text-strong: oklch(39.128% 0.029 152.560); /* #3A4A3E */
  --pt-text-secondary: oklch(45.011% 0.028 152.780); /* #4A5A4E */
  --pt-text-meta: #5F6B62; /* was #7C8A80 in the handoff; AA ≥4.5:1, approved 2026-10-10 */

  /* Badge and chip foregrounds. Darker than the semantic colours above because they sit on a
     10-14% tint of the same hue; the semantic colour itself does not reach AA there. Straight
     from the handoff's badge table, so every screen's status pills agree. */
  --pt-on-success: oklch(42.694% 0.079 150.024); /* #2B5B37 */
  --pt-on-warning: oklch(51.280% 0.101 72.028); /* #8A5C16 */
  --pt-on-danger: oklch(40.931% 0.109 33.670); /* #7A2F1F */
  --pt-on-info: oklch(43.196% 0.064 239.450); /* #2C5570 */
  --pt-on-gold: oklch(29.647% 0.053 82.399); /* #3A2A08 — text on a solid gold fill */

  /* Panel white. Distinct from cream-50: the handoff's cards are pure white on app-bg. */
  --pt-surface: oklch(100% 0 89.876); /* #FFFFFF */
  /* Muted chart fill — sparkline bars other than today. */
  --pt-chart-track: oklch(86.889% 0.032 135.014); /* #CBD9C4 */
  /* Warm-toned counterpart of --pt-chart-track for Capy Reportes' (P17) "período anterior" bars,
     which sit on the cream palette rather than the green one --pt-chart-track was picked for. */
  --pt-chart-track-warm: oklch(87.650% 0.023 89.806); /* #DCD6C6 */
  --pt-row-divider: oklch(94.248% 0.012 88.195); /* #F0EDE3 */
  --pt-available-tint: oklch(95.841% 0.021 133.109); /* #F0F5EC */
  --pt-unavailable-icon: oklch(68.854% 0.021 133.956); /* #A0A89C */
  --pt-unavailable-text: #677269; /* was #8B9A8C in the handoff; AA ≥4.5:1, approved 2026-10-10 */
  --pt-text-muted: #5A665C; /* was #6E7A70 in the handoff; AA ≥4.5:1, approved 2026-10-10 */
  --pt-toggle-off: oklch(84.803% 0.022 87.168); /* #D6D0C2 */
  --pt-danger-surface: oklch(98.722% 0.010 31.871); /* #FFF8F6 */
  --pt-danger-summary: oklch(97.478% 0.020 31.211); /* #FFF3EF */
  --pt-radio-card-border: oklch(91.184% 0.015 94.405); /* #E6E1D5 */
  --pt-radio-mark-border: oklch(81.374% 0.033 86.966); /* #CFC6AE */
  --pt-radio-selected: oklch(97.674% 0.021 134.365); /* #F5FAF2 */

  /* Capy Mesas (P15) — the prototype's STATES chip pairs that have no existing exact-hex token.
     `libre`'s fg/bg/dot already match --pt-forest-600/--pt-available-tint/--pt-success exactly
     (reused, not redeclared here); its border did not exist. `ocupada` and `cuenta` (WaitingPayment)
     needed a full new fg/tint/border triple each — `ocupada`'s dot matches --pt-gold-500 exactly
     (reused). TableStatus.Closed (ruling R2) deliberately reuses the existing neutral/cream tokens
     instead of a fifth new pair — it must never borrow one of these four. */
  --pt-available-border: oklch(88.688% 0.039 134.609); /* #CFE0C6 */
  --pt-occupied-fg: oklch(45.528% 0.093 64.421); /* #7A4A12 */
  --pt-occupied-tint: oklch(96.118% 0.026 82.386); /* #FBF1DF */
  --pt-occupied-border: oklch(86.788% 0.064 84.913); /* #E7D1A4 */
  --pt-pending-fg: oklch(48.464% 0.129 336.128); /* #8A3E7A — WaitingPayment ("cuenta") */
  --pt-pending-tint: oklch(95.920% 0.015 332.237); /* #F8EEF6 */
  --pt-pending-border: oklch(86.499% 0.042 332.149); /* #E4C9DF */
  /* "Reservada" (computed label over an Available table, never a stored status): the prototype's
     `reservada` STATES pair is not in this repo, so fg/tint/border are derived from --pt-info
     (same hue 238.9) in the pattern of the pairs above. Awaiting product-owner confirmation. */
  --pt-reserved-fg: oklch(42% 0.08 238.936);
  --pt-reserved-tint: oklch(95.5% 0.015 238.936);
  --pt-reserved-border: oklch(86% 0.04 238.936);
  --pt-tray-bg: oklch(98.173% 0.009 93.567); /* #FBF9F2 — the chip grid's own background inset */

  /* Capy Dashboard shell — nav rail, user popover, top bar and notification centre.
     Literal hex rather than the OKLCH form above: the standing instruction is to take the
     prototype's hex verbatim. The rendered colour is identical either way. */
  --pt-forest-750: #24462F;  /* active nav link fill */
  --pt-forest-850: #1B3527;  /* user popover surface */
  --pt-sage-300: #A9BBA6;    /* idle nav link */
  --pt-sage-200: #DCE7DA;    /* popover item text */
  --pt-sage-100: #E8EFE6;    /* user name */
  --pt-moss-500: #6E8570;    /* brand sub-line, user role */
  --pt-moss-600: #55684F;    /* nav group label */
  --pt-moss-300: #8FA58C;    /* nav group label; 6.2:1 on the rail, approved 2026-10-10 */
  --pt-clay-300: #E6A594;    /* log out item */
  --pt-sage-400: #9FB89F;    /* popover, switcher and shop-button icons */
  /* The rail's own hairlines and fills. The prototype writes these as rgba over the forest
     surface rather than as flat hexes, and they stay rgba here for the same reason it does:
     the rail's popover and its accordion sit on two different greens. */
  --pt-nav-line: rgba(185,199,182,.16);      /* popover border, switcher rule */
  --pt-nav-line-soft: rgba(185,199,182,.14); /* user block divider */
  --pt-nav-fill: rgba(232,239,230,.10);      /* user and shop buttons, open or hovered */
  --pt-nav-fill-soft: rgba(232,239,230,.09); /* popover and switcher item hover */
  --pt-nav-fill-out: rgba(168,68,47,.16);    /* log out hover */
  /* Pressed. The design system gives every pressable surface a "bajada" on press, and for a
     flat row that is a deeper fill rather than a shadow it does not have. */
  --pt-nav-fill-press: rgba(232,239,230,.16);
  --pt-nav-fill-out-press: rgba(168,68,47,.26);
  --pt-nav-mark: #7FBF8C;                    /* check on the current restaurant */
  /* Hairline and faint text, general purpose. --pt-radio-card-border and
     --pt-unavailable-icon carry the same two values under names that only describe one call
     site each; those keep their existing usages and are not retuned here. */
  --pt-line-200: #E6E1D5;
  --pt-line-100: #F5F2E9;
  --pt-row-hover: #F7F5EE;
  --pt-text-faint: #6B766D; /* was #A0A89C in the handoff; AA ≥4.5:1, approved 2026-10-10 */
  --pt-radius-popover: 13px;
  --pt-radius-chip: 7px;
  --pt-shadow-popover: 0 18px 44px rgba(22,33,26,.16), 0 2px 6px rgba(22,33,26,.06);
  --pt-shadow-navpopover: 0 20px 44px rgba(6,14,10,.44);
  --pt-dur-quick: 140ms;     /* bell border and fill */
  --pt-dur-glide: 420ms;     /* tabs, popover items, hover states */
  --pt-dur-slide: 520ms;     /* nav link transform */
  /* The frontend's ease-out. Merged 2026-08-31: --pt-ease-key used to sit in the motion block
     below with a second control point above 1, which made everything using it overshoot its
     destination and settle back — subtle on the QR card's entrance, a visible wobble on
     Onboarding's two hard-shadow buttons when a hover ended. Once that bounce came out the two
     curves were perceptually the same, so they became one and Onboarding's three call sites moved
     here. The surviving VALUE is this one, unchanged: it comes from the Capy Dashboard prototype
     and CapyShellTokenTests pins it there, so replacing it would be a fidelity deviation needing
     approval in advance — and it buys nothing, since neither curve overshoots. */
  --pt-ease-glide: cubic-bezier(.23,1,.32,1);
  --pt-ease-enter: cubic-bezier(.2,0,0,1);

  /* ── Shell chrome ────────────────────────────────────────────────────────────────────────
     The top bar, its bell and the notification centre ride above whatever screen is mounted.
     They are siblings of the content in MainLayout, not children of it, so a screen that
     paints its own surface cannot restyle them from its own stylesheet. These tokens are the
     seam: the chrome reads them, and a screen re-declares them on its own branch of the tree
     (see the kitchen block in app.css). Everything below is the light default — the Capy
     Dashboard prototype's own values, unchanged from what the chrome hardcoded before. */
  --pt-chrome-bar: var(--pt-surface);          /* the top bar band itself */
  --pt-chrome-surface: var(--pt-surface);      /* bell fill, panel body, rows */
  --pt-chrome-inset: var(--pt-app-bg);         /* panel tab strip and footer band */
  --pt-chrome-line: var(--pt-line-200);        /* bar border, bell border, tab border */
  --pt-chrome-divider: var(--pt-row-divider);  /* panel head/tabs/foot rules */
  --pt-chrome-hairline: var(--pt-line-100);    /* between rows */
  --pt-chrome-hover: var(--pt-app-bg);         /* bell hover, row hover */
  --pt-chrome-inset-hover: var(--pt-line-100); /* footer hover, on the inset band */
  --pt-chrome-title: var(--pt-ink-900);
  --pt-chrome-strong: var(--pt-text-strong);
  --pt-chrome-text: var(--pt-text-muted);
  --pt-chrome-faint: var(--pt-text-faint);
  --pt-chrome-icon: var(--pt-text-secondary);  /* the bell glyph */
  --pt-chrome-accent: var(--pt-forest-700);    /* selected tab fill, open bell border */
  --pt-chrome-accent-fg: var(--pt-cream-50);
  --pt-chrome-shadow: var(--pt-shadow-popover);
  --pt-chrome-link: var(--pt-success);         /* "marcar todo como leído" */
  --pt-chrome-dot: var(--pt-success);          /* unread dot */
  --pt-chrome-unread: oklch(from var(--pt-success) l c h / .045);
  /* Tone pairs for the row icon, its action button and the header count. Foreground and tint
     both flip: a 10% tint of --pt-danger is invisible on a dark board, and #A8442F text on it
     is unreadable. */
  --pt-chrome-danger: var(--pt-danger);
  --pt-chrome-danger-tint: oklch(from var(--pt-danger) l c h / .10);
  --pt-chrome-warn: var(--pt-on-warning);
  --pt-chrome-warn-tint: oklch(from var(--pt-gold-500) l c h / .14);
  --pt-chrome-info: var(--pt-on-info);
  --pt-chrome-info-tint: oklch(from var(--pt-info) l c h / .10);

  --pt-space-1: 4px; --pt-space-2: 8px; --pt-space-3: 12px;
  --pt-space-4: 16px; --pt-space-5: 20px; --pt-space-6: 24px; --pt-space-8: 32px; --pt-space-12: 48px;
  --pt-topbar-height: 57px; /* shell top bar band: TopBar, ErrorLayout, and the sticky Configuración header below it */
  --pt-menu-section-min-height: 46px;
  --pt-action-min-height: 38px;
  --pt-action-min-height-touch: 44px;
  --pt-radius-pixel: 0; --pt-radius-sm: 4px; --pt-radius-md: 8px;
  --pt-radius-lg: 12px; --pt-radius-pill: 999px;
  /* Shadow colour is ink-900 (#16211A), the rgba(22,33,26) the handoff specifies. */
  --pt-shadow-card: 0 1px 2px oklch(23.463% 0.021 156.521 / .05),
                    0 3px 10px oklch(23.463% 0.021 156.521 / .05);
  --pt-shadow-panel: 0 8px 40px oklch(23.463% 0.021 156.521 / .16),
                     0 2px 8px oklch(23.463% 0.021 156.521 / .08);
  --pt-border-card: 1px solid var(--pt-cream-300);
  --pt-border-row: 1px solid var(--pt-row-divider);
  /* Two-tone focus ring (light gap + solid forest); was forest at 24% (~1.6:1). Approved 2026-10-10. */
  --pt-focus-ring: 0 0 0 2px var(--pt-surface), 0 0 0 4px var(--pt-forest-600);
  --pt-focus-outline: 2px solid var(--pt-forest-600); /* use with outline-offset: 2px */
  /* Selection highlight (not focus): the former focus-ring value. */
  --pt-selected-halo: 0 0 0 3px oklch(from var(--pt-forest-600) l c h / .24);
  --pt-lift-hover: translateY(-2px);
  --pt-font-display: 'Outfit', system-ui, sans-serif;
  --pt-font-body: 'Nunito', system-ui, sans-serif;
  --pt-font-mono: 'Silkscreen', monospace;
  --pt-text-display-xl: 54px; --pt-leading-display-xl: 1.02; --pt-tracking-display-xl: -.03em;
  --pt-text-display-l: 38px; --pt-leading-display-l: 1.08; --pt-tracking-display-l: -.025em;
  --pt-text-title: 24px; --pt-leading-title: 1.2; --pt-tracking-title: -.015em;
  --pt-text-subtitle: 18px; --pt-leading-subtitle: 1.35;
  --pt-text-body: 15px; --pt-leading-body: 1.6;
  --pt-text-caption: 13px; --pt-leading-caption: 1.5;
  --pt-dur-press: 110ms; --pt-dur-base: 220ms; --pt-dur-hover: 300ms;
  --pt-dur-color: 320ms; --pt-dur-return: 440ms; --pt-dur-swap: 620ms;
  --pt-ease-soft: cubic-bezier(.22,.68,.24,1);
  --pt-ease-press: cubic-bezier(.3,0,.7,1);
  --pt-ease-slow: cubic-bezier(.33,.02,.23,1);

  /* Language-swap skeleton. Declared here rather than inside either consumer because two surfaces
     paint it and they live in different stylesheets on different grounds: the screen being
     translated (Settings.razor.css) and the nav rail above it (app.css). The ramp is the landing's
     own .capy-langload recipe with its rgba() literals resolved against real tokens;
     --pt-shimmer-inverse is the same ramp inverted for the forest fills — the rail, the active nav
     item, the primary button — where a dark shimmer is invisible. The keyframes it names live in
     app.css, since @keyframes are global whatever file declares them. */
  --pt-shimmer: linear-gradient(90deg,
      oklch(from var(--pt-text-meta) l c h / .10) 20%,
      oklch(from var(--pt-text-meta) l c h / .26) 40%,
      oklch(from var(--pt-text-meta) l c h / .10) 60%);
  --pt-shimmer-inverse: linear-gradient(90deg,
      oklch(from var(--pt-cream-50) l c h / .16) 20%,
      oklch(from var(--pt-cream-50) l c h / .38) 40%,
      oklch(from var(--pt-cream-50) l c h / .16) 60%);
  --pt-shimmer-animation: capy-shimmer 1.15s linear infinite;
}

/* Reduced motion. This block used to zero every duration token, which made every transition in
   the dashboard instant — a colour fade included. That is not what the prototypes do: both
   Capy Dashboard.dc.html and Capy Design System.dc.html implement the setting as
   `* { animation: none !important; }`, killing keyframes and leaving transitions alone, and the
   Design System states the rule as "prefers-reduced-motion apaga todo lo no esencial". A
   background or colour fade is not motion; a transform is.

   So the policy is: suppress animations and transforms, keep colour. There is deliberately no
   blanket `* { transform: none }` here — plenty of layout depends on transform for centring,
   and neutralising it globally would move things rather than stop them moving. Each surface
   that transitions a transform suppresses its own, next to the rule that declares it. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --pt-lift-hover: none;
    /* The bars stay — they are the message, and a static tint is still a skeleton. Only the
       travel stops, which is this file's own rule: suppress movement, keep colour. */
    --pt-shimmer-animation: none;
  }
}

/* ── Responsive breakpoint ladder ──────────────────────────────────────────────
   Declared here so screens reference one ladder instead of inventing widths. It
   cannot be tokenised: custom properties are not allowed in media query conditions.

     >= 1181px   full desktop, two-column master/detail, permanent 232px rail
     <= 1180px   single column, and navigation becomes a dismissible drawer
     <=  820px   tighter content padding
     <=  700px   phone content: rows recompose, KPI strips collapse
     <=  600px   dense rows stack

   200% browser zoom needs no rule of its own: on 1440x900 it yields 720x450 CSS
   pixels, which already lands inside this ladder.

   Touch sizing is a SEPARATE axis and never keys on width:
     @media (hover: none) and (pointer: coarse)
   Widening a control by viewport width would fatten every control at 200% zoom on
   a mouse desktop, which is exactly where density matters most. */
