/* MoneyOS look and feel. Every color, size, radius, shadow, motion and font value below
   comes from tokens/moneyos.json via finance_app/static/tokens.css (generated: never hand-edit
   that file). This sheet defines zero custom properties of its own. */

/* ds-allow-hardcode:start -- @font-face must declare literal family names and file paths;
   every consumer reads var(--font-sans) / var(--font-mono) instead of the family string.
   Self-hosted so the design renders the same on every machine: a local()-only source
   silently fell back to the system face on any Mac without IBM Plex installed, which was
   every machine that has looked at this app. No outbound request; same origin as app.css. */
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/IBMPlexMono-400-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/IBMPlexMono-400-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/fonts/IBMPlexMono-500-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/fonts/IBMPlexMono-500-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url("/assets/fonts/IBMPlexSans-var-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url("/assets/fonts/IBMPlexSans-var-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Sans Thai";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/IBMPlexSansThai-400-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Sans Thai";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/IBMPlexSansThai-400-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Sans Thai";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/IBMPlexSansThai-400-thai.woff2") format("woff2");unicode-range:U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC}
@font-face{font-family:"IBM Plex Sans Thai";font-style:normal;font-weight:600;font-display:swap;src:url("/assets/fonts/IBMPlexSansThai-600-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"IBM Plex Sans Thai";font-style:normal;font-weight:600;font-display:swap;src:url("/assets/fonts/IBMPlexSansThai-600-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"IBM Plex Sans Thai";font-style:normal;font-weight:600;font-display:swap;src:url("/assets/fonts/IBMPlexSansThai-600-thai.woff2") format("woff2");unicode-range:U+02D7, U+0303, U+0331, U+0E01-0E5B, U+200C-200D, U+25CC}
/* ds-allow-hardcode:end */

*{box-sizing:border-box}
[hidden]{display:none!important}
html{scroll-behavior:smooth}
/* TICKET 153: a jump to the work queue (or any in-page move) is not animated for someone
   who asked for reduced motion, as design A's own sheet has it. */
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--color-surface-page);color:var(--color-text-primary);font-family:var(--font-sans);font-size:var(--text-md);line-height:var(--leading-relaxed);font-variant-numeric:tabular-nums;overflow-wrap:break-word;word-break:normal}
p a{color:var(--color-text-link)} /* prose links carry the link token: on the dark theme the user-agent blue measures 1.99:1 on a panel */
svg.icon,svg.i{width:var(--space-20);height:var(--space-20);stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto} /* scoped to icons: a bare svg rule also strokes the report chart shapes */

/* --- Controls: base + the eight required states (default, hover, focus, active, disabled). --- */
button,input,select,textarea{font:inherit}
button,input,select,textarea{min-height:var(--size-44);border:1px solid var(--color-border-strong);border-radius:var(--radius-control);padding:var(--space-8) var(--space-12);background:var(--color-surface-field);color:var(--color-text-primary);transition:background var(--duration-fast) var(--ease-standard),border-color var(--duration-fast) var(--ease-standard)}
input,select{inline-size:100%;min-inline-size:0}
textarea{inline-size:100%;min-inline-size:0;resize:vertical}
button{cursor:pointer;background:var(--color-action-primary);border-color:var(--color-action-primary);color:var(--color-action-primary-text);font-weight:var(--weight-semibold);white-space:nowrap}
button:hover{background:var(--color-action-primary-hover);border-color:var(--color-action-primary-hover)}
button:active{transform:translateY(1px)}
:is(button,input,select,textarea,summary,a[href]):focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:2px;box-shadow:var(--shadow-focus-ring);border-radius:var(--radius-control)}
button:disabled{opacity:var(--opacity-disabled);cursor:not-allowed;transform:none}
.secondary{background:var(--color-action-secondary-bg);color:var(--color-action-secondary-text);border-color:var(--color-action-secondary-border)}
.secondary:hover{background:var(--color-action-secondary-hover)}
.quiet{background:transparent;color:var(--color-text-primary);border-color:var(--color-border-default)}
.quiet:hover{background:var(--color-action-ghost-hover)}
.danger{background:var(--color-surface-card);color:var(--color-action-destructive);border-color:var(--color-action-destructive-border)}
.danger:hover{background:var(--color-action-destructive-hover)}
.primary-action{min-height:var(--size-48);padding-inline:var(--space-20)}
.icon-button{display:inline-flex;align-items:center;justify-content:center;width:var(--size-36);height:var(--size-36);min-height:0;padding:0;background:transparent;color:var(--color-text-secondary);border-color:transparent;position:relative}
.icon-button:hover{background:var(--color-action-ghost-hover)}
.check{display:grid;grid-template-columns:28px 1fr;align-items:start;gap:var(--space-10);flex-basis:100%;font-weight:var(--weight-medium)}
.check input{width:24px;height:24px;min-height:24px;margin:var(--space-2) 0;accent-color:var(--color-action-primary)} /* ds-allow-hardcode: 24px checkbox hit target, fixed control shape not a scale step; the canvas fills the box gold when checked */
.check:has(input:focus-visible){outline:2px solid var(--color-focus-ring);outline-offset:4px;border-radius:var(--radius-sm)}

/* --- Typography and layout scaffolding. --- */
/* TICKET 132: `margin:auto` set every side of `main` to auto, and `.app-column` is a
   column flex container, so a page shorter than the viewport had its TOP margin absorb
   the free space too, pushed well down a tall viewport with nothing above it (measured
   on the intake setup page; see the ticket's report for the figures). A page starts at
   the top of the column; centring is horizontal only. */
/* TICKET 153 (SB-19): design A's page gutter -- --space-32 round the page, --space-24
   from the prototype's widest step down and --space-16 on a phone (the media blocks
   below). */
main{width:min(1180px,100%);margin:0 auto;padding:var(--space-32) var(--space-32) var(--space-56)}
h1,h2,h3,h4{line-height:var(--leading-tight);margin:0 0 var(--space-8)}
h1{font-size:var(--text-xxl);font-weight:var(--weight-semibold);letter-spacing:-0.02em}
h2{font-size:var(--text-lg);font-weight:var(--weight-semibold)}
h3{font-size:var(--text-md);font-weight:var(--weight-semibold)}
h4{font-size:var(--text-base);font-weight:var(--weight-semibold);margin-top:var(--space-20)}
/* Thai carries vowels and tone marks above and below the line; negative tracking
   collides them, and the design-handoff asks for normal letter-spacing on Thai
   headings. The Latin tightening stays, selected by the lang the i18n layer sets on
   <html> (th or en), so one rule covers every heading on every screen. */
:root:lang(th) :is(h1,h2,h3,h4,.brand-name,.admin-heading h1){letter-spacing:normal}
/* Money is read down a column, so the figures line up: the tabular set is on <body>
   and is repeated here for anything a later ticket renders outside it. */
td,th,.active-company{font-variant-numeric:tabular-nums}
p{color:var(--color-text-secondary);max-width:78ch;margin:0 0 var(--space-8)}
.eyebrow,.step-number,.nav-label{display:block;white-space:nowrap;color:var(--color-text-caption);font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:.08em;text-transform:uppercase}
.hold{color:var(--color-feedback-hold-text)}
/* TICKET 153 (SB-19): the page heading every page borrows. Two shapes reach this rule:
   the overview's (a wrapper holding the title and its subtitle, then the freshness line
   as a `role=status` sibling) and every other page's (eyebrow, title and subtitle as
   direct children). One wrapping row serves both: a wrapper and a status line share the
   row, title at the start and freshness at the end, and anything else takes a whole
   line of its own, so the second shape still stacks. The eyebrow is not drawn: it said
   the breadcrumb's own first word again, one line above the title it introduced. */
.page-heading{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--space-8) var(--space-20);margin:0 0 var(--space-28)}
/* Repeated with a `:has()` so it outranks a page's own heading class loaded after this
   sheet (page-board.css `.board-heading` sets flex-start and its own gap). */
.page-heading:has(>[role=status]){align-items:flex-end;gap:var(--space-8) var(--space-20)}
.page-heading>:not(div,[role=status]){flex:1 1 100%}
.page-heading>div{flex:1 1 auto;min-inline-size:0}
.page-heading>[role=status]{flex:0 1 auto;margin:0;padding-block-end:var(--space-4)}
.page-heading .eyebrow{display:none}
/* The page title every page borrows is design A's display size on the prototype's own
   line: --text-display-sm on --leading-normal, and --text-xxl on the same leading on a
   phone (the phone block). --leading-normal is 1.5, the brief's 1.5-1.6 for Thai: the
   old --leading-tight (1.15) left no room above the line for Thai vowels and tone marks,
   and --leading-snug (1.2) would leave little more. Scoped to the page heading so the back
   office, which borrows this sheet and keeps its own shell, keeps its own titles. */
.page-heading h1{margin:0;font-size:var(--text-display-sm);line-height:var(--leading-normal)}
.page-heading h1~p{margin:var(--space-8) 0 0;font-size:var(--text-base)}
.page-heading h1+p{margin-block-start:var(--space-12)}
.admin-heading{padding:0;background:transparent;border:0}

