/* Dryvera operations dashboard: the original dashboard's layout (a Dark Azure sidebar with the section tabs, a Light
   Tan page, white rounded cards, the "Portfolio" bar with the signed-in person) in the website's design system (Sora,
   the five brand colours, 5 px buttons in Dark Green with a Light Tan edge, small uppercase Arial labels, pill tags,
   amber only for risk and errors). Never green for a status; grey hatching for "unavailable". Every page reads
   without JavaScript; focus is always visible. */

/* Sora, the website's typeface (components/home/fonts: the same variable file, weights 100-800, OFL 1.1). */
@font-face {
  font-family: "Sora";
  src: url("fonts/sora-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* The brand palette (as on the website, app/globals.css). */
  --dark-blue: #011638;
  --dark-azure: #14212b;
  --dark-green: #3c571d;
  --light-tan: #e4dfdb;
  --lighter-tan: #f3f1ef;
  --white: #ffffff;
  /* Mixed from the palette as the website does: accent text and focus on the dark grounds, the primary's hover. */
  --green-accent: #a7b399;
  --green-accent-scene: #c1c9b7;
  --green-hover: #536b38;
  /* Amber, the one functional colour (risk and errors): the website's #e9b45a, deepened for text on light grounds
     (amber 44 % + black, 6.5:1 on its tint) and mixed with white for the tag grounds. */
  --amber: #e9b45a;
  --amber-ink: #674f28;
  --amber-bg: #f9ead1;
  --amber-strong-bg: #f3d6a4;
  --amber-strong-ink: #4a3818;
  /* Text on the light grounds: navy, and the website's light-ground muted (Dark Blue 70 % over Lighter Tan). */
  --ink: var(--dark-blue);
  --ink-muted: #4a586f;
  --line: #d6cfc9;
  --hairline: rgba(1, 22, 56, 0.14);
  /* "Unavailable": derived from the palette (ink = Dark Azure 75 % over white, 7:1 on white and 5.6:1 on its ground;
     ground = Light Tan 80 % over Lighter Tan), always with hatching or a dashed mark so it never reads as calm. */
  --unavailable-bg: #e7e3df;
  --unavailable-ink: #4f5960;
  /* Errors on the light grounds: the brand pair plus the word "Error:" (never a colour alone). */
  --danger-ink: var(--dark-blue);
  --danger-bg: var(--white);
  --radius: 5px;
  --radius-card: 16px;
  --shadow: 0 1px 2px rgba(1, 22, 56, 0.04);
  --font: "Sora", "Helvetica Neue", Arial, sans-serif;
  --font-label: Arial, Helvetica, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --gutter: 16px;
  --max: 1240px;
  --sidebar: 288px;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html { font-size: 100%; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 400;
  line-height: 1.55;
  color: var(--ink);
  background: var(--light-tan);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; }

/* Links as on the website's light grounds (components/site/util.module.css .docLink): Dark Green (8.2:1 on white,
   6.2:1 on Light Tan) with a 1 px underline, navy on hover, eased over 0.6 s. A link that names a room or a building
   carries class "place" and stays navy, like a title, also on hover (its underline thickens instead), so no green word
   ever sits beside a room's state: green is never a status. */
a {
  color: var(--dark-green); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
  transition: color 0.6s var(--ease-out), background-color 0.6s var(--ease-out), text-decoration-color 0.6s var(--ease-out),
    text-decoration-thickness 0.6s var(--ease-out);
}
a:hover { color: var(--dark-blue); }
.place, .place:hover { color: var(--dark-blue); }
.place:hover { text-decoration-thickness: 2px; }

:focus { outline: none; }
/* Focus as on the website's light grounds (Dark Green ring, offset); the dark grounds use the pale green ring. Links
   and buttons take rounded rings; fields keep their own corners (:where keeps the rule at (0,1,0), so the round
   controls and the buttons keep theirs too). */
:focus-visible { outline: 2px solid var(--dark-green); outline-offset: 3px; }
:focus-visible:not(:where(input, select, textarea)) { border-radius: 4px; }
.sidebar :focus-visible, body.public :focus-visible { outline-color: var(--green-accent-scene); }
/* The wordmark link fills the top of the sidebar, whose scroll box would cut an outside ring: on wide screens it is
   drawn inside the Dark Azure box (the tabs keep theirs outside: inside, it would vanish on the current tab's band). */
@media (min-width: 900px) { .sidebar-brand:focus-visible { outline-offset: -4px; } }

.skip-link {
  position: absolute; left: 8px; top: 8px; z-index: 100; transform: translateY(-200%);
  background: var(--dark-blue); color: var(--lighter-tan); padding: 10px 16px; border-radius: var(--radius); font-weight: 600;
  transition: transform 120ms ease;
}
.skip-link:hover { color: var(--lighter-tan); } /* never the links' navy hover on its own navy ground */
.skip-link:focus { transform: none; }
.skip-link:focus-visible { outline-color: var(--green-accent-scene); } /* it shows over the Dark Azure sidebar */

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* The website's Sora scale (components/site/ui.module.css): 400 for titles and card titles (h1 at the light-ground
   title's -0.022em), 300 for figures, 500 for buttons and labels, 600 only for strong emphasis over the 400 body. */
h1, h2, h3, h4 { color: var(--dark-blue); line-height: 1.25; margin: 0 0 0.5em; font-weight: 400; letter-spacing: -0.02em; text-wrap: balance; }
h1 { font-size: 1.55rem; letter-spacing: -0.022em; }
h2 { font-size: 1.15rem; margin-top: 0; }
h3 { font-size: 1rem; letter-spacing: -0.01em; }
p { margin: 0 0 0.75em; }
strong { font-weight: 600; }
.muted { color: var(--ink-muted); }
.lead { font-size: 1.02rem; max-width: 72ch; color: var(--ink); }
code { font-family: var(--mono); font-size: 0.9em; }

/* ── the application shell: sidebar + main column (signed in) ───────────────────────────────────────────── */

.shell { display: grid; grid-template-columns: var(--sidebar) minmax(0, 1fr); min-height: 100vh;
  /* The sidebar's column stays Dark Azure below the sticky sidebar on long pages. */
  background: linear-gradient(to right, var(--dark-azure) var(--sidebar), transparent var(--sidebar)); }
.shell-main { display: flex; flex-direction: column; min-width: 0; }

.sidebar {
  position: sticky; top: 0; align-self: start; height: 100vh; overflow-y: auto;
  display: flex; flex-direction: column; background: var(--dark-azure); color: var(--lighter-tan);
}
.sidebar-brand {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 32px 24px 30px;
  color: var(--lighter-tan); text-decoration: none;
}
/* The website's own wordmark (public/placeholders/29.png, cropped): "Dry" in Light Tan and "vera" in white, made for
   dark grounds, so it is shown as drawn, as in the website's navigation pill. */
.sidebar-brand img { height: 38px; width: auto; }
.sidebar-sub { font: 400 0.68rem/1 var(--font-label); letter-spacing: 0.16em; text-transform: uppercase; color: var(--green-accent); }
.sidebar-nav ul, .sidebar-foot ul { list-style: none; margin: 0; padding: 0; }
.sidebar-nav { flex: 1; padding: 6px 0 18px; }
.nav-link {
  display: flex; align-items: center; gap: 14px; padding: 12px 28px; color: rgba(243, 241, 239, 0.86);
  text-decoration: none; font-size: 1.02rem; font-weight: 500; letter-spacing: -0.01em;
  transition: background-color 0.6s var(--ease-out), color 0.6s var(--ease-out);
}
.nav-link:hover { background: rgba(243, 241, 239, 0.06); color: var(--lighter-tan); }
/* The current tab: a Light Tan band edge to edge with Dark Green text (6.2:1), as in the original. */
.nav-link[aria-current="page"] { background: var(--light-tan); color: var(--dark-green); }
/* Every icon sits in a 36 px circle (20 px + 8 px padding, cancelled by negative margins so the rows and labels keep
   their alignment); the current tab fills it Dark Azure with a Lighter Tan stroke, as in the original. */
.nav-icon { width: 20px; height: 20px; flex: none; box-sizing: content-box; padding: 8px; margin: -8px -2px -8px -8px; border-radius: 50%; }
.nav-link[aria-current="page"] .nav-icon { background: var(--dark-azure); color: var(--lighter-tan); }
.sidebar-foot { padding: 14px 0 26px; }
.sidebar-foot::before { content: ""; display: block; height: 1px; margin: 0 28px 14px; background: rgba(243, 241, 239, 0.32); }
.sidebar-foot .nav-link { font-size: 0.98rem; padding-top: 10px; padding-bottom: 10px; }
.sidebar-foot form { margin: 0; }
.sidebar-foot button.nav-link { width: 100%; border: 0; background: transparent; font: inherit; font-size: 0.98rem; font-weight: 500; cursor: pointer; text-align: left; }

/* The bar above every page: "Portfolio: <organization>", search, alerts and the signed-in person. */
.appbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; padding: 26px 40px 10px;
}
.appbar-portfolio { margin: 0 auto 0 0; font-size: 1.45rem; font-weight: 500; color: var(--dark-blue); letter-spacing: -0.02em; display: flex; align-items: center; gap: 10px; }
.appbar-portfolio .appbar-label { font-weight: 500; }
/* Every hover eases over 0.6 s, as on the website (the reduced-motion block at the end turns it off). */
.appbar-switch, .appbar-search-submit, .appbar-icon, .card-more {
  transition: color 0.6s var(--ease-out), background-color 0.6s var(--ease-out);
}
.appbar-switch { display: inline-flex; color: var(--dark-blue); }
.appbar-switch svg { width: 22px; height: 22px; }
.appbar-switch:hover, .appbar-icon:hover { color: var(--dark-green); }
.appbar-search { position: relative; display: flex; align-items: center; flex: 0 1 220px; min-width: 0; }
/* The Dark Green magnifier is the form's submit button, inside the pill on the left. */
.appbar-search-submit {
  position: absolute; left: 6px; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; padding: 0; border: 0;
  border-radius: 50%; background: transparent; color: var(--dark-green); cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.appbar-search-submit:hover { background: var(--lighter-tan); }
.appbar-search-submit svg { width: 18px; height: 18px; }
.appbar-search input[type="search"] {
  /* The original's white pill, with the inputs' edge so the field stands out from the tan page (4.4:1, WCAG 1.4.11). */
  width: 100%; height: 40px; padding: 0 16px 0 42px; border: 1px solid rgba(1, 22, 56, 0.6); border-radius: 999px;
  background: var(--white); color: var(--ink); font: inherit; font-size: 0.9rem; box-shadow: var(--shadow);
}
.appbar-search input[type="search"]::placeholder { color: var(--ink-muted); }
.appbar-actions { display: flex; align-items: center; gap: 16px; }
.appbar-icon { display: inline-flex; color: var(--dark-azure); padding: 6px; border-radius: 999px; }
.appbar-icon svg { width: 24px; height: 24px; }
.appbar-user { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.25; }
.appbar-user-name { font-weight: 500; font-size: 0.98rem; color: var(--dark-blue); }
.appbar-user-role { font-size: 0.82rem; color: var(--ink-muted); }
.appbar-user .acting { font-size: 0.78rem; color: var(--ink-muted); }
.avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--dark-green); color: var(--lighter-tan); font-weight: 500; font-size: 0.95rem; letter-spacing: 0.02em;
  box-shadow: inset 0 0 0 1px var(--light-tan);
}

