/* VieBudget app layer on the VESS v2.3 tokens (vess_v2_3_tokens.css). Colours come from
 * --vno-* variables only; nothing here introduces a hex. */

:root {
  /* Text colours that pass WCAG AA (4.5:1, bible §15) on paper and on the light plates
     (bg, green/red/gold/teal soft). The VESS mute / soft / green-deep / red / teal-deep
     measure 2.5-4.2:1 on these backgrounds, so small text uses these mixes of VESS tokens
     instead (no new hex). The VESS colours stay for borders, dots, rules and pills. */
  --vb-text-secondary: color-mix(in srgb, var(--vno-soft) 60%, var(--vno-slate));       /* >= 4.7:1 */
  --vb-text-positive:  color-mix(in srgb, var(--vno-green-deep) 50%, var(--vno-ink));   /* >= 5.0:1 */
  --vb-text-negative:  color-mix(in srgb, var(--vno-red) 75%, var(--vno-ink));          /* >= 4.9:1 */
  --vb-text-link:      var(--vno-navy-soft);                                             /* >= 4.9:1 */
  /* Navy has two jobs: a fill (buttons, the department band) and a text / line colour.
     The dark theme keeps the fills and lightens the text, so the two are separate tokens. */
  --vb-navy-text:      var(--vno-navy);
  --vb-navy-dark-text: var(--vno-navy-deep);
  --vb-navy-line:      var(--vno-navy);
  --vb-on-fill:        white;   /* text on a navy / red fill, in both themes */
}

/* Dark theme (header switch, ui.js): the same VESS tokens re-pointed to the bible's dark
   panels — navy-ink surfaces, dark-text ink, sky for navy text; soft plates are the
   status colour over navy-ink. Every Tailwind utility follows, since they map to tokens. */
html[data-theme="dark"] {
  color-scheme: dark;   /* native selects, scrollbars and date pickers */
  --vno-bg:         color-mix(in srgb, var(--vno-navy-ink) 70%, black);
  --vno-paper:      color-mix(in srgb, var(--vno-navy-ink) 80%, var(--vno-navy-deep));
  --paper-cool:     color-mix(in srgb, var(--vno-navy-ink) 40%, var(--vno-navy-deep));
  --vno-line:       color-mix(in srgb, var(--vno-navy) 55%, var(--vno-navy-ink));
  --vno-line-soft:  color-mix(in srgb, var(--vno-navy) 35%, var(--vno-navy-ink));
  --vno-ink:        var(--vno-dark-text);
  --vno-slate:      color-mix(in srgb, var(--vno-dark-text) 75%, var(--vno-dark-mute));
  --vno-soft:       var(--vno-dark-mute);
  --vno-teal-soft:  color-mix(in srgb, var(--vno-teal) 22%, var(--vno-navy-ink));
  --vno-gold-soft:  color-mix(in srgb, var(--vno-gold) 20%, var(--vno-navy-ink));
  --vno-green-soft: color-mix(in srgb, var(--vno-green) 20%, var(--vno-navy-ink));
  --vno-red-soft:   color-mix(in srgb, var(--vno-red) 25%, var(--vno-navy-ink));
  --vb-text-negative:  color-mix(in srgb, var(--vno-red) 55%, var(--vno-ink));
  --vb-text-link:      var(--vno-sky-deep);
  --vb-navy-text:      var(--vno-sky);
  --vb-navy-dark-text: var(--vno-sky);
  --vb-navy-line:      var(--vno-sky-deep);
}
/* Tailwind's bg-white is not a token (bg-white/10 needs the plain colour). */
html[data-theme="dark"] .bg-white { background-color: var(--vno-paper); }
html[data-theme="dark"] :is(a, button).bg-white:hover { background-color: var(--paper-cool); }
:where(html[data-theme="dark"]) :where(input, select, textarea) {   /* utilities still win */ background-color: var(--vno-paper); }
html[data-theme="dark"] .app-footer img { filter: brightness(0) invert(0.85); }

body { font-family: var(--font-sans); color: var(--vno-ink); background: var(--vno-bg); }