/* --- Login lives in page-login.css since ticket 113: design A is a two-panel page, not
       a card in this column, and the session check in front of it is its own state. --- */

/* --- Forms shared by every panel. --- */
form{display:flex;align-items:flex-end;flex-wrap:wrap;gap:var(--space-16);padding:var(--space-12) 0}
label{display:flex;flex:1 1 210px;flex-direction:column;gap:var(--space-6);font-weight:var(--weight-medium)}
.wide{flex-basis:100%;width:100%;min-width:0}
.filter-card,.advanced-section,.admin-section{border:1px solid var(--color-border-default);border-radius:var(--radius-card);background:var(--color-surface-card);padding:0 var(--space-16);margin:var(--space-14) 0}
.filter-card>summary,.advanced-section>summary,.admin-section>summary{cursor:pointer;min-height:var(--size-48);padding:var(--space-12) 0;font-weight:var(--weight-semibold);display:flex;align-items:center}

/* TICKET 110 removed the board's date bar: `.range-shortcuts`, `.filter-range` and
   `#filters input[aria-invalid=true]` went with it. The overview's date scope is
   ticket 109's control (date-range.css), whose boundaries the server computes. */

/* --- The reusable filter control (finance_app/static/filter-select.js): a searchable,
   multi-select combobox. Open and closed is the `hidden` attribute and these classes and
   nothing else: the CSP is `style-src 'self'` with no unsafe-inline, so a style attribute
   is forbidden outright. Every value below is a token; this sheet defines none. --- */
.filter-select{display:flex;flex-direction:column;gap:var(--space-6);flex:1 1 var(--size-150);min-width:0}
.filter-select>label{flex:0 0 auto;font-weight:var(--weight-medium)}
.filter-select-field{position:relative;display:flex;align-items:center;min-width:0}
.filter-select-field input{padding-inline-end:var(--space-36)}
.filter-select-chevron{position:absolute;inset-inline-end:var(--space-10);display:flex;color:var(--color-text-secondary);pointer-events:none}
.filter-select-popup{position:absolute;inset-inline:0;top:100%;margin-block-start:var(--space-4);z-index:var(--z-overlay);background:var(--color-surface-raised);border:1px solid var(--color-border-strong);border-radius:var(--radius-card);box-shadow:var(--shadow-sm);max-block-size:var(--size-280);overflow:auto}
.filter-select-list{list-style:none;margin:0;padding:var(--space-4)}
.filter-select-option{display:flex;align-items:center;gap:var(--space-8);min-height:var(--size-44);padding:var(--space-8) var(--space-12);border-radius:var(--radius-control);cursor:pointer;font-size:var(--text-sm)}
.filter-select-option:hover{background:var(--color-action-ghost-hover)}
.filter-select-option[aria-selected=true]{background:var(--color-surface-selected);font-weight:var(--weight-semibold)}
/* The highlight the arrow keys move is drawn, not only announced: aria-activedescendant
   moves no real focus, so nothing would show it otherwise. */
.filter-select-option[data-active=true]{outline:2px solid var(--color-focus-ring);outline-offset:calc(-1 * var(--space-2))}
.filter-select-tick{display:flex;color:var(--color-action-primary)}
/* Chosen is a mark as well as a tint, so the state does not rest on colour alone. */
.filter-select-option[aria-selected=false] .filter-select-tick{visibility:hidden}
.filter-select-empty{margin:0;padding:var(--space-8) var(--space-12);font-size:var(--text-sm)}
.filter-select-note{margin:0;font-size:var(--text-sm)}

/* TICKET 110: `.filter-dates` styled the board's two `type=date` boxes, which the
   date-range control replaced. */

.language-switch{display:inline-flex;align-items:center;flex:0 0 auto;border:1px solid var(--color-border-strong);border-radius:var(--radius-control);overflow:hidden;background:var(--color-surface-card)}
.language-switch button{min-height:0;height:var(--size-36);min-width:var(--size-44);padding-inline:var(--space-10);border:0;border-radius:0;background:transparent;color:var(--color-text-secondary);font-size:var(--text-sm);font-weight:var(--weight-semibold)}
.language-switch button:hover{background:var(--color-action-ghost-hover)}
.language-switch button[aria-pressed=true]{background:var(--color-action-primary);color:var(--color-action-primary-text)}
.language-switch button:focus-visible{outline-offset:calc(-1 * var(--space-2))}
/* --- Application shell, design A (contract: .app-shell / .sidebar / .company-switch /
   #primary-nav / .sidebar-foot / .app-column / .topbar / .avatar). The sidebar carries
   the six destinations the brief names and the company being looked at; the top bar
   carries where you are, that company's name again, the language and Refresh. Before
   sign-in there is no company and no section, so the sidebar is not rendered at all and
   the top bar is the brand and the language switch. --- */