.page {
  width: 100%; max-width: var(--max); margin: 0 auto; padding: 14px 40px 40px; flex: 1;
  min-width: 0; overflow-wrap: anywhere; /* a 64-hex hash or a long address never widens the page */
}
.page:focus { outline: none; }

/* ── signed-out pages (sign in, first run, invitations): the website's navy ground and glass ─────────────── */

body.public { background: var(--dark-blue); color: var(--lighter-tan); }
.public-shell { min-height: 100vh; display: flex; flex-direction: column; }
.public-head { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 40px 16px 8px; }
.public-head a { display: inline-flex; flex-direction: column; align-items: center; gap: 8px; text-decoration: none; color: var(--lighter-tan); }
.public-head img { height: 44px; width: auto; }
/* Forced colours (Windows high contrast) may replace the dark grounds with a light system colour, and the wordmark is
   light: keep it on a navy backplate, as the website's navigation does. */
@media (forced-colors: active) {
  .sidebar-brand img, .public-head img { forced-color-adjust: none; background: var(--dark-blue); border-radius: 6px; padding: 4px 8px; box-sizing: content-box; }
}
.public-head .sidebar-sub { color: var(--green-accent); }
/* The sign-in, first-run and invitation cards carry the label as their chip, so the header shows the wordmark alone. */
body.page-auth .public-head .sidebar-sub { display: none; }
body.public .page { max-width: 592px; padding: 24px 16px 48px; }
/* The website's login card (app/login/page.tsx: ui.glass + ui.glassStrong + ui.notched + util.loginCard): the strong
   glass, 20 px corners with the top-right corner cut by 22 px (the clip cuts the edge too, so ::after draws the 1 px
   diagonal back in), 560 px wide, padding clamp(28px, 4vw, 52px). */