/* Bible §15: visible focus ring on every interactive element. */
:focus-visible { outline: 2px solid var(--vno-teal); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* Page chrome: eyebrow / title / accent rule (bible §7). */
.page-eyebrow { font: 600 var(--type-eyebrow)/1 var(--font-sans); color: var(--vb-text-secondary);
                letter-spacing: 0.16em; text-transform: uppercase; }
.page-title   { font: 700 24px/1.2 var(--font-sans); color: var(--vno-ink);
                letter-spacing: -0.01em; margin-top: var(--sp-2); }
.page-accent  { display: block; width: 32px; height: 2px; border: 0;
                background: var(--vno-green); margin: var(--sp-3) 0 var(--sp-4); }
.section-label { font: 600 var(--type-eyebrow)/1 var(--font-sans); color: var(--vb-text-secondary);
                 letter-spacing: 0.16em; text-transform: uppercase; }

/* Status pills: label + colour, never colour alone (bible §10, §15). */
.pill { display: inline-block; border-radius: var(--r-pill); padding: 2px 8px;
        font: 600 11px/1.4 var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase;
        vertical-align: middle; }
.pill-info      { background: var(--vno-teal-soft);  color: var(--vb-navy-text); }
.pill-watch     { background: var(--vno-gold-soft);  color: var(--vno-ink); }
.pill-locked    { background: var(--vno-navy-deep);  color: var(--vb-on-fill); }
.pill-positive  { background: var(--vno-green-soft); color: var(--vno-ink); }

/* Auto-save state on grid inputs: gold = saving, green = saved, red = failed. The
   save-status bar (ui.js) says the same in words, so the state is not colour-only. */
.cell-saving { border-color: var(--vno-gold) !important; }
.cell-saved  { border-color: var(--vno-green-deep) !important; }
.cell-error  { border-color: var(--vno-red) !important; background: var(--vno-red-soft) !important; }

/* Save-status bar: pinned bottom right, shown from the first save of the page on. */
.save-status { position: fixed; right: 16px; bottom: 16px; z-index: 50; max-width: calc(100vw - 32px);
               display: flex; align-items: center; gap: var(--sp-3); padding: 8px 14px;
               border-radius: var(--r-2); box-shadow: var(--shadow-card); border: 1px solid var(--vno-line);
               background: var(--vno-paper); color: var(--vno-ink); font: 600 13px/1.4 var(--font-sans); }
.save-status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; flex: none; }
.save-status[data-state="saving"]::before { background: var(--vno-gold); }
.save-status[data-state="saved"]::before  { background: var(--vno-green-deep); }
.save-status[data-state="error"] { background: var(--vno-red-soft); border-color: var(--vno-red); }
.save-status[data-state="error"]::before  { background: var(--vno-red); }
.save-status-why { font-weight: 400; color: var(--vno-slate); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.save-status button { flex: none; border: 1px solid var(--vb-navy-line); color: var(--vb-navy-text); background: var(--vno-paper);
                      border-radius: var(--r-1); padding: 2px 10px; font-weight: 600; }
.save-status button:disabled { opacity: 0.5; }

/* In-page dialogs (ui.js): confirmations and required comments. */
.vb-dialog { width: min(480px, calc(100vw - 32px)); border: 0; border-radius: var(--r-3); padding: 0;
             box-shadow: var(--shadow-lift); color: var(--vno-ink); background: var(--vno-paper); }
.vb-dialog::backdrop { background: rgba(0, 42, 58, 0.35); }
.vb-dialog form { padding: 20px 24px; display: flex; flex-direction: column; gap: 12px; font-size: 14px; }
.vb-dialog h2 { font: 700 17px/1.3 var(--font-sans); color: var(--vb-navy-text); }
.vb-dialog dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0;
                padding: 8px 12px; background: var(--vno-bg); border-radius: var(--r-2); }
.vb-dialog dt { color: var(--vb-text-secondary); }
.vb-dialog dd { margin: 0; font-weight: 600; }
.vb-dialog p { color: var(--vno-slate); line-height: 1.5; }
.vb-dialog label { display: flex; flex-direction: column; gap: 4px; font-weight: 600; }
.vb-dialog textarea { border: 1px solid var(--vno-line); border-radius: var(--r-1); padding: 6px 8px;
                      font: 400 14px/1.4 var(--font-sans); resize: vertical; }
.vb-dialog .vb-dialog-error { color: var(--vb-text-negative); font-size: 13px; }
.vb-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
.vb-dialog-actions button { border-radius: var(--r-1); padding: 6px 14px; font-weight: 600; }
.vb-btn-primary   { background: var(--vno-navy); color: var(--vb-on-fill); }
.vb-btn-danger    { background: color-mix(in srgb, var(--vno-red) 75%, var(--vno-navy-ink)); color: var(--vb-on-fill); }
.vb-btn-secondary { border: 1px solid var(--vb-navy-line); color: var(--vb-navy-text); background: var(--vno-paper); }

/* Page shell: one centred column that follows the screen — full width up to a 24"
   monitor, with a gutter that shrinks on a phone. Wide grids scroll inside their card,
   never the whole page. */
.page { width: 100%; max-width: 2560px; margin-inline: auto;
        padding: var(--sp-6) clamp(16px, 2.5vw, 40px) var(--sp-10); }
.page-bar { width: 100%; max-width: 2560px; margin-inline: auto;
            padding-inline: clamp(16px, 2.5vw, 40px); }