.app-shell{display:grid;grid-template-columns:calc(var(--space-64)*3 + var(--space-40)) minmax(0,1fr);min-block-size:100vh}
body:has(#workspace[hidden]) .app-shell{grid-template-columns:minmax(0,1fr)}
body:has(#workspace[hidden]) .sidebar,body:has(#workspace[hidden]) .breadcrumb,body:has(#workspace[hidden]) #active-company,body:has(#workspace[hidden]) #refresh{display:none}
.topbar .brand{display:none}
body:has(#workspace[hidden]) .topbar .brand{display:flex}
.skip-link{position:absolute;inset-block-start:var(--space-8);inset-inline-start:var(--space-8);z-index:var(--z-modal);padding:var(--space-12) var(--space-16);background:var(--color-surface-card);color:var(--color-text-primary);border:1px solid var(--color-border-strong);border-radius:var(--radius-control);transform:translateY(-200%)}
.skip-link:focus-visible{transform:none}

.sidebar{display:flex;flex-direction:column;gap:var(--space-24);min-inline-size:0;padding:var(--space-24) var(--space-16);background:var(--color-surface-card);border-inline-end:1px solid var(--color-border-default)}
/* TICKET 153 (SB-13): on a desk the sidebar is fixed to the viewport, as design A's is, so
   the receiving state, the profile and sign-out stay in the first screen however long the
   page under it grows; a sidebar taller than the window scrolls inside itself. */
@media (min-width:981px){
  .sidebar{position:sticky;inset-block-start:0;align-self:start;block-size:100vh;block-size:100dvh;overflow-y:auto;overscroll-behavior:contain}
}
/* TICKET 153 (SB-01): the drawer is the sidebar's own column above 700px -- the
   navigation and the foot, in the order they always had -- and becomes the phone's menu
   panel below it (the phone block). The receiving mark, the menu button, the drawer's
   own heading and its scrim are phone-only. */
.shell-drawer{display:flex;flex-direction:column;gap:var(--space-24);flex:1 1 auto;min-block-size:0;min-inline-size:0}
.shell-status,.shell-menu,.shell-drawer-head,.shell-scrim{display:none}
.shell-menu,.shell-menu-close{align-items:center;justify-content:center;flex:0 0 auto;inline-size:var(--size-44);block-size:var(--size-44);min-block-size:0;padding:0;background:var(--color-action-secondary-bg);color:var(--color-action-secondary-text);border-color:var(--color-action-secondary-border)}
.shell-menu:hover{background:var(--color-action-secondary-hover);border-color:var(--color-action-secondary-border)}
.shell-menu-close{display:inline-flex;background:transparent;border-color:transparent;color:var(--color-text-secondary)}
.shell-menu-close:hover{background:var(--color-action-ghost-hover);border-color:transparent;color:var(--color-text-primary)}
.shell-drawer-title{font-size:var(--text-md);font-weight:var(--weight-semibold);color:var(--color-text-primary)}
.shell-language{display:flex;align-items:center;justify-content:space-between;gap:var(--space-12);min-inline-size:0}
.brand{display:flex;align-items:center;gap:var(--space-12);min-inline-size:0}
.brand-mark{display:flex;align-items:center;justify-content:center;inline-size:var(--size-40);block-size:var(--size-40);flex:0 0 auto;border-radius:var(--radius-card);background:var(--color-action-primary);color:var(--color-text-on-primary);font-weight:var(--weight-bold);font-size:var(--text-lg)}
.brand-copy{display:flex;flex-direction:column;min-inline-size:0}
.brand-name{font-weight:var(--weight-semibold);font-size:var(--text-lg);letter-spacing:-0.02em;color:var(--color-text-primary)}
.brand-sub{font-size:var(--text-xs);font-weight:var(--weight-medium);letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-secondary)}

/* The company switcher. The select is the control and the source of truth; the search
   box above it appears only once the list is long (COMPANY_SEARCH_FROM in app.js) and
   filters the options in place, so the keyboard model stays the platform's own. */
.company-switch{display:flex;flex-direction:column;gap:var(--space-8);min-inline-size:0;padding-block:var(--space-16);border-block:1px solid var(--color-border-default)}
.mini-label{display:block;flex:0 0 auto;font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-caption)}
.company-search{display:flex;align-items:center;gap:var(--space-8);min-inline-size:0;padding-inline:var(--space-10);border:1px solid var(--color-border-strong);border-radius:var(--radius-control);background:var(--color-surface-field);color:var(--color-text-secondary)}
.company-search:focus-within{outline:2px solid var(--color-focus-ring);outline-offset:2px;border-radius:var(--radius-control)}
.company-search input{min-inline-size:0;flex:1 1 auto;border:0;background:transparent;padding-inline:0}
.company-search input:focus-visible{outline:0;box-shadow:none}
.company-switch select{inline-size:100%;min-inline-size:0;font-weight:var(--weight-semibold)}
.company-count{margin:0;font-size:var(--text-xs);color:var(--color-text-secondary);max-inline-size:none}

#primary-nav{display:flex;flex-direction:column;gap:var(--space-4);min-inline-size:0}
.nav-item{display:flex;align-items:center;gap:var(--space-12);inline-size:100%;min-inline-size:0;min-block-size:var(--size-44);padding:var(--space-10) var(--space-12);text-align:start;white-space:normal;background:transparent;border:1px solid transparent;border-radius:var(--radius-control);color:var(--color-text-secondary);font-size:var(--text-base);font-weight:var(--weight-medium)}
.nav-item>span{min-inline-size:0;overflow-wrap:anywhere}
.nav-item:hover{background:var(--color-action-ghost-hover);border-color:transparent;color:var(--color-text-primary)}
.nav-item:active{background:var(--color-action-secondary-hover)}
.nav-item[aria-current=page]{background:var(--color-surface-selected);color:var(--color-action-primary);font-weight:var(--weight-semibold)}
.nav-item[aria-current=page]:hover{background:var(--color-surface-accent-chip);color:var(--color-action-primary-hover)}
/* TICKET 153 (SB-08): the work queue's count on its own entry, design A's warning chip.
   It is drawn only while the board has handed the shell a number (app.js `setNavCount`);
   with none it is `hidden`, never a zero or a dash the shell made up. */
.nav-count{flex:0 0 auto;margin-inline-start:auto;min-inline-size:var(--space-20);padding-inline:var(--space-6);border-radius:var(--radius-sm);background:var(--color-feedback-warning-bg);color:var(--color-feedback-hold-text);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:var(--leading-normal);text-align:center}

.sidebar-foot{display:flex;flex-direction:column;gap:var(--space-10);margin-block-start:auto;min-inline-size:0}
/* Receiving state, read from the server (GET /api/c/{company}/telegram). The dot is
   never the only carrier: the words beside it say the same thing. */
.intake-status{display:flex;align-items:center;gap:var(--space-8);margin:0;max-inline-size:none;font-size:var(--text-sm);color:var(--color-text-secondary)}
.status-dot{inline-size:var(--space-8);block-size:var(--space-8);flex:0 0 auto;border-radius:var(--radius-pill);background:var(--color-text-caption)}
.intake-status[data-state=running] .status-dot{background:var(--color-feedback-success-text)}
.intake-status[data-state=running]{color:var(--color-feedback-success-text)}
/* TICKET 157 (SI-07): a worker that ended without anybody pressing Stop has its own words
   and its own mark, told apart from a person's stop by shape as well as colour: a square in
   the error ink where a stop is a grey dot. */
.intake-status[data-state=interrupted] .status-dot{border-radius:var(--radius-sm);background:var(--color-feedback-error-text)}
.intake-status[data-state=interrupted]{color:var(--color-feedback-error-text)}
.sidebar-link{display:flex;align-items:center;gap:var(--space-10);inline-size:100%;min-inline-size:0;min-block-size:var(--size-44);padding:var(--space-10) var(--space-12);background:transparent;border:1px solid transparent;border-radius:var(--radius-control);color:var(--color-text-secondary);font-size:var(--text-sm);font-weight:var(--weight-medium);text-align:start}
.sidebar-link:hover{background:var(--color-action-ghost-hover);color:var(--color-text-primary)}
.sidebar-link[aria-current=page]{background:var(--color-surface-selected);color:var(--color-action-primary);font-weight:var(--weight-semibold)}
#notify-count:not(:empty){display:inline-flex;align-items:center;justify-content:center;margin-inline-start:auto;min-inline-size:var(--space-20);block-size:var(--space-20);padding-inline:var(--space-6);border-radius:var(--radius-pill);background:var(--color-badge-failed-bg);color:var(--color-badge-failed-text);font-size:var(--text-xs);font-weight:var(--weight-bold);line-height:var(--leading-none)}
.profile{display:flex;align-items:center;gap:var(--space-10);min-inline-size:0;padding-block-start:var(--space-12);border-block-start:1px solid var(--color-border-default)}
.profile-copy{display:flex;flex-direction:column;min-inline-size:0}
.profile-name{font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--color-text-primary);overflow-wrap:anywhere}
.profile-role{font-size:var(--text-xs);color:var(--color-text-secondary)}
.avatar{display:inline-flex;align-items:center;justify-content:center;inline-size:var(--size-36);block-size:var(--size-36);flex:0 0 auto;border-radius:var(--radius-pill);background:var(--color-avatar-bg);color:var(--color-avatar-text);font-weight:var(--weight-semibold);font-size:var(--text-sm)}
.sidebar-signout{justify-content:flex-start;inline-size:100%;min-inline-size:0;gap:var(--space-10);display:flex;align-items:center;font-size:var(--text-sm)}

.app-column{display:flex;flex-direction:column;min-inline-size:0}
.topbar{display:flex;align-items:center;gap:var(--space-16);min-block-size:var(--size-64);padding:var(--space-8) var(--space-24);background:var(--color-surface-card);border-block-end:1px solid var(--color-border-default);flex-wrap:wrap;row-gap:var(--space-8)}
.breadcrumb{display:flex;align-items:center;gap:var(--space-8);margin:0;min-inline-size:0;max-inline-size:none;font-size:var(--text-sm);color:var(--color-text-secondary)}
.breadcrumb strong{color:var(--color-text-primary);font-weight:var(--weight-semibold)}
.top-actions{display:flex;align-items:center;gap:var(--space-12);margin-inline-start:auto;min-inline-size:0;flex-wrap:wrap;row-gap:var(--space-8)}
.active-company{min-inline-size:0;font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--color-text-primary);overflow-wrap:anywhere}
#refresh,#logout{flex:0 0 auto}
/* TICKET 153 (SB-26): the icon and the word sit on one line, a gap apart. */
#refresh{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-8)}

/* TICKET 110: the four board tiles (`.tiles` / `.tile` / `.tile-lead`) are the
   overview's own counters now, in page-board.css. TICKET 132: the settings hub's own
   `.hub-tile` rules, further down in this file until this ticket, are retired with it. */

.shortcut-tile{display:inline-flex;align-items:center;gap:var(--space-8);justify-content:flex-start;background:var(--color-surface-card);color:var(--color-text-primary);border:1px solid var(--color-border-strong);border-radius:var(--radius-card);padding:var(--space-16);min-height:var(--size-64);font-weight:var(--weight-semibold)}
.shortcut-tile:hover{background:var(--color-surface-selected);border-color:var(--color-action-primary);color:var(--color-action-primary)}
.shortcut-tile span{flex:1 1 auto;text-align:start}
.shortcuts,.dashboard-shortcuts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-16);margin:var(--space-16) 0}
/* TICKET 110: the five kanban columns and their slip cards are gone (brief F08), and
   with them `.board`, `.board-column`, `.board-count`, `.board-cards`, `.board-more`
   and every `.slip-*` rule. `.badge` below stays: the alert log and the overview's
   work queue both wear it. */
.mono{font-family:var(--font-mono)}
.badge{display:inline-flex;align-items:center;gap:var(--space-6);height:var(--space-20);padding-inline:var(--space-10);border-radius:var(--radius-pill);font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:.01em;white-space:nowrap}
.badge[data-badge=pending]{background:var(--color-badge-pending-bg);color:var(--color-badge-pending-text)}
.badge[data-badge=processing]{background:var(--color-badge-processing-bg);color:var(--color-badge-processing-text)}
.badge[data-badge=review]{background:var(--color-badge-review-bg);color:var(--color-badge-review-text)}
.badge[data-badge=reviewed]{background:var(--color-badge-reviewed-bg);color:var(--color-badge-reviewed-text)}
.badge[data-badge=failed]{background:var(--color-badge-failed-bg);color:var(--color-badge-failed-text)}
.badge[data-badge=duplicate]{background:var(--color-badge-duplicate-bg);color:var(--color-badge-duplicate-text)}