body.public .card {
  position: relative; background: rgba(8, 21, 40, 0.8); border: 1px solid rgba(243, 241, 239, 0.16); border-radius: 20px;
  border-top-right-radius: 0; clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 0 100%);
  box-shadow: inset 0 1px 0 rgba(243, 241, 239, 0.08), 0 20px 60px rgba(1, 22, 56, 0.35); color: var(--lighter-tan);
  padding: clamp(28px, 4vw, 52px);
}
body.public .card::after {
  content: ""; position: absolute; top: -1px; left: calc(100% - 21px); width: 31.2px; height: 2px; pointer-events: none;
  background: rgba(243, 241, 239, 0.16); transform: rotate(45deg) translateY(-1px); transform-origin: 0 0;
}
/* Forced colours (Windows high contrast) replace backgrounds, so the redrawn diagonal vanishes while the clip still
   cuts the frame: there the card keeps a closed frame, its top-right corner rounded like the others. */
@media (forced-colors: active) {
  body.public .card { clip-path: none; border-top-right-radius: 20px; }
  body.public .card::after { display: none; }
}
/* The website's chip (ui.module.css .chip): Light Tan on Dark Green (8.7:1), a pale green edge and point. A label, not
   a status. Compound, so the card's paragraph rule below does not reach its font. */
body.public .card .chip {
  display: inline-flex; align-items: center; gap: 10px; margin: 0 0 22px; padding: 9px 14px; border-radius: 999px;
  color: var(--light-tan); background: rgba(60, 87, 29, 0.62); border: 1px solid rgba(167, 179, 153, 0.4);
  font: 400 0.7rem/1 var(--font-label); letter-spacing: 0.07em; text-transform: uppercase;
}
body.public .card .chip::before {
  content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--green-accent);
  box-shadow: 0 0 0 3px rgba(60, 87, 29, 0.55), 0 0 10px rgba(167, 179, 153, 0.7);
}
body.public h1, body.public h2 { color: var(--lighter-tan); font-weight: 300; }
body.public h1 { font-size: 2rem; letter-spacing: -0.03em; }
/* The login card's title (util.module.css .loginTitle): light and large, 66.56 px at 1280 px, 41.6 px on a phone. The
   first-run and invitation titles are sentences: the same light display face, one step smaller. */
body.public.page-auth .card h1 { font-size: clamp(2rem, 3.6vw, 2.75rem); line-height: 1.04; letter-spacing: -0.04em; margin-bottom: 18px; }
body.public.page-signin .card h1 { font-size: clamp(2.6rem, 5.2vw, 4.4rem); line-height: 0.96; letter-spacing: -0.045em; }
body.public a { color: var(--green-accent); }
body.public a:hover { color: var(--lighter-tan); }
body.public .muted, body.public .help { color: rgba(243, 241, 239, 0.78); }
/* The card's text as the website's (util.module.css .loginBody): Sora 300 at 80 % Lighter Tan (11:1 on the glass). */
body.public .card p { font-weight: 300; font-size: 1rem; line-height: 1.6; color: rgba(243, 241, 239, 0.8); }
/* Below the button: a hairline (ui.module.css .hairline), the note, and the way to ask for access (util.module.css
   .helpLink: 0.95rem, the arrow slides on hover). */
body.public .card .card-rule { display: block; height: 1px; margin: 26px 0 18px; background: rgba(243, 241, 239, 0.12); }
body.public .card .card-rule + p { font-size: 0.95rem; line-height: 1.5; }
body.public .card .access { margin: 12px 0 0; }
/* Inline, so on a phone the arrow follows the last word when the line wraps; the padding keeps a 24 px target. */
body.public .access-link {
  display: inline; padding-block: 4px; text-decoration: none;
  color: rgba(243, 241, 239, 0.8); font-size: 0.95rem; line-height: 1.3; font-weight: 300;
}
body.public .access-link .button-arrow { display: inline-block; margin-left: 10px; vertical-align: -0.14em; }
body.public .access-tail { white-space: nowrap; }
body.public .access-link:hover { color: var(--green-accent); }
body.public .access-link:hover .button-arrow { transform: translateX(3px); }
/* The website's form (app/globals.css .field): uppercase Arial labels in the muted grey, 48 px fields with 10 px
   corners and a border at 3:1 or more against the glass (rgba 0.5). Buttons keep their 5 px corners. */