/* Table card: a white surface for every table. A small table scrolls sideways inside its
   card on a phone. A month grid (.sheet) works like a spreadsheet in ONE window: it never
   clips, the page itself scrolls both ways (the browser's scrollbar stays at the bottom of
   the screen), the header row sticks under the top bar and the label column to the left. */
.table-card { background: var(--vno-paper); border: 1px solid var(--vno-line);
              border-radius: var(--r-2); box-shadow: var(--shadow-card);
              overflow: auto; max-width: 100%; }
.table-card > table { margin-bottom: 0; }
.table-card.fit { width: fit-content; }
.table-card.sheet { overflow: visible; width: max-content; min-width: 100%; max-width: none; }
.table-card thead th { position: sticky; top: 0; z-index: 2; background: var(--vno-paper);
                       box-shadow: inset 0 -1px 0 var(--vno-line);
                       padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
.table-card thead th.col-pin-left, .table-card thead th.col-pin-right { z-index: 3; }
/* a sheet scrolls with the page: its header stops just under the pinned top bar (a small
   card scrolls on its own, so its header sticks to the card top) */
.table-card.sheet thead th { top: var(--sticky-top, 0px); }
.table-card tbody tr:hover > td:not(.bg-slate-100) { background-color: var(--paper-cool); }
.table-card td:first-child, .table-card th:first-child { padding-left: var(--sp-3); }

/* Pinned grid columns (label left, FY total right) sit on the card surface. */
.col-pin-left  { position: sticky; left: 0;  z-index: 1; background: var(--vno-paper); white-space: nowrap;
                 box-shadow: 1px 0 0 var(--vno-line); }
.col-pin-right { position: sticky; right: 0; z-index: 1; background: var(--vno-paper);
                 box-shadow: -1px 0 0 var(--vno-line); white-space: nowrap; }

/* Grid display (ui.js). Compact = the default, a full year on a laptop screen.
   Comfortable: larger figures, roomier rows, input boxes reduced to an underline. */
.grid-view { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.grid-view-seg { display: inline-flex; border: 1px solid var(--vno-line); border-radius: var(--r-1); overflow: hidden; }
.grid-view-seg button { padding: 2px 10px; background: var(--vno-paper); color: var(--vb-navy-text); }
.grid-view-seg button + button { border-left: 1px solid var(--vno-line); }
.grid-view-seg button[aria-pressed="true"] { background: var(--vno-navy); color: var(--vb-on-fill); font-weight: 600; }
html.grid-comfortable .table-card.sheet { font-size: 14px; }
html.grid-comfortable .table-card.sheet td, html.grid-comfortable .table-card.sheet th { padding-top: 6px; padding-bottom: 6px; }
html.grid-comfortable .table-card.sheet .text-xs, html.grid-comfortable .table-card.sheet input,
html.grid-comfortable .table-card.sheet select { font-size: 13px; }
html.grid-comfortable .table-card.sheet .fct-row td { font-size: 12px; padding-top: 0; padding-bottom: 6px; }
html.grid-comfortable .table-card.sheet td > input:not(.cell-error):not(.cell-saving):not(.cell-saved) {
  border-color: transparent; border-bottom-color: var(--vno-line); border-radius: 0; }
html.grid-comfortable .table-card.sheet td > input:not(.cell-error):not(.cell-saving):not(.cell-saved):is(:hover, :focus) {
  border-color: var(--vb-navy-line); border-radius: var(--r-1); }
/* the prior-year lines interleaved in a grid (Opex), and their explanation */
html.hide-compare .fct-row, html.hide-compare .fct-note { display: none; }
/* a discreet line before Apr, Jul and Oct */
.table-card.sheet .q-start { border-left: 1px solid var(--vno-line); }

/* Filter / version bar above a grid. */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4);
           margin-bottom: var(--sp-4); }
.toolbar select { max-width: 100%; }

/* Phone and small tablet: only the label stays pinned, so the months get the width;
   touch targets grow to a finger's size. */
@media (max-width: 767px) {
  /* stays sticky for the header row (top), no longer pinned to the right */
  .col-pin-right { right: auto; box-shadow: none; }
  .table-card thead th.col-pin-right { right: auto; box-shadow: inset 0 -1px 0 var(--vno-line); }
  .col-acct { max-width: 9rem !important; }
  .page-title { font-size: 20px; }
}
@media (pointer: coarse) {
  .table-card input, .table-card select, .toolbar select { min-height: 34px; }
  button { min-height: 36px; }
}

/* Top bar (banners, navigation, department bar with its Approve / Accept buttons): stays
   in view on a desktop so the actions are one click away at any scroll depth. */