/* --- Alert log (contract: #alerts-panel / .alert-pills / .alert-pill / .badge[data-badge^=alert-]). --- */
.alert-pills{display:flex;flex-direction:column;gap:var(--space-16);list-style:none;margin:0;padding:0}
.alert-pill{display:flex;align-items:flex-start;gap:var(--space-10);padding:var(--space-10) var(--space-12);border:1px solid var(--color-border-lead);border-radius:var(--radius-control);background:var(--color-feedback-error-bg);color:var(--color-feedback-error-text)}
.alert-pill-body{min-width:0;display:flex;flex-direction:column;gap:var(--space-6)} /* TICKET 293: the message, then its next try */
.alert-pill-body>span{min-width:0;white-space:pre-line} /* the group receives a Thai line and an English line; keep the break */
.alert-next-try{margin:0;font-size:var(--text-sm);font-weight:var(--weight-semibold)}
.alert-next-try>time{white-space:nowrap}
.alert-empty{margin:0;color:var(--color-text-secondary)}
.alert-note{margin:0;font-size:var(--text-base);color:var(--color-text-secondary);white-space:pre-line} /* the canvas closes the card with the latest resolution message */
.badge[data-badge=alert-raised]{background:var(--color-badge-review-bg);color:var(--color-badge-review-text)}
.badge[data-badge=alert-cleared]{background:var(--color-badge-reviewed-bg);color:var(--color-badge-reviewed-text)}
.alert-time{font-family:var(--font-mono);font-size:var(--text-base)}
.alert-kind{overflow-wrap:anywhere}
#alert-rows td{vertical-align:top}

/* --- Tables (contract: .table-scroll). The records table under the board went with
   the kanban (ticket 110); the settings pages and the back office keep these. --- */
.table-scroll{max-width:100%;overflow:auto;border:1px solid var(--color-border-default);border-radius:var(--radius-card);background:var(--color-surface-card);margin:var(--space-14) 0}
table{width:100%;border-collapse:collapse;min-width:680px} /* ds-allow-hardcode: intrinsic table minimum forces .table-scroll to scroll instead of squeezing data columns */
th,td{padding:var(--space-12);text-align:left;border-bottom:1px solid var(--color-border-subtle)}
th{background:var(--color-surface-sunken);font-size:var(--text-sm)}
caption{text-align:left;padding:var(--space-12);font-weight:var(--weight-semibold)}
.inline-controls{display:flex;gap:var(--space-6);align-items:center;flex-wrap:wrap}
.inline-controls select,.inline-controls input{min-inline-size:0;inline-size:auto}
.inline-controls button{margin:0;padding-inline:var(--space-12)}
#users-table td{vertical-align:middle}

/* --- Inspection detail (evidence + review form). --- */
.inspection{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-18);margin-top:var(--space-18)}
.inspection>div{min-width:0;background:var(--color-surface-card);border:1px solid var(--color-border-default);border-radius:var(--radius-card);padding:var(--space-18)}
.inspection .wide{grid-column:1/-1}
.inspection img{display:block;max-width:100%;max-height:620px;margin:auto} /* ds-allow-hardcode: viewport-fit cap for evidence images, not a scale step */
/* The canvas ends the left detail card on the evidence itself, inside its own frame. */
.inspection .evidence{display:flex;align-items:center;justify-content:center;margin-top:var(--space-14);padding:var(--space-10);border:1px solid var(--color-border-default);border-radius:var(--radius-control);background:var(--color-surface-sunken)}
.inspection pre{white-space:pre-wrap;overflow-wrap:anywhere}
/* The review form's reason gate (ticket 27) wears the back office gate's disabled tokens
   rather than fading the gold fill: a held primary action has to stay readable. */
#review-form button:disabled,#sample-form button:disabled,#correction-form button:disabled{background:var(--color-action-disabled-bg);border-color:var(--color-action-disabled-border);color:var(--color-action-disabled-text);opacity:1;cursor:not-allowed}
#moneyos-event-detail{display:block;max-width:100%;overflow:auto}
#moneyos-event-detail img{display:block;max-width:100%;max-height:26rem;object-fit:contain;margin:var(--space-14) auto}
.button-spinner{display:inline-block;width:1rem;height:1rem;border:var(--space-2) solid currentColor;border-right-color:transparent;border-radius:50%;animation:button-spin .7s linear infinite}
button[aria-busy="true"]{opacity:1;pointer-events:none}
@keyframes button-spin{to{transform:rotate(360deg)}}
.moneyos-field-grid{display:grid;grid-template-columns:minmax(10rem,1fr) minmax(0,2fr);gap:var(--space-8) var(--space-14)}
.moneyos-field-grid dt{font-weight:var(--weight-semibold)}
.moneyos-field-grid dd{margin:0;overflow-wrap:anywhere}
@media(max-width:600px){.moneyos-field-grid{grid-template-columns:1fr}} /* ds-allow-hardcode: narrow layout breakpoint */

#reconcile,#export,#bi-export,#load-audit,#recover{width:auto;background:var(--color-action-secondary-bg);color:var(--color-action-secondary-text);border-color:var(--color-action-secondary-border)} /* secondary: the page keeps one primary action */
/* --- Settings (contract: .settings-card / .card-actions). TICKET 157 (SI-01): `.settings-layout`
   and `#settings-nav`, the settings rail, are gone; each settings page is full width. --- */
.settings-card{background:var(--color-surface-card);border:1px solid var(--color-border-default);border-radius:var(--radius-card);padding:var(--space-24);display:flex;flex-direction:column;gap:var(--space-16);margin:var(--space-16) 0}
.settings-card>summary{padding:0;min-height:0;font-size:var(--text-lg);font-weight:var(--weight-semibold)}
.settings-card h2{margin:0;font-size:var(--text-lg);font-weight:var(--weight-semibold)}
.card-actions{display:flex;align-items:center;justify-content:space-between;gap:var(--space-16);margin:var(--space-8) calc(var(--space-24) * -1) calc(var(--space-24) * -1);padding:var(--space-16) var(--space-24);border-top:1px solid var(--color-border-default);background:var(--color-surface-page);border-radius:0 0 var(--radius-card) var(--radius-card);flex-wrap:wrap}
/* TICKET 110: `#board-status-tabs` and the `.segmented` strip it was the only user of
   went with the kanban they switched between. */

/* The footer band bleeds to the card's edge and pulls itself into the card's bottom
   padding. Canvas frame 06 continues past that band -- the version lines and the group
   table -- so whatever follows must not be dragged up over it. `.step-nav` already
   cancels the pull with a top margin of its own. */
.card-actions + :not(.step-nav){margin-top:var(--space-32)}

/* TICKET 119 retired `.telegram-wizard`, `.wizard-step`, `.recovery-card`, `.status-card`
   and `.step-back` with the wizard markup that wore them; the intake setup is
   `page-intake-setup.css`. What is left in this block belongs to surfaces this app still
   draws: `.status-details` is the correction fold and `.plain-checklist` its history. */
.wizard-intro{padding:var(--space-20) var(--space-20) var(--space-8)}
.wizard-intro .hold{background:var(--color-feedback-hold-bg);border:1px solid var(--color-border-lead);border-radius:var(--radius-card);padding:var(--space-12);max-width:none}
.telegram-states{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-8);padding:var(--space-12) var(--space-20)}
.state-pill{display:grid;grid-template-columns:34px 1fr;align-items:center;column-gap:var(--space-8);padding:var(--space-10);border:1px solid var(--color-border-default);border-radius:var(--radius-card);background:var(--color-surface-sunken)} /* ds-allow-hardcode: 34px icon column matches the fixed 32px state dot plus its gap */
.state-pill>span{grid-row:1/3;display:grid;place-items:center;width:32px;height:32px;border-radius:var(--radius-pill);background:var(--color-border-default);color:var(--color-text-secondary);font-weight:var(--weight-bold);font-size:var(--text-base)} /* ds-allow-hardcode: fixed 32px status dot, not a scale step */
.state-pill strong{font-size:var(--text-base)}
.state-pill small{color:var(--color-text-secondary);font-size:var(--text-xs)}
.state-pill[data-state=on]{background:var(--color-surface-selected);border-color:var(--color-action-primary)}
.state-pill[data-state=on]>span{background:var(--color-action-primary);color:var(--color-text-on-primary)}
.state-pill[data-state=active]{background:var(--color-badge-processing-bg);border-color:var(--color-badge-processing-text)}
.state-pill[data-state=active]>span{background:var(--color-badge-processing-text);color:var(--color-text-on-primary)}
.step-progress{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--space-4);list-style:none;margin:var(--space-10) var(--space-20) 0;padding:0}
.step-progress li{position:relative;padding:var(--space-10) var(--space-4) var(--space-8);border-top:4px solid var(--color-border-default);color:var(--color-text-caption);font-size:var(--text-xs);text-align:center} /* ds-allow-hardcode: 4px progress rule thickness, decorative not thematic */
.step-progress li[data-state=done]{border-color:var(--color-action-primary);color:var(--color-action-primary)}
.step-progress li[data-state=current]{border-color:var(--color-focus-ring);color:var(--color-text-primary);font-weight:var(--weight-bold)}
.status-details{margin-top:var(--space-8)}
.status-details summary{cursor:pointer;min-height:var(--size-44);padding:var(--space-8) 0;font-weight:var(--weight-semibold);color:var(--color-text-secondary)}
.plain-checklist{list-style:none;padding:0;margin:var(--space-18) 0}
.plain-checklist li{position:relative;padding:var(--space-10) var(--space-10) var(--space-10) var(--space-36);border-bottom:1px solid var(--color-border-subtle)}
.plain-checklist li:before{content:"-";position:absolute;left:var(--space-8);color:var(--color-action-primary);font-weight:var(--weight-bold)}
.helper{font-size:var(--text-base);color:var(--color-text-secondary)}
.safe-notice{padding:var(--space-12);border:1px solid var(--color-border-default);border-radius:var(--radius-card);background:var(--color-feedback-success-bg);color:var(--color-feedback-success-text)}
.visual-help{margin:var(--space-14) 0;border:1px solid var(--color-border-default);border-radius:var(--radius-card);background:var(--color-surface-card);padding:0 var(--space-12)}
.visual-help>summary{cursor:pointer;min-height:var(--size-48);padding:var(--space-12) 0;font-weight:var(--weight-semibold)}
.visual-help ol{list-style:none;padding:0}
.visual-help li,li.tap-guide{display:grid;grid-template-columns:48px 1fr;gap:var(--space-10);padding:var(--space-12) 0;border-top:1px solid var(--color-border-subtle)} /* ds-allow-hardcode: 48px fixed icon column for the tap guide */
.visual-help [role=img],li.tap-guide [role=img]{display:grid;place-items:center;width:44px;height:44px;border-radius:var(--radius-card);background:var(--color-surface-selected);color:var(--color-action-primary);font-weight:var(--weight-bold)} /* ds-allow-hardcode: 44px matches the touch-target size scale but keyed to icon shape, not a control */
.visual-help p{margin:var(--space-2) 0}