body.public label { font: 400 0.72rem/1.3 var(--font-label); letter-spacing: 0.08em; text-transform: uppercase; color: #aaafb8; }
body.public input[type="text"], body.public input[type="email"], body.public input[type="password"] {
  background: rgba(1, 22, 56, 0.55); color: var(--lighter-tan); border: 1px solid rgba(243, 241, 239, 0.5); max-width: none;
  border-radius: 10px; min-height: 48px; height: auto; padding: 13px 14px;
}
body.public input:hover { border-color: rgba(243, 241, 239, 0.7); }
body.public input:focus-visible { border-color: var(--green-accent-scene); }
/* The neutral flash first, so an error (a flash or a form error) keeps its amber edge and point on the glass. */
body.public .flash { background: rgba(243, 241, 239, 0.06); color: var(--lighter-tan); border-color: rgba(243, 241, 239, 0.3); }
body.public .flash::after { background: var(--lighter-tan); }
body.public .form-error, body.public .flash-error { background: rgba(233, 180, 90, 0.12); color: var(--lighter-tan); border-color: var(--amber); }
body.public .form-error::before, body.public .flash-error::before { color: var(--amber); }
body.public .form-error::after, body.public .flash-error::after { background: var(--amber); }
body.public .footer { background: transparent; color: rgba(243, 241, 239, 0.7); border-top: 1px solid rgba(243, 241, 239, 0.12); }
body.public .button { color: var(--lighter-tan); border-color: rgba(243, 241, 239, 0.42); background: transparent; }
/* The website's primary (ui.module.css .btnPrimary): 52 px, 0.98rem, the arrow after the label. */
body.public .button-primary {
  color: var(--lighter-tan); background: var(--dark-green); border: 0; box-shadow: inset 0 0 0 1px var(--light-tan);
  min-height: 52px; padding: 0 24px 0 26px; font-size: 0.98rem; gap: 10px;
}
body.public .button-primary:hover { background: var(--green-hover); box-shadow: inset 0 0 0 1px var(--light-tan), 0 10px 40px rgba(60, 87, 29, 0.55); }

/* ── layout ───────────────────────────────────────────────────────────────────────────────────────────── */

/* minmax(0, 1fr): a grid item never grows to its content (a wide table scrolls inside its card instead of
   widening the page; WCAG 1.4.10 reflow). */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; }
.grid-3 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; }
/* The content column is the viewport less the 288 px sidebar: two columns from 1080 px, three from 1140 px. */
@media (min-width: 1080px) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1140px) { .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.grid-2 > .card, .grid-3 > .card { margin-bottom: 0; }
.grid-2, .grid-3 { margin-bottom: 22px; }

/* White rounded cards on the tan page, as in the original. */
.card {
  background: var(--white); border: 0; border-radius: var(--radius-card); box-shadow: var(--shadow);
  padding: 24px 26px; margin-bottom: 22px;
}
.card > h2:first-child, .card > header:first-child h2 { margin-bottom: 14px; }
.card-narrow { max-width: 620px; }
.card-highlight { box-shadow: inset 0 0 0 2px var(--dark-blue), var(--shadow); }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.card-head h2 { margin: 0; }
/* A button in a card head keeps its label on one line, as the website's buttons do; when the title and the button
   do not fit side by side (phones), the button moves under the title instead of either one breaking. */
.card-head:has(> .button) { flex-wrap: wrap; }
.card-head > .button { white-space: nowrap; }
.card-sub { margin: -6px 0 16px; }
.card-more { display: inline-flex; align-items: center; color: var(--dark-blue); text-decoration: none; padding: 4px; border-radius: 999px; }
.card-more svg { width: 22px; height: 22px; }
.card-more:hover { color: var(--dark-green); background: var(--lighter-tan); }

/* ── banners, flashes ─────────────────────────────────────────────────────────────────────────────────── */

.banner { margin: 0; padding: 10px 40px; text-align: center; font-weight: 500; font-size: 0.9rem; }
/* The demonstration label keeps its 600: demonstration data is never shown as real, so it stays the most
   conspicuous line on the page. */
.banner-demo { background: var(--lighter-tan); color: var(--dark-azure); font-weight: 600; }
/* On screens it is the website's notice (app/globals.css .contact-form-alert) inside the page column: a white panel
   with a 1 px edge, 16 px corners and an 8 px point. The point is navy: demonstration data is not a risk (never amber)
   and green is never a status. Paper keeps print.css's dashed box. */
@media screen {
  .banner-demo {
    position: relative; box-sizing: border-box; width: calc(100% - 80px); max-width: calc(var(--max) - 80px);
    margin: 14px auto 0; padding: 12px 20px 12px 44px; text-align: left; color: var(--dark-blue); background: var(--white);
    border: 1px solid rgba(1, 22, 56, 0.4); border-radius: var(--radius-card);
  }
  .banner-demo::before {
    content: ""; position: absolute; left: 20px; top: calc(12px + 0.775em - 4px); width: 8px; height: 8px; border-radius: 50%;
    background: var(--dark-blue); box-shadow: 0 0 0 3px rgba(1, 22, 56, 0.12);
  }
}

/* Notices as on the website (app/globals.css .contact-form-alert): 16 px panels with a 1 px edge in their tone and an
   8 px point beside the first line, never a stripe down one side. The point is ::after (.form-error and .flash-error
   print "Error:" with ::before): amber for errors, navy for information and confirmations, Dark Azure for service
   notes. Every one keeps its words, so the colour is never the only cue. */
.flash, .form-error, .banner-error, .banner-note, .warnings {
  position: relative; border-radius: var(--radius-card); padding: 12px 18px 12px 40px;
}
.flash::after, .form-error::after, .banner-error::after, .banner-note::after, .warnings::after {
  content: ""; position: absolute; left: 18px; top: calc(12px + 0.775em - 4px); width: 8px; height: 8px; border-radius: 50%;
  background: var(--dark-blue);
}
.flash-error::after, .form-error::after { background: var(--amber); box-shadow: 0 0 0 1px var(--amber-ink); }
.banner-note::after, .warnings::after { background: var(--dark-azure); }

.flashes { margin-bottom: 16px; }
.flash { border: 1px solid var(--line); background: var(--white); margin: 0 0 8px; }
.flash-success { border-color: var(--dark-green); }
.flash-info { border-color: var(--dark-azure); }
.flash-error { border: 1px solid var(--amber-ink); background: var(--white); color: var(--ink); }
/* A service note (the pilot's protocol line, alert delivery not configured): Lighter Tan with a Dark Azure edge. */
.banner-note { background: var(--lighter-tan); border: 1px solid var(--dark-azure); }

/* ── forms ────────────────────────────────────────────────────────────────────────────────────────────── */

.form { display: block; }
.form-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 14px; }
.form-row > .field { margin-bottom: 0; }
.field { margin-bottom: 14px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field-check { flex-direction: row; align-items: center; gap: 8px; }
.field-check label { display: flex; align-items: center; gap: 8px; }
.field-hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
/* Field labels in the website's small Arial label style. */
label { font: 400 0.8125rem/1.4 var(--font-label); letter-spacing: 0.02em; color: var(--dark-green); }
input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="datetime-local"],
input[type="date"], input[type="url"], input[type="search"], select, textarea {
  font: inherit; font-size: 0.95rem; line-height: 1.3; color: var(--ink); background: var(--white);
  /* 4.9:1 on white and 4.4:1 on the tan page (WCAG 1.4.11 asks 3:1). The website's soft box: 10 px corners, the edge
     eased over 0.6 s (navy on hover, Dark Green on focus). */
  border: 1px solid rgba(1, 22, 56, 0.6);
  border-radius: 10px; padding: 9px 14px; min-width: 0; width: 100%; max-width: 440px;
  transition: border-color 0.6s var(--ease-out);
}
/* Fields and buttons share one height (42 px), so a row of them lines up. */
input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="datetime-local"],
input[type="date"], input[type="url"], input[type="search"], select { height: 42px; }
textarea { min-height: 96px; }
input:hover, select:hover, textarea:hover { border-color: var(--dark-blue); }
input:focus, select:focus, textarea:focus { border-color: var(--dark-green); }
/* The website's checkbox (app/globals.css .contact-form__check) on the light grounds: a 24 px soft box with the
   fields' navy edge (4.8:1 on white), Dark Green with a Light Tan edge and a Lighter Tan tick once checked (7.2:1). A
   ticked box is a control, not a status. Forced colours bring back the browser's own box. */