@media (min-width: 1024px) {
  /* fixed, not sticky: it must stay put when a wide grid scrolls the page sideways too;
     base.html reserves its height at the top of the body */
  .app-top { position: fixed; top: 0; left: 0; right: 0; z-index: 40; box-shadow: 0 1px 0 var(--vno-line); }
  body { padding-top: var(--sticky-top, 0px); }
}

/* Scope bar (level 2 of the header): the department being worked on, on a navy band,
   or the company with a department picker on a light strip. */
.scope-dept  { background: var(--vno-navy-deep); color: var(--vb-on-fill); }
.scope-bar   { background: var(--paper-cool); border-bottom: 1px solid var(--vno-line); }
.scope-label { font: 600 11px/1 var(--font-sans); letter-spacing: 0.14em; text-transform: uppercase; }
.scope-bar .scope-label { color: var(--vb-text-secondary); }
.scope-dept .scope-label, .scope-muted { color: var(--vno-dark-text); }
.dept-switch { background: transparent; color: var(--vb-on-fill); font-weight: 600; max-width: 100%;
               border: 1px solid rgba(255, 255, 255, 0.35); border-radius: var(--r-1); padding: 3px 8px; }
.dept-switch option { color: var(--vno-ink); background: var(--vno-paper); }
.scope-dept :focus-visible { outline-color: var(--vb-on-fill); }
.scope-chip { padding: 2px 10px; border: 1px solid var(--vno-line); border-radius: var(--r-pill);
              background: var(--vno-paper); color: var(--vb-text-link); }

/* Header navigation: inline on a desktop, a Menu button below 1024px. */
.nav-toggle { display: none; }
@media (max-width: 1023px) {
  .nav-toggle { display: inline-flex; }
  .app-nav:not(.is-open) .nav-panel { display: none; }
  .nav-panel { flex-basis: 100%; flex-direction: column; align-items: stretch !important; gap: var(--sp-1) !important; }
  .nav-panel a, .nav-panel .nav-sep { padding: var(--sp-2) var(--sp-1); }
  .nav-panel .nav-sep { display: block; border-top: 1px solid var(--vno-line); height: 0; padding: 0; margin: var(--sp-1) 0; color: transparent; overflow: hidden; }
}

/* Footer: wordmark bottom-left, source caption centre (bible §7). */
.app-footer { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
              flex-wrap: wrap; border-top: 1px solid var(--vno-line);
              padding: var(--sp-4) max(clamp(16px, 2.5vw, 40px), calc((100% - 2560px) / 2 + clamp(16px, 2.5vw, 40px)));
              color: var(--vb-text-secondary); font: 400 12px/1.4 var(--font-sans); letter-spacing: 0.04em; }
.app-footer img { height: 32px; width: auto; }   /* bible: <= 32px standard */

/* Home page: KPI tiles and budget-vs-forecast variances. The arrow and sign carry the
   direction; colour only says favourable (green) or unfavourable (red). */
.kpi-tile   { background: var(--vno-paper); border: 1px solid var(--vno-line);
              border-radius: 6px; padding: var(--sp-3) var(--sp-4); }
.kpi-label  { font: 600 11px/1.3 var(--font-sans); color: var(--vb-text-secondary);
              letter-spacing: 0.08em; text-transform: uppercase; }
.kpi-value  { font: 700 22px/1.2 var(--font-sans); color: var(--vno-ink); margin-top: 4px;
              font-variant-numeric: tabular-nums; }
.kpi-value-lg { font-size: 28px; }
/* Home detail panels: a table opened on demand. */
.detail-panel > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
                          cursor: pointer; list-style: none; background: var(--vno-paper); border: 1px solid var(--vno-line);
                          border-radius: var(--r-2); padding: 12px 16px; }
.detail-panel > summary::-webkit-details-marker { display: none; }
.detail-panel > summary::after { content: "▾"; color: var(--vb-navy-text); }
.detail-panel[open] > summary::after { content: "▴"; }
.kpi-compare { font: 400 12px/1.4 var(--font-sans); color: var(--vb-text-secondary); margin-top: 2px; }
.var-good   { color: var(--vb-text-positive); font-weight: 600; white-space: nowrap; }
.var-bad    { color: var(--vb-text-negative); font-weight: 600; white-space: nowrap; }
.spark-budget  { fill: none; stroke: var(--vb-navy-text); stroke-width: 2; }
.spark-compare { fill: none; stroke: var(--vno-mute); stroke-width: 1.5; stroke-dasharray: 4 3; }

/* View-as banner: an unmistakable read-only state, above the navigation. */
.view-as-bar { background: var(--vno-gold-soft); color: var(--vno-ink);
               border-bottom: 1px solid var(--vno-gold); }

/* Small tables outside a card (home page cards) scroll on their own on a phone. */
@media (max-width: 767px) {
  .page table:not(.table-card table) { display: block; overflow-x: auto; max-width: 100%; }
}