/* --- Global status message + footer. --- */
/* The operator notice. It used to be `position:sticky;bottom:` and therefore sat at the
   foot of a page that is fourteen screens tall on a phone, which is where the owner
   reported never seeing it. It is now pinned to the top of the viewport: after pressing
   something the eye is near the control, not at the end of the document. app.js clears it
   on a timer, so nothing accumulates here. */
#message:not(:empty){position:fixed;top:var(--space-16);left:var(--space-16);right:var(--space-16);margin:0 auto;width:fit-content;max-width:calc(100% - var(--space-32));z-index:var(--z-overlay);padding:var(--space-14) var(--space-18);border:2px solid var(--color-action-primary);border-radius:var(--radius-card);background:var(--color-surface-card);box-shadow:var(--shadow-sm);font-weight:var(--weight-semibold);color:var(--color-text-primary);text-align:center} /* ds-allow-hardcode: 2px toast border weight, decorative not thematic */
footer{padding:var(--space-24) max(var(--space-20),calc((100vw - 1180px)/2));background:var(--color-surface-sunken);color:var(--color-text-secondary);font-size:var(--text-base)}

/* --- BI report: chart series, stat tiles, legend, tooltip, status pills. --- */
.bi-presets{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-8);padding:var(--space-10) 0 var(--space-2)}
.bi-presets .helper{margin:0 var(--space-6) 0 0}
.bi-presets button{min-height:var(--size-40);padding:var(--space-6) var(--space-14);background:var(--color-surface-card);color:var(--color-text-primary);border:1px solid var(--color-border-default)}
.bi-presets button:hover{background:var(--color-surface-selected)}
.bi-tiles div[data-metric]{border-radius:var(--radius-card)}
.bi-tiles dd[data-metric=expected_satang]{font-size:var(--text-xl);color:var(--color-action-primary)}
.bi-tiles div:has(dd[data-metric=expected_satang]){border-color:var(--color-action-primary);background:var(--color-surface-selected)}
.bi-equation{font-variant-numeric:tabular-nums;color:var(--color-text-secondary);margin:calc(var(--space-6) * -1) 0 var(--space-16)}
.bi-charts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,32ch),1fr));gap:var(--space-14);margin:var(--space-6) 0 var(--space-18)}
.bi-chart{margin:0;background:var(--color-surface-card);border:1px solid var(--color-border-default);border-radius:var(--radius-card);padding:var(--space-14) var(--space-16) var(--space-8)}
.bi-chart figcaption{font-weight:var(--weight-bold);font-size:var(--text-md);margin-bottom:var(--space-6)}
.chart-legend{display:flex;gap:var(--space-16);list-style:none;margin:0 0 var(--space-6);padding:0;font-size:var(--text-sm);color:var(--color-text-secondary)}
.chart-legend li{display:flex;align-items:center;gap:var(--space-6)}
.chart-legend .swatch{width:14px;height:10px;border-radius:var(--radius-sm);display:inline-block} /* ds-allow-hardcode: fixed 14x10 legend swatch shape, decorative not thematic */
.bi-svg{width:100%;height:auto;display:block;font-family:inherit} /* ds-allow-hardcode: inherits the page font, not a literal family name */
.bi-svg .grid{stroke:var(--color-chart-grid);stroke-width:1}
.bi-svg .axis{stroke:var(--color-chart-axis);stroke-width:1}
.bi-svg .tick,.bi-svg .label,.bi-svg .value{font-size:var(--text-xs);fill:var(--color-text-secondary);font-variant-numeric:tabular-nums}
.bi-svg .label{fill:var(--color-text-primary)}
.bi-svg .value{fill:var(--color-text-primary);font-weight:var(--weight-semibold)}
.bi-svg .bar{transition:opacity var(--duration-fast) var(--ease-standard)}
.bi-svg .bar:hover,.bi-svg .bar:focus{opacity:.8;outline:none}
.bi-svg .bar:focus-visible{stroke:var(--color-focus-ring);stroke-width:1.5}
#bi-tooltip{position:absolute;z-index:var(--z-tooltip);background:var(--color-text-primary);color:var(--color-text-on-primary);border-radius:var(--radius-card);padding:var(--space-8) var(--space-10);font-size:var(--text-sm);pointer-events:none;box-shadow:var(--shadow-sm);max-width:260px} /* ds-allow-hardcode: tooltip max-width is a layout guard, not a scale step */
#bi-tooltip .tip-row{display:flex;align-items:center;gap:var(--space-8)}
#bi-tooltip .tip-key{width:12px;height:3px;border-radius:var(--radius-sm);display:inline-block;background:var(--color-text-on-primary)} /* ds-allow-hardcode: fixed legend-key mark shape, decorative not thematic */
#bi-tooltip strong{font-variant-numeric:tabular-nums}
.status-pill{display:flex;align-items:flex-start;gap:var(--space-10);margin:var(--space-8) 0;padding:var(--space-10) var(--space-12);border-radius:var(--radius-control);border:1px solid var(--color-border-default);background:var(--color-surface-card);color:var(--color-text-primary);max-width:none}
.status-pill .status-icon{flex:0 0 auto;color:currentColor}
.status-pill:empty{display:none}
.status-pill[data-kind=good]{border-color:var(--color-border-default);background:var(--color-feedback-success-bg);color:var(--color-feedback-success-text)}
.status-pill[data-kind=warning]{border-color:var(--color-border-lead);background:var(--color-feedback-warning-bg);color:var(--color-feedback-warning-text)}
.status-pill[data-kind=critical]{border-color:var(--color-border-danger);background:var(--color-feedback-error-bg);color:var(--color-feedback-error-text)}

/* --- Bottom nav (phone only). --- */
.sr-only,.visually-hidden{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;padding:0;margin:-1px}

/* --- Responsive: 700px collapses chrome to phone shape; 380px trims further. Never overflows at 280px. --- */
/* TICKET 153 (SB-19): the prototype's widest step narrows the gutter and stacks the page
   heading, so the freshness line goes under the title instead of squeezing it. */
@media (max-width:1200px){
  main{padding-inline:var(--space-24)}
  .topbar{padding-inline:var(--space-24)}
  .page-heading:has(>[role=status]){align-items:flex-start}
  .page-heading>[role=status]{flex-basis:100%}
}
/* The shell folds before the content does: below 980px the sidebar becomes a strip
   above the work area (the prototype's own break), and the top bar drops the company
   name because the switcher two rows above is already showing it. */