input[type="checkbox"] {
  -webkit-appearance: none; appearance: none; flex: none; width: 24px; height: 24px; margin: 0;
  border: 1px solid rgba(1, 22, 56, 0.6); border-radius: 6px; background: var(--white) center / 16px 16px no-repeat;
  cursor: pointer; transition: border-color 0.6s var(--ease-out);
}
input[type="checkbox"]:hover { border-color: var(--dark-blue); }
input[type="checkbox"]:checked {
  border-color: var(--dark-green); background-color: var(--dark-green); box-shadow: inset 0 0 0 1px var(--light-tan);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23f3f1ef' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
input[type="checkbox"]:focus-visible { outline-offset: 2px; }
@media (forced-colors: active) {
  input[type="checkbox"] { -webkit-appearance: auto; appearance: auto; }
}
input[type="radio"] { accent-color: var(--dark-green); }
/* The attachment picker: the page's own type, with the ghost button for "Choose File". */
input[type="file"] { font: inherit; font-size: 0.88rem; color: var(--ink-muted); max-width: 100%; }
input[type="file"]::file-selector-button {
  font: inherit; font-weight: 500; font-size: 0.85rem; color: var(--dark-blue); min-height: 34px; padding: 0 12px;
  margin-right: 12px; border: 1px solid rgba(1, 22, 56, 0.5); border-radius: var(--radius); background: transparent;
  cursor: pointer; transition: background-color 0.6s var(--ease-out), border-color 0.6s var(--ease-out);
}
input[type="file"]::file-selector-button:hover { border-color: var(--dark-blue); background: rgba(1, 22, 56, 0.05); }
/* A datetime-local with seconds (step=1) has an intrinsic minimum near 290 px in Chromium, wider than a 320 px
   screen's card: let its box shrink with the column and clip its inner fields rather than widen the page (A11Y-1). */
input[type="datetime-local"] { max-width: min(440px, 100%); overflow: hidden; }
@media (max-width: 400px) { input[type="datetime-local"] { font-size: 0.9rem; padding-left: 6px; padding-right: 6px; } }
/* Only after the person has interacted with the field (:user-invalid), never on a freshly loaded empty form; the
   server's .form-error message (role=alert) states the problem in words. */
input:user-invalid, select:user-invalid, textarea:user-invalid { border: 2px solid var(--amber-ink); }
.form-error { color: var(--ink); background: var(--white); border: 1px solid var(--amber-ink); }
/* An error beside a table value (a failed delivery): the same notice, compact. */
small.form-error { display: inline-block; margin-top: 2px; padding: 2px 10px 2px 24px; border-radius: 10px; }
small.form-error::after { left: 9px; top: calc(2px + 0.775em - 4px); }
.form-error::before, .flash-error::before { content: "Error: "; font-weight: 700; color: var(--amber-ink); }
.help { color: var(--ink-muted); font-size: 0.86rem; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px; margin: 0 0 14px; }
legend { font: 400 0.75rem/1.4 var(--font-label); letter-spacing: 0.08em; text-transform: uppercase; color: var(--dark-green); padding: 0 4px; }

/* Buttons as on the website: rectangles with 5 px corners; the primary in Dark Green with a Light Tan edge. */
.button {
  font: inherit; font-weight: 500; font-size: 0.92rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; min-height: 42px; padding: 0 18px; border-radius: var(--radius); border: 1px solid rgba(1, 22, 56, 0.5);
  background: transparent; color: var(--dark-blue); text-decoration: none; line-height: 1.2; text-align: center; max-width: 100%;
  padding-top: 6px; padding-bottom: 6px;
  transition: background-color 0.6s var(--ease-out), border-color 0.6s var(--ease-out), color 0.6s var(--ease-out),
    box-shadow 0.6s var(--ease-out);
}
.button:hover { border-color: var(--dark-blue); background: rgba(1, 22, 56, 0.05); color: var(--dark-blue); }
.button-primary { border: 0; background: var(--dark-green); color: var(--lighter-tan); box-shadow: inset 0 0 0 1px var(--light-tan); }
.button-primary:hover { background: var(--green-hover); color: var(--lighter-tan); box-shadow: inset 0 0 0 1px var(--light-tan), 0 10px 34px rgba(60, 87, 29, 0.25); }
/* Forced colours drop box-shadows, and with them the primary's edge (the inset Light Tan line): there it takes a real
   border so it still reads as a button. After both primary rules (the signed-out one is more specific). */
@media (forced-colors: active) {
  .button-primary, body.public .button-primary { border: 1px solid ButtonText; }
}
.button-quiet { border-color: transparent; background: transparent; min-height: 32px; padding: 4px 8px; text-decoration: underline; text-underline-offset: 3px; }
.button-quiet:hover { background: rgba(1, 22, 56, 0.05); border-color: transparent; }
.button-danger { color: var(--dark-blue); border-style: dashed; }
.button-danger:hover { background: var(--lighter-tan); }
.button:disabled { opacity: 0.6; cursor: not-allowed; }
/* The website's arrow (components/site/PageHero.tsx Arrow, partials/icons.html "arrow"): after the label of a way
   forward (sign in, the way back from an error page, the access line); it slides 3 px on hover. */
.button-arrow { width: 1em; height: 1em; flex: none; transition: transform 0.6s var(--ease-out); }
.button-primary:hover .button-arrow { transform: translateX(3px); }
/* A button in a table row stays on one line (the table scrolls inside its .table-wrap, never the page). */
.table .button { white-space: nowrap; }
.inline-form { display: inline; }
.inline-form select { width: auto; max-width: 180px; height: 34px; padding: 4px 8px; }
.error-back { margin: 18px 0 0; } /* the way back on an error page (errors/_back.html) */
/* A form that follows a table keeps its distance from the last rule. */
.table-wrap + .form, .table-wrap + form { margin-top: 14px; }

/* ── tables ───────────────────────────────────────────────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; position: relative; }
/* A scroll box that holds nothing focusable is a Tab stop of its own (Chromium). On phones the table itself scrolls
   inside .table-wrap, whose overflow would cut a ring drawn outside the table: its ring is drawn inside its box. (A
   scrolling .table-wrap keeps the outside ring: nothing clips it there, and an inside ring would sit under the header
   row, which the positioned table paints over it.) */
.table-wrap > .table:focus-visible { outline-offset: -2px; }
.table { width: 100%; border-collapse: collapse; font-size: 0.9rem; position: relative; }
.table th, .table td { text-align: left; padding: 10px 10px; border-bottom: 1px solid var(--hairline); vertical-align: top; }
/* Column headings in the website's label style (Arial, uppercase, Dark Green on the light grounds). */
.table thead th { font: 400 0.72rem/1.35 var(--font-label); letter-spacing: 0.08em; text-transform: uppercase; color: var(--dark-green); background: var(--lighter-tan); }
.table tbody th { font-weight: 500; }
.table tbody tr { transition: background-color 0.6s var(--ease-out); }
.table tbody tr:hover { background: var(--lighter-tan); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
/* Cells wrap at spaces and hyphens only, so a column never splits a word letter by letter ("Cove rage"); a table
   wider than its card scrolls inside its .table-wrap (on phones the table itself scrolls), never the page. Hashes and
   long identifiers opt back in to breaking anywhere. */
.table th, .table td { overflow-wrap: normal; word-break: normal; }
.table .hash, .table code { overflow-wrap: anywhere; }
.cell-wrap { overflow-wrap: break-word; } /* breaks a token only when it cannot fit; never letter by letter in a table */
/* Screen only: on paper a scroll box cannot scroll (print.css lays tables out in full). */
@media screen and (max-width: 759px) {
  .table { display: block; overflow-x: auto; white-space: nowrap; }
  .table .cell-wrap { white-space: normal; }
}

/* ── facts, notes, freshness ──────────────────────────────────────────────────────────────────────────── */

.facts { display: grid; grid-template-columns: fit-content(45%) minmax(0, 1fr); gap: 4px 14px; margin: 0 0 10px; }
@media screen and (max-width: 759px) {
  .facts { grid-template-columns: minmax(0, 1fr); }
  .facts dd { margin-bottom: 6px; }
}
.facts dt { font: 400 0.8125rem/1.5 var(--font-label); letter-spacing: 0.02em; color: var(--ink-muted); }
.facts dd { margin: 0; }
.notes { margin: 6px 0 0; font-size: 0.9rem; }
.freshness { font-size: 0.84rem; color: var(--ink-muted); margin: 0; }
.freshness-unavailable { color: var(--unavailable-ink); font-weight: 600; }
.scope { font-size: 0.86rem; color: var(--ink-muted); font-weight: 400; letter-spacing: 0; }
.code-block { font-family: var(--mono); background: var(--lighter-tan); border: 1px solid var(--line); padding: 10px; border-radius: var(--radius); word-break: break-all; }
.code-large { font-family: var(--mono); font-size: 1.6rem; letter-spacing: 0.06em; }

/* ── status pills: the website's tags (a word plus a mark), never colour alone, never green ──────────── */

/* The website's light-ground tag (ui.module.css .tag): Arial 400, 0.68rem, uppercase, a filled 6 px dot in the tone.
   The strongest risk state takes a square mark and "unavailable" a dashed ring on a hatched ground, so the three
   states differ by shape as well as colour. */
.pill {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px; border-radius: 999px;
  font: 400 0.68rem/1 var(--font-label); letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap;
  border: 1px solid rgba(1, 22, 56, 0.4); background: rgba(1, 22, 56, 0.04); color: var(--dark-blue);
}
.pill-mark { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.pill-neutral { background: rgba(1, 22, 56, 0.04); color: var(--dark-blue); border-color: rgba(1, 22, 56, 0.4); }
.pill-amber { background: var(--amber-bg); color: var(--amber-ink); border-color: var(--amber); }
.pill-amber .pill-mark { background: var(--amber-ink); }
.pill-amber_strong { background: var(--amber-strong-bg); color: var(--amber-strong-ink); border-color: var(--amber-ink); }
.pill-amber_strong .pill-mark { background: var(--amber-strong-ink); width: 7px; height: 7px; border-radius: 1px; }
.pill-unavailable {
  color: var(--unavailable-ink); border-color: var(--unavailable-ink); border-style: dashed;
  background: repeating-linear-gradient(135deg, var(--unavailable-bg) 0 4px, var(--white) 4px 8px);
}
.pill-unavailable .pill-mark { width: 8px; height: 8px; background: transparent; border: 1.5px dashed currentColor; }

.room-card { position: relative; background: var(--white); border: 1px solid var(--hairline); border-left: 6px solid var(--light-tan); border-radius: 10px; padding: 14px 16px; }
.room-card.tone-neutral { border-left-color: var(--light-tan); }
.room-card.tone-amber { border-left-color: var(--amber); }
.room-card.tone-amber_strong { border-left-color: var(--amber-ink); }
.room-card.tone-unavailable { border-left-color: var(--unavailable-ink); background: repeating-linear-gradient(135deg, var(--white) 0 10px, var(--lighter-tan) 10px 12px); }
.room-card-title { margin-bottom: 4px; font-size: 1rem; }
.room-card-building { display: block; font-weight: 400; font-size: 0.86rem; color: var(--ink-muted); }
.room-card-status { margin-bottom: 8px; }
.room-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; margin-bottom: 22px; }
/* Sections on the tan page keep the cards' rhythm: a heading never touches the block above it. */
.page > section:not(.card) { margin-bottom: 28px; }
@media (min-width: 640px) { .room-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .room-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.index-block { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.index-value { font-size: 2.6rem; font-weight: 300; color: var(--dark-blue); font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -0.04em; }
.index-value.is-unavailable { color: var(--unavailable-ink); font-size: 1.4rem; font-weight: 400; letter-spacing: 0; }
.index-scale { font-size: 0.86rem; color: var(--ink-muted); }

.timeline { list-style: none; margin: 0; padding: 0 0 0 18px; border-left: 2px solid var(--line); }
.timeline li { position: relative; padding: 0 0 10px 10px; }
.timeline li::before { content: ""; position: absolute; left: -24px; top: 6px; width: 10px; height: 10px; border-radius: 50%; background: var(--dark-blue); }
.timeline .late::before { background: var(--amber); }
.timeline .overdue::before { background: var(--amber-ink); border-radius: 2px; }

.chart { width: 100%; height: auto; background: var(--white); border: 1px solid var(--hairline); border-radius: 10px; }
.chart-line { fill: none; stroke: var(--dark-blue); stroke-width: 2; }
.chart-axis { stroke: var(--line); stroke-width: 1; }
.chart-label { font-size: 11px; fill: var(--ink-muted); font-family: var(--font-label); }
/* CHART-1: on a phone the SVG is drawn at about 0.43 of its 720-unit width, so labels use 28 units (about 12 px at
   375 px) and only the major day labels (charts.x_tick_marks: at most 4) are kept so they never collide. */
@media (max-width: 759px) { .chart { overflow: visible; } .chart-label { font-size: 28px; } .chart-tick-minor { display: none; } }
.chart-band { fill: var(--amber-bg); }
.chart-gap { fill: var(--unavailable-bg); }

details { border: 1px solid var(--hairline); border-radius: 10px; padding: 10px 14px; margin-bottom: 12px; background: var(--white); }
summary { cursor: pointer; font-weight: 500; color: var(--dark-blue); }

.pagination { display: flex; gap: 16px; align-items: center; justify-content: center; margin: 12px 0; }

/* "How to read this": a white card whose accent is the website's short rule under the title (ui.module.css .rule),
   drawn as a border so it prints. */
.guardrails { background: var(--white); padding: 16px 20px; border-radius: var(--radius-card); box-shadow: var(--shadow); margin-bottom: 22px; }
.guardrails h2 { font-size: 1.05rem; }
.guardrails h2::after { content: ""; display: block; width: 40px; height: 0; margin-top: 10px; border-top: 2px solid var(--dark-green); border-radius: 2px; }
.guardrails ul { margin: 0 0 6px; }

/* Lists as the website's .docList (components/site/util.module.css): no browser disc, a short 12 x 2 px rule as the
   marker, drawn as a border so it prints. Dark Green for reading lists and links; navy beside a room's state (room
   notes, cause shares, closed episodes, recipients, the watch list), so no green mark sits beside a status. */
.guardrails ul, .link-list, .plain-list, .snapshots, .split-links, .columns, .notes, .shares, .form-error ul, .warnings ul {
  list-style: none; padding-left: 0;
}
:is(.guardrails ul, .link-list, .plain-list, .snapshots, .split-links, .columns, .notes, .shares, .form-error ul, .warnings ul) > li {
  position: relative; padding-left: 22px;
}
:is(.guardrails ul, .link-list, .plain-list, .snapshots, .split-links, .columns, .notes, .shares, .form-error ul, .warnings ul) > li::before {
  content: ""; position: absolute; left: 0; top: 0.78em; width: 12px; height: 0; border-top: 2px solid var(--dark-green);
  border-radius: 2px;
}
:is(.notes, .shares, .plain-list, .form-error ul, .warnings ul) > li::before { border-top-color: var(--dark-blue); }

/* ── the overview: the original four cards ────────────────────────────────────────────────────────────── */

.overview-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; margin-bottom: 22px; }
@media (min-width: 1080px) { .overview-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.overview-grid > .card { margin-bottom: 0; }

/* Risk Overview: a Dark Green round icon, the label with its scope, the figure on the right. */
.stat-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 18px; }
.stat { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 16px; }
.stat-icon, .row-icon {
  width: 44px; height: 44px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: var(--dark-green); color: var(--lighter-tan); flex: none;
}
.row-icon { border-radius: 12px; }
.stat-icon svg, .row-icon svg { width: 22px; height: 22px; }
.stat-label { display: block; font-weight: 500; font-size: 1.02rem; color: var(--dark-blue); }
.stat-caption { display: block; font-size: 0.84rem; color: var(--ink-muted); }
.stat-value { font-size: 1.45rem; font-weight: 300; color: var(--dark-blue); font-variant-numeric: tabular-nums; letter-spacing: -0.04em; text-align: right; }
.stat-value.is-unavailable { font-size: 0.95rem; color: var(--unavailable-ink); font-weight: 400; letter-spacing: 0; }
.stat-qual { display: block; font: 400 0.68rem/1.2 var(--font-label); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); }

/* Rooms needing attention: an icon tile, the room, its status and figures. */
.attention-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.attention-row { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 14px; align-items: start; }
.attention-row .row-title { display: block; font-weight: 500; font-size: 1.02rem; color: var(--dark-blue); margin-bottom: 2px; }
.attention-row .row-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; font-size: 0.86rem; color: var(--ink-muted); }
.attention-row .row-meta .pill { padding: 5px 9px; white-space: normal; line-height: 1.2; }
.attention-more { margin: 14px 0 0; font-size: 0.88rem; }

/* Recent monthly reports: rows with dividers and a Dark Green "View". */
.link-rows { list-style: none; margin: 0; padding: 0; }
.link-rows li { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid rgba(1, 22, 56, 0.35); }
.link-rows li:last-child { border-bottom: 0; }
.link-rows .view { color: var(--dark-green); font-weight: 500; font-size: 0.9rem; text-decoration: none; white-space: nowrap; }
.link-rows .view:hover { text-decoration: underline; }

/* Properties: the risk score of one building as the original's half gauge (Dark Blue on Light Tan: a score, not a
   status, so never green). */
.gauge-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.gauge-title { font-weight: 500; color: var(--dark-blue); display: block; }
.gauge-sub { font-size: 0.84rem; color: var(--ink-muted); display: block; }
.gauge-pick { display: flex; align-items: flex-end; gap: 8px; }
.gauge-pick .field { margin-bottom: 0; }
.gauge-pick label { font-size: 0.78rem; }
.gauge-pick select { width: auto; max-width: 190px; height: 34px; padding: 4px 8px; font-size: 0.85rem; }
.gauge-pick .button { min-height: 34px; padding: 0 12px; font-size: 0.85rem; }
.gauge { display: block; width: 100%; max-width: 320px; height: auto; margin: 4px auto 0; }
.gauge-track { fill: none; stroke: var(--light-tan); stroke-width: 34; }
.gauge-value { fill: none; stroke: var(--dark-blue); stroke-width: 34; }
.gauge-hatch { fill: none; stroke-width: 34; } /* stroke="url(#gauge-hatch)" is set on the path (a same-document pattern) */
.gauge-number { font: 300 44px/1 var(--font); fill: var(--dark-blue); letter-spacing: -0.04em; }
.gauge-number.is-unavailable { font-size: 15px; font-weight: 400; fill: var(--unavailable-ink); letter-spacing: 0; }
.gauge-scale { font: 400 12px/1 var(--font-label); fill: var(--ink-muted); }
.gauge-caption { text-align: center; font-size: 0.86rem; color: var(--ink-muted); margin: 6px 0 0; }

/* ── search results ───────────────────────────────────────────────────────────────────────────────────── */

.result-list { list-style: none; margin: 0; padding: 0; }
.result-list li { padding: 10px 0; border-bottom: 1px solid var(--hairline); }
.result-list li:last-child { border-bottom: 0; }
.result-list .result-meta { display: block; font-size: 0.84rem; color: var(--ink-muted); }

/* ── footer ───────────────────────────────────────────────────────────────────────────────────────────── */

/* The website's bottom bar (components/site/footer.module.css .legal): Arial 0.75rem with 0.04em tracking. */
.footer { padding: 18px 40px 26px; font: 400 0.75rem/1.5 var(--font-label); letter-spacing: 0.04em; color: var(--ink-muted); border-top: 1px solid var(--hairline); }
.footer p { max-width: var(--max); margin: 0 auto 4px; }
/* .footer-meta takes the footer colour as is (no opacity: 5.4:1 on tan, 6.2:1 on navy). */

/* ── narrow screens: the sidebar becomes a top block (no JavaScript needed) ───────────────────────────── */

@media (max-width: 899px) {
  .shell { grid-template-columns: minmax(0, 1fr); background: none; }
  /* One band: the wordmark with Add Account, Switch Account and Log Out on its right, then the section tabs as one
     row that scrolls sideways (inside itself, never the page), so the page content starts near the top. */
  .sidebar { position: static; height: auto; overflow: visible; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; }
  .sidebar-brand { flex-direction: row; justify-content: flex-start; padding: 12px 16px; gap: 12px; }
  .sidebar-brand img { height: 28px; }
  .sidebar-foot { grid-column: 2; grid-row: 1; justify-self: end; padding: 0 8px; min-width: 0; }
  .sidebar-foot::before { display: none; }
  .sidebar-foot ul { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 2px; }
  .sidebar-foot .nav-link, .sidebar-foot button.nav-link { font-size: 0.85rem; width: auto; padding: 8px 10px; gap: 6px; }
  /* The 6 px above the tabs holds a focused tab's ring (2 px at a 3 px offset), which the row's scroll box would
     otherwise cut. */
  /* scroll-padding keeps a tab brought into view (app.js, on focus) clear of the row's edges, ring included. */
  .sidebar-nav { grid-column: 1 / -1; padding: 6px 0 10px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; scroll-padding-inline: 8px; }
  .sidebar-nav ul { display: flex; flex-wrap: nowrap; gap: 4px; padding: 0 8px; width: max-content; }
  .nav-link { padding: 8px 12px; font-size: 0.92rem; gap: 10px; border-radius: var(--radius); white-space: nowrap; }
  .nav-icon { width: 18px; height: 18px; padding: 5px; margin: -5px 0 -5px -5px; }
  .appbar { padding: 14px 16px 6px; gap: 10px 14px; }
  .appbar-portfolio { font-size: 1.2rem; flex-basis: 100%; }
  .appbar-search { flex: 1; min-width: 0; }
  .appbar-search input[type="search"] { width: 100%; }
  .page { padding: 10px 16px 32px; }
  .banner { padding: 10px 16px; }
  .footer { padding: 16px; }
  .card { padding: 18px; }
}
/* The demonstration notice keeps the page column's 16 px gutters (after .banner above, so it wins). */
@media screen and (max-width: 899px) {
  .banner-demo { width: calc(100% - 32px); margin-top: 10px; padding: 10px 16px 10px 40px; }
  .banner-demo::before { left: 16px; top: calc(10px + 0.775em - 4px); }
}
/* Phones: the foot links keep their names for assistive technology but show their icons only, and the signed-in
   person's name moves to the Account tab (the avatar stays). */
@media (max-width: 599px) {
  .sidebar-foot .nav-link span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
  .sidebar-foot .nav-link, .sidebar-foot button.nav-link { padding: 10px; }
  .appbar-user { display: none; }
}

/* ── motion ───────────────────────────────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* Paper only (print.css shows it): the letterhead. */
.print-only { display: none; }

[hidden] { display: none !important; }