@media (max-width:980px){
  .app-shell,body:has(#workspace[hidden]) .app-shell{grid-template-columns:minmax(0,1fr)}
  .sidebar{gap:var(--space-16);padding:var(--space-16);border-inline-end:0;border-block-end:1px solid var(--color-border-default)}
  .shell-drawer{gap:var(--space-16)}
  .nav-count{margin-inline-start:0}
  .company-switch{padding-block:var(--space-12)}
  /* TICKET 153: seven entries take two rows of four, so the strip is no taller with the
     work-queue entry than it was with six entries in two rows of three. */
  #primary-nav{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--space-8)}
  .nav-item{justify-content:center;text-align:center;padding-inline:var(--space-8)}
  .sidebar-foot{flex-direction:row;flex-wrap:wrap;align-items:center;gap:var(--space-12);margin-block-start:0;padding-block-start:var(--space-12);border-block-start:1px solid var(--color-border-default)}
  .sidebar-foot .mini-label{flex-basis:100%}
  .sidebar-link,.sidebar-signout{inline-size:auto}
  .profile{padding-block-start:0;border-block-start:0}
  #active-company{display:none}
}
/* TICKET 153: on the tablet strip the count line sits at the end of the label's own line
   rather than under the select. Only here: on a phone the switcher is part of the
   phone's header row (the next block). */
@media (min-width:701px) and (max-width:980px){
  .company-switch{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:var(--space-12)}
  .company-switch>:not(.mini-label,.company-count){grid-column:1/-1}
  .company-switch>.company-count{grid-row:1;grid-column:2}
}
@media(max-width:700px){
  /* TICKET 153 (SB-19): the phone gutter is --space-16, and the page title --text-xxl. */
  main{padding:var(--space-24) var(--space-16) var(--space-44)}
  .page-heading h1{font-size:var(--text-xxl)}
  .page-heading{margin-block-end:var(--space-24)}
  .page-heading h1~p{font-size:var(--text-sm)}
  .page-heading h1+p{margin-block-start:var(--space-8)}
  .topbar{min-block-size:var(--size-48);padding:var(--space-2) var(--space-16)}
  .breadcrumb{font-size:var(--text-xs)}
  /* TICKET UX-PR (Group 2): Refresh is in the user menu now, with its word, at every width. */
  body{font-size:var(--text-md)}

  /* TICKET 153 (SB-01): the shell folds into ONE header row -- the brand mark, the
     company select, the receiving mark and the menu button -- with the switcher's search
     under it once the list is long enough to need one. Everything else the sidebar held
     is in the drawer the menu button opens. The switcher's own box gives up its layout
     (`display:contents`) so its select can share the row with the brand and the button. */
  .sidebar{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:var(--space-8) var(--space-10);padding:var(--space-12) var(--space-16)}
  .sidebar>.brand{grid-row:1;grid-column:1}
  .sidebar .brand-copy{display:none}
  .sidebar .brand-mark{inline-size:var(--size-36);block-size:var(--size-36);font-size:var(--text-md)}
  .company-switch{display:contents}
  .company-switch>.mini-label{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:-1px}
  .company-switch select{grid-row:1;grid-column:2;min-block-size:var(--size-44);padding-block:var(--space-6)}
  .company-search{grid-column:1/-1}
  /* The count line speaks while a search is typed; the rest of the time it is a status
     for a screen reader only, and the select two rows up already shows the company. */
  .company-count{grid-column:1/-1}
  .company-count:not([data-searching=true]){position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:-1px}
  /* The receiving mark: filled while receiving, a ring once stopped, a dashed ring while
     unknown, so the state is carried by shape as well as colour. Its words are the
     paragraph's own (sr-only) and the drawer's Connection block. */
  .shell-status{display:flex;align-items:center;justify-content:center;grid-row:1;grid-column:3;inline-size:var(--size-24);block-size:var(--size-24);margin:0}
  .shell-status .status-dot{inline-size:var(--space-10);block-size:var(--space-10);background:transparent;border:var(--size-hairline-strong) dashed var(--color-text-caption)}
  .shell-status[data-state=stopped] .status-dot{border-style:solid}
  .shell-status[data-state=running] .status-dot{border-style:solid;border-color:var(--color-feedback-success-text);background:var(--color-feedback-success-text)}
  .shell-status[data-state=interrupted] .status-dot{border-style:solid;border-radius:var(--radius-sm);border-color:var(--color-feedback-error-text);background:var(--color-feedback-error-text)}
  .shell-menu{display:inline-flex;grid-row:1;grid-column:4}

  /* The drawer: closed, it is not drawn; open, it is a panel over the page's end edge
     with a scrim behind it (app.js owns open, close, the focus trap and Escape). */
  .shell-drawer{display:none}
  body[data-drawer=open]{overflow:hidden}
  body[data-drawer=open] .shell-scrim{display:block;position:fixed;inset:0;z-index:var(--z-overlay);background:var(--color-text-primary);opacity:var(--opacity-disabled)}
  body[data-drawer=open] .shell-drawer{display:flex;position:fixed;inset-block:0;inset-inline-end:0;z-index:var(--z-modal);inline-size:min(calc(var(--space-64)*5),calc(100% - var(--space-48)));gap:var(--space-16);padding:var(--space-12) var(--space-16) var(--space-24);overflow-y:auto;overscroll-behavior:contain;background:var(--color-surface-card);border-inline-start:1px solid var(--color-border-default);box-shadow:var(--shadow-sm)}
  .shell-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-12);padding-block-end:var(--space-8);border-block-end:1px solid var(--color-border-default)}
  #primary-nav{display:flex;flex-direction:column;gap:var(--space-4)}
  .nav-item{justify-content:flex-start;text-align:start;padding-inline:var(--space-12);font-size:var(--text-base)}
  .nav-count{margin-inline-start:auto}
  .sidebar-foot{flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:var(--space-8);margin-block-start:auto;padding-block-start:var(--space-16)}
  .sidebar-foot .mini-label{flex-basis:auto}
  .sidebar-link,.sidebar-signout{inline-size:100%}
  .profile{padding-block:var(--space-12) 0;border-block-start:1px solid var(--color-border-default)}
  form{display:grid;grid-template-columns:1fr;width:100%}
  label,.wide{width:100%;min-width:0}
  form button{width:100%}
  .shortcuts,.dashboard-shortcuts{grid-template-columns:minmax(0,1fr)}
  .inspection{grid-template-columns:1fr}
  .inspection .wide{grid-column:auto}
  .wizard-intro,.telegram-states{padding-left:var(--space-14);padding-right:var(--space-14)}
  .telegram-states{grid-template-columns:1fr}
  .step-progress{margin-inline:var(--space-14)}
  .step-progress li,.step-progress li[data-state=current]{font-size:0;min-height:12px;padding:0} /* ds-allow-hardcode: collapsed progress rail marker height, decorative not thematic */
  .table-scroll{margin-inline:0}
  footer{padding:var(--space-20) var(--space-16)}
  .bi-charts{grid-template-columns:1fr}
  .bi-tiles dd[data-metric=expected_satang]{font-size:var(--text-lg)}
}
@media(max-width:380px){
  button{white-space:normal;max-width:100%}
  .card-actions button,.card-actions .btn{flex:1 1 100%;max-width:100%}
  form button{max-width:100%}
}

/* TICKET 157 (SI-01): the settings rail's numbered marks (`.rail-n`, `.rail-link`, `.rail-text`,
   `.rail-t`, `.rail-s`, `.rail-more`) went with the rail. */

/* TICKET 132: the settings hub -- `.hub-row`/`.hub-mark`/`.hub-text`/`.hub-lock` (one
   row per pipeline step) and `.hub-tiles`/`.hub-tile`/`.hub-foot` (the four figures
   above them) -- is retired with the hub's own view container. What each showed is accounted
   for on the ticket's report; nothing here replaces them, because nothing on this
   panel shows them a second time. The table-sizing rule below lost the same view's
   two table ids (`#settings-team-table`, `#rejected-slips-table`) and, with them,
   `#recent-transactions-table`, which had named no element in this document since
   ticket 107 and is not carried forward. */

/* The page owns its title now, so the card beneath must not repeat it. The heading
   stays in the markup for anything that reads the document outline; it is the
   duplicate rendering that the design does not have. */
#telegram-wizard>header,#sheets-details>header,#moneyos-intake-details>header,
#recovery-audit-details>header,#users-details>header,#config-details>header,#expected-details>header{display:none}
/* An empty scroller is not a table. */
.table-scroll:empty{display:none}

/* TICKET 153 (SB-19): the settings pages' own title size (--text-xxl on a 1.15 line,
   after the phase-1 design canvas) is retired. Design A gives every page the same title,
   so the settings pages borrow the page `h1` above like the rest. */

/* TICKET 157 (SI-01, SI-10): the panel is one full-width settings page at a time, and
   `.step-nav` (the Back/Continue pair under the account cards) is gone with the rail it
   walked. */

/* TICKET 119: the Start-receiving page's review (`.start-review`, `.review-row`,
   `.start-go`, `.step-lede`) is the setup's own step 4 now, in `page-intake-setup.css`. */

/* A closed disclosure must actually hide its content. The UA does this, but an author
   display rule on a child (form is flex here) overrides it, so the fields of a collapsed
   section stayed on the page and only looked put away. */
details:not([open])>*:not(summary){display:none}

/* The rehearsal notices belong to a synthetic stage. A live stage records real money and
   must not carry a banner saying it does not. */
body[data-stage="live"] [data-synthetic-note]{display:none}


/* ===== TICKET 183 BEGIN: a tab opened before a deploy knows it is old ==================
   The one quiet bar `build-check.js` fills when the server serves a newer build of this
   page. Both pages load this file and that script, so the bar is one look on both. It is
   in the page from the start with nothing in it and takes no room, so its live region
   exists before its sentence does; it is a NOTICE, the same family as the live update's
   offline line, never an error. Every value is a token. */
.build-bar{display:flex;align-items:center;gap:var(--space-12);
  padding:var(--space-8) var(--space-28);background:var(--color-feedback-hold-bg);
  color:var(--color-feedback-hold-text);border-block-end:1px solid var(--color-border-lead)}
.build-bar:not([data-stale]){padding:0;border:0}
.build-bar .icon{flex:0 0 auto}
/* The sentence and its button read as one line, side by side, not at the two ends of a wide
   screen; `p`'s measure is not this line's to keep. */
.build-bar-text{flex:0 1 auto;min-inline-size:0;max-width:none;margin:0;font-size:var(--text-sm);
  font-weight:var(--weight-semibold);color:inherit;line-height:var(--leading-normal)}
.build-bar-reload{flex:0 0 auto;display:inline-flex;align-items:center;gap:var(--space-8);
  min-block-size:var(--size-36);padding-block:var(--space-4);font-size:var(--text-sm)}
/* On a phone the sentence wraps beside its button rather than the button dropping a line. */
@media (max-width: 48rem){
  .build-bar[data-stale]{padding-inline:var(--space-16)}
}
/* ===== TICKET 183 END ================================================================== */
/* ===== TICKET 226 ======================================================================
   The eighth sidebar entry ("ตรวจสอบรายการถอน") costs the desk's column one 44-pixel row. On a
   desk 959 pixels high or less the column's rhythm tightens by one step, so the receiving
   state, the profile and sign-out still sit in the first screen (ticket 153's rule, SB-13):
   the gaps between the column's blocks 24 to 16, between entries 4 to 2, and the company
   block's padding 16 to 12. No entry gets shorter than its 44-pixel target; a taller desk is
   unchanged. */
@media (min-width:981px) and (max-height:959px){
  .sidebar,.shell-drawer{gap:var(--space-16)}
  #primary-nav{gap:var(--space-2)}
  .company-switch{padding-block:var(--space-12)}
}
/* ===== TICKET 226 END ================================================================== */
/* ===== TICKET 238 ======================================================================
   The ninth sidebar entry ("บันทึกเงินเข้า") costs the column another 46-pixel row: with twelve
   companies (the company search shows) sign-out ended at 938 pixels on a 900-high desk. On the
   same short desk the column tightens one more step: the gaps between its blocks 16 to 12, its
   top and bottom padding 24 to 16, and the footer's rows 10 to 4. No entry or control gets
   shorter than its 44-pixel target; a taller desk is unchanged. */
@media (min-width:981px) and (max-height:959px){
  .sidebar,.shell-drawer{gap:var(--space-12)}
  .sidebar{padding-block:var(--space-16)}
  .sidebar-foot{gap:var(--space-4)}
}
/* ===== TICKET 238 END ================================================================== */
/* ===== TICKET 260 ======================================================================
   The tenth sidebar entry ("ค่าใช้จ่าย") costs the column another 46-pixel row: with twelve companies
   sign-out ended at 940 pixels on a 900-high desk. On the same short desk the column tightens one more
   step, as tickets 226 and 238 did: the entries sit edge to edge (2 to 0), the gaps between its blocks
   12 to 8, its top and bottom padding 16 to 12, and the company block's padding 12 to 8 and its rows 8 to
   4. No entry or control gets shorter than its 44-pixel target; a taller desk is unchanged. */
@media (min-width:981px) and (max-height:959px){
  #primary-nav{gap:0}
  .sidebar,.shell-drawer{gap:var(--space-8)}
  .sidebar{padding-block:var(--space-12)}
  .company-switch{padding-block:var(--space-8);gap:var(--space-4)}
}
/* ===== TICKET 260 END ================================================================== */
/* ===== TICKET 261 ======================================================================
   The eleventh sidebar entry ("ส่งมอบงาน") costs the column another 44-pixel row: with twelve companies sign-out
   ended at 931 pixels on a 900-high desk (measured), and the gaps tickets 226, 238 and 260 tightened are spent.
   On the same short desk two captions leave the eye and stay for a screen reader (the `.sr-only` rule): the
   brand's tagline under "MoneyOS", and the foot's "Connection" caption, whose receiving state below it says
   itself in words. The profile's top padding goes 12 to 8. No entry or control gets shorter than its 44-pixel
   target, nothing a person can act on is hidden, and a taller desk is unchanged. */
@media (min-width:981px) and (max-height:959px){
  .sidebar .brand-sub,.sidebar-foot>.mini-label:first-child{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;padding:0;margin:-1px}
  .sidebar .profile{padding-block-start:var(--space-8)}
}
/* ===== TICKET 261 END ================================================================== */

/* --- TICKET UX-PR (the production review's F06): one tab component for every page -------------------------------
   The owner's mockup: the chosen tab in the primary green with a green indicator under it; the others secondary.
   The withdrawal review, expenses, top-ups, all accounts, the overview and settings all wear these two classes
   (their own classes keep only where the row sits). The row's hairline is drawn INSIDE the row (an inset shadow)
   and no tab reaches below it, so a row that may scroll sideways on a narrow screen never overflows by a pixel
   downwards: the small vertical scrollbar the review saw came from each tab's negative bottom margin inside an
   `overflow-x: auto` row (whose other axis is then `auto` too). Nothing is clipped or hidden to remove it. */
.app-tabs{display:flex;gap:var(--space-4);margin:0 0 var(--space-20);padding:0;overflow-x:auto;
  box-shadow:inset 0 -1px 0 var(--color-border-default)}
.app-tab{flex:0 0 auto;min-height:var(--size-44);margin:0;padding:var(--space-8) var(--space-16);background:transparent;border:0;
  border-block-end:var(--size-hairline-strong) solid transparent;border-radius:0;color:var(--color-text-secondary);
  font-weight:var(--weight-medium);white-space:nowrap}
.app-tab:hover{background:var(--color-action-ghost-hover);border-color:transparent;color:var(--color-text-primary)}
.app-tab:active{background:var(--color-action-ghost-hover);transform:none}
.app-tab[aria-selected=true]{border-block-end-color:var(--color-action-primary);color:var(--color-action-primary);font-weight:var(--weight-semibold)}
.app-tab[aria-selected=true]:hover{border-block-end-color:var(--color-action-primary);color:var(--color-action-primary-hover)}
.app-tab:focus-visible{outline-offset:calc(-1 * var(--space-2))}
.app-tab:disabled{background:transparent}

/* --- TICKET UX-PR (F07): the switch that shows the whole account numbers, for a role that may see them ------------ */
.account-reveal{min-height:var(--size-44)}
.account-reveal[aria-pressed=true] .icon{color:var(--color-action-primary)}

/* --- TICKET UX-PR (the owner's Group 2): the shell as the mockup draws it ----------------------------------------
   The user block is a button that opens a small menu above it (the language, Refresh and, for a role that may see
   them, the switch for the whole account numbers), so the top bar keeps the company, "ทุกบริษัท" and the bell. The
   menu floats over the sidebar and never lengthens it; on a phone it is part of the drawer. The settings page's
   tabs are the one tab component. The alert centre is an entry of the menu, beside the others. */
.user-block{position:relative;min-inline-size:0}
.user-block>.profile{inline-size:100%;min-block-size:var(--size-48);margin:0;padding:var(--space-8) var(--space-8) var(--space-8) 0;
  background:transparent;border:0;border-block-start:1px solid var(--color-border-default);border-radius:0;color:var(--color-text-primary);
  font-weight:var(--weight-regular);text-align:start;white-space:normal}
.user-block>.profile:hover{background:var(--color-action-ghost-hover)}
.user-block>.profile:active{transform:none}
.user-block>.profile .profile-copy{flex:1 1 auto}
.user-menu-chevron{flex:0 0 auto;color:var(--color-text-secondary);transition:transform var(--duration-fast) var(--ease-standard)}
.user-block>.profile[aria-expanded=false] .user-menu-chevron{transform:rotate(180deg)}
.user-menu{position:absolute;inset-inline:0;inset-block-end:calc(100% + var(--space-4));z-index:var(--z-tooltip);display:grid;gap:var(--space-8);
  padding:var(--space-12);background:var(--color-surface-card);border:1px solid var(--color-border-default);border-radius:var(--radius-card);
  box-shadow:var(--shadow-sm)}
.user-menu-row{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--space-8);min-inline-size:0}
.user-menu-row .mini-label{margin:0}
.user-menu-item{display:inline-flex;align-items:center;justify-content:flex-start;gap:var(--space-8);inline-size:100%}
.user-menu .account-reveal{justify-content:flex-start;padding-inline:0}
.settings-tabs{margin-block:calc(-1 * var(--space-8)) var(--space-24)}
@media (prefers-reduced-motion: reduce){
  .user-menu-chevron{transition:none}
}

/* ===== TICKET 267 (the owner's mockup, 19 ต.ค. 2026): the shell, every page's frame ==================================
   The sidebar, the top bar, the user block and the phone menu as `moneyos-ux-review-mockup.html` draws them, laid over
   the rules above (later and of the same weight, so each wins where it says something). Every value is a token.
   - The sidebar: 14rem of the 64-step (three steps and a 32), the brand's mark at 36 on the control radius, its line
     in the caption's case, the company's label in the mockup's words and weight, no rules round the company block,
     and the entry on screen on the selected surface with a short primary bar at its start, as the mockup's track.
   - The user block at the foot: the name, the role and "ดูแลระบบ"; the menu it opens holds the language, Refresh,
     the numbers switch, the receiving state and sign-out (index.html says why the receiving state is there).
   - The top bar: the company and "บริษัทนี้" at the start (or "ระดับระบบ" and "ทุกบริษัท"), "ทุกบริษัท" with its
     building and the bell at the end. The breadcrumb leaves the eye and stays for a screen reader.
   - Every page's heading is the mockup's: the title at --text-xxl in bold on a line Thai marks fit in, its line under
     it in the secondary ink.
   - At the phone width the sidebar is not drawn; the top bar is the mockup's phone bar (the menu button, the company,
     the building, the bell) and the menu opens from the start edge with the whole sidebar in it. */
@media (min-width:981px){
  .app-shell{grid-template-columns:calc(var(--space-64)*3 + var(--space-32)) minmax(0,1fr)}
  /* The mockup's rhythm on every desk height: the receiving state and sign-out left the foot, so the column has
     the room tickets 226, 238, 260 and 261 took back on a short desk, and the brand's line is drawn again. */
  .sidebar,.sidebar{gap:var(--space-24);padding:var(--space-24) var(--space-12)}
  .shell-drawer{gap:var(--space-24)}
  #primary-nav{gap:var(--space-4)}
  .sidebar .brand-sub{position:static;inline-size:auto;block-size:auto;overflow:visible;clip-path:none;white-space:normal;margin:0}
  .nav-item{gap:var(--space-10);padding:var(--space-12)}
}
.sidebar .brand{gap:var(--space-10);padding-inline:var(--space-8)}
.brand-mark{inline-size:var(--size-36);block-size:var(--size-36);border-radius:var(--radius-control);font-size:var(--text-lg)}
.brand-sub{font-size:var(--text-xs);font-weight:var(--weight-regular);letter-spacing:normal;text-transform:none;color:var(--color-text-secondary)}
.company-switch{gap:var(--space-8);padding:0 var(--space-8);border-block:0}
.company-switch>.mini-label{font-size:var(--text-xs);font-weight:var(--weight-medium);letter-spacing:normal;text-transform:none;color:var(--color-text-secondary)}
.company-switch select{min-block-size:var(--size-40);font-weight:var(--weight-regular)}
/* The count line is a status for a screen reader, and on screen only while a search is typed (the mockup has none). */
.company-count:not([data-searching=true]){position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:-1px}
.nav-item{position:relative;font-size:var(--text-sm)}
.nav-item[aria-current=page]{border-radius:var(--radius-card)}
.nav-item[aria-current=page]::before{content:'';position:absolute;inset-inline-start:0;inset-block:25%;inline-size:var(--space-2);border-radius:var(--radius-pill);background:var(--color-action-primary)}
.sidebar-foot{gap:var(--space-8)}
.user-block{display:grid;gap:var(--space-4);padding-block-start:var(--space-16);border-block-start:1px solid var(--color-border-default)}
.user-block>.profile{min-block-size:var(--size-44);padding:var(--space-4) var(--space-8);border-block-start:0;border-radius:var(--radius-control)}
.user-block .avatar{display:none}
.user-block .profile-name{font-size:var(--text-base)}
.shell-backoffice{display:inline-flex;align-items:center;justify-self:start;min-block-size:var(--size-36);padding:var(--space-4) var(--space-8);border-radius:var(--radius-control);color:var(--color-text-link);font-size:var(--text-xs);font-weight:var(--weight-medium);text-decoration:none}
.shell-backoffice:hover{background:var(--color-surface-selected)}
.shell-backoffice[hidden]{display:none}
.user-menu-status{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:var(--space-8);margin:0;font-size:var(--text-xs)}
.user-menu-status .user-menu-status-label{grid-column:2;font-weight:var(--weight-medium);color:var(--color-text-secondary)}
.user-menu-status #intake-status-text{grid-column:2}
.user-menu-status .status-dot{grid-row:1 / span 2;grid-column:1}
.user-menu .sidebar-signout{min-block-size:var(--size-44)}
.topbar{justify-content:space-between;gap:var(--space-12);padding:var(--space-12) var(--space-28)}
.topbar-scope{display:flex;align-items:center;gap:var(--space-12);min-inline-size:0;margin:0;max-inline-size:none}
.topbar-scope .active-company{font-size:var(--text-xs);font-weight:var(--weight-regular);color:var(--color-text-secondary);overflow-wrap:anywhere}
.topbar-chip{flex:0 0 auto;padding:var(--space-4) var(--space-8);border-radius:var(--radius-sm);background:var(--color-surface-sunken);font-size:var(--text-xs);color:var(--color-text-primary);white-space:nowrap}
body:has(#workspace[hidden]) .topbar-scope,body:has(#workspace[hidden]) #scope-entry,body:has(#workspace[hidden]) #shell-menu{display:none}
.breadcrumb{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:-1px}
.top-actions{gap:var(--space-12)}
.scope-entry{inline-size:auto;min-block-size:var(--size-40);padding:var(--space-8) var(--space-8);gap:var(--space-8);color:var(--color-text-link);font-size:var(--text-xs);font-weight:var(--weight-medium)}
.scope-entry:hover{background:var(--color-surface-selected);color:var(--color-text-link)}
.scope-entry[aria-current=page]{background:var(--color-surface-selected);color:var(--color-text-link)}
.scope-entry[aria-current=page]::before{display:none}
.notify-top{min-block-size:var(--size-40)}
.page-heading h1{font-size:var(--text-xxl);font-weight:var(--weight-bold);line-height:var(--leading-normal)}
.page-heading h1~p{color:var(--color-text-secondary)}
@media (max-width:980px){
  .sidebar{padding:var(--space-16)}
  .user-block{padding-block-start:0;border-block-start:0}
  .topbar-scope .active-company{display:none}
}
@media (max-width:700px){
  .sidebar{display:block;padding:0;border:0;block-size:0}
  /* The sidebar is an empty row at this width, so the column takes the rest of a short page (it would otherwise share
     the spare height with the empty row and start lower down). */
  .app-shell{grid-template-rows:auto minmax(0,1fr)}
  .topbar{flex-wrap:nowrap;min-block-size:var(--size-64);padding:var(--space-12) var(--space-16);gap:var(--space-8)}
  .shell-menu{display:inline-flex;flex:0 0 auto;inline-size:var(--size-40);block-size:var(--size-40);order:-1}
  .topbar-scope{flex:1 1 auto;gap:var(--space-8)}
  .topbar-scope :is(#active-company,#topbar-system){display:block;max-inline-size:calc(var(--space-40)*4);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .topbar-chip{display:none}
  .top-actions{flex:0 0 auto;flex-wrap:nowrap;gap:var(--space-8);margin-inline-start:0}
  .scope-entry{min-inline-size:var(--size-40);justify-content:center;padding-inline:var(--space-8)}
  .scope-entry-label{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:-1px}
  body[data-drawer=open] .shell-drawer{inset-inline-start:0;inset-inline-end:auto;inline-size:min(85%,calc(var(--space-64)*3 + var(--space-32)));
    gap:var(--space-20);padding:var(--space-12) var(--space-12) var(--space-24);border-inline-start:0;border-inline-end:1px solid var(--color-border-default)}
  .sidebar .brand-copy{display:flex}
  .company-switch{display:flex;padding:0 var(--space-8)}
  .company-switch>.mini-label{position:static;inline-size:auto;block-size:auto;overflow:visible;clip-path:none;white-space:normal;margin:0}
  .company-switch select{grid-row:auto;grid-column:auto}
  .user-block{padding-block-start:var(--space-16);border-block-start:1px solid var(--color-border-default)}
}
/* ===== TICKET 267 END ================================================================================================ */
/* ===== TICKET 264 ======================================================================
   The twelfth sidebar entry ("รูปยอดรอตรวจ", where the owner's mockup puts it) costs the column another 47-pixel row:
   "ดูแลระบบ" ended at 919 pixels on a 900-high desk with twelve companies (measured,
   `test_the_shell_matches_design_a_browser.py`). On a desk 959 pixels high or less each entry's padding goes 12 to 10
   above and below (ticket 267's rhythm, which this block follows and overrides only there); its 44-pixel target is
   its `min-block-size` and does not move, so no entry gets shorter than that, and a taller desk is unchanged. */
@media (min-width:981px) and (max-height:959px){
  .nav-item{padding-block:var(--space-10)}
}
/* ===== TICKET 264 END ================================================================== */
