/* Warm UI — design-system token layer (#design-system).
   Loaded AFTER bootstrap.min.css in every base template; overrides Bootstrap's
   defaults through its own CSS variables plus targeted component rules. Phase 1:
   re-tint the whole app (ground, ink, cards, buttons, fields, type) without touching
   markup. Per-screen bespoke work comes later. Palette read from the app screenshots:
   light warm theme, orange the single accent, violet-night is the ink not a surface. */

/* ── Clash Display (self-hosted, /static/fonts) ───────────────────────────── */
@font-face{font-family:'Clash Display';src:url('/static/fonts/clash-display-400.woff2') format('woff2');font-weight:400;font-display:swap;font-style:normal}
@font-face{font-family:'Clash Display';src:url('/static/fonts/clash-display-500.woff2') format('woff2');font-weight:500;font-display:swap;font-style:normal}
@font-face{font-family:'Clash Display';src:url('/static/fonts/clash-display-600.woff2') format('woff2');font-weight:600;font-display:swap;font-style:normal}
@font-face{font-family:'Clash Display';src:url('/static/fonts/clash-display-700.woff2') format('woff2');font-weight:700;font-display:swap;font-style:normal}

/* ── Tokens ───────────────────────────────────────────────────────────────── */
:root{
  --brand:#F76C22; --brand-hover:#ef6014;
  --ink:#0f0339; --ink-hover:#1c0a4d;
  --ground:#F7F7F3; --surface:#FFFFFF; --peach:#FDECE0; --muted:#9e93b4;
  --violet:#6d28d9; --blue:#2563eb; --green:#16a34a; --danger:#dc2626;

  --shadow-sm:0 1px 2px rgba(15,3,57,.04), 0 4px 12px rgba(15,3,57,.03);
  --shadow-md:0 4px 6px -1px rgba(15,3,57,.05), 0 12px 24px -4px rgba(15,3,57,.08);
  --shadow-lg:0 10px 25px -3px rgba(15,3,57,.10), 0 20px 48px -6px rgba(15,3,57,.12);
  --glow-brand:0 6px 22px rgba(247,108,34,.30);

  --r-lg:20px; --r-md:14px; --r-sm:10px;
  --ease:cubic-bezier(.16,1,.3,1); --t:all .25s var(--ease);
  --fd:'Clash Display', system-ui, -apple-system, sans-serif;

  /* Map onto Bootstrap so text-primary/bg-primary/links/radius follow the theme.
     --bs-body-bg is WHITE (not the cream ground): Bootstrap defaults cards,
     list-groups, tables, dropdowns and modals to --bs-body-bg, and they must be
     white surfaces. The cream page ground is set on <body> directly below. */
  --bs-body-bg:var(--surface);
  --bs-body-color:var(--ink);
  --bs-body-font-family:system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --bs-primary:#F76C22; --bs-primary-rgb:247,108,34;
  --bs-link-color:var(--brand); --bs-link-color-rgb:247,108,34;
  --bs-link-hover-color:var(--brand-hover);
  --bs-border-color:rgba(15,3,57,.10);
  --bs-border-radius:var(--r-md);
  --bs-border-radius-sm:var(--r-sm);
  --bs-border-radius-lg:var(--r-lg);
  --bs-emphasis-color:var(--ink);
}

body{background:var(--ground);color:var(--ink);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
/* The page ground is warm cream and cards are white (like the mockup). Templates
   put bg-light on <body>, which otherwise wins as near-white — pin it back to the
   ground. Cards are forced white here because Bootstrap's --bs-card-bg defaults to
   --bs-body-bg (cream), which would make cards the same colour as the ground. */
body.bg-light{background:var(--ground)!important}

/* ── Typography — Clash Display on headings + brand ───────────────────────── */
h1,h2,h3,h4,h5,h6,.navbar-brand,.display-1,.display-2,.display-3,.display-4,.display-5,.display-6{
  font-family:var(--fd);letter-spacing:-.02em}
.text-muted{color:var(--muted)!important}

/* ── Depth — soft, diffuse shadows replace Bootstrap's flat ones ──────────── */
.shadow-sm{box-shadow:var(--shadow-sm)!important}
.shadow{box-shadow:var(--shadow-md)!important}
.shadow-lg{box-shadow:var(--shadow-lg)!important}

/* ── Cards ────────────────────────────────────────────────────────────────── */
.card{--bs-card-bg:var(--surface);background-color:var(--surface);border:1px solid rgba(15,3,57,.06);border-radius:var(--r-lg);transition:var(--t)}
.card.shadow-sm:hover{box-shadow:var(--shadow-md)!important}

/* ── Buttons — rounded, tactile, brand glow on primary ────────────────────── */
.btn{border-radius:var(--r-sm);font-weight:600;transition:var(--t)}
.btn:active{transform:translateY(0) scale(.985)}
.btn-dark{--bs-btn-bg:var(--ink);--bs-btn-border-color:var(--ink);
  --bs-btn-hover-bg:var(--ink-hover);--bs-btn-hover-border-color:var(--ink-hover);
  --bs-btn-active-bg:var(--ink-hover);--bs-btn-active-border-color:var(--ink-hover)}
.btn-dark:hover{transform:translateY(-2px);box-shadow:0 8px 22px rgba(15,3,57,.22)}
.btn-primary{--bs-btn-bg:var(--brand);--bs-btn-border-color:var(--brand);
  --bs-btn-hover-bg:var(--brand-hover);--bs-btn-hover-border-color:var(--brand-hover);
  --bs-btn-active-bg:var(--brand-hover);--bs-btn-active-border-color:var(--brand-hover);
  box-shadow:var(--glow-brand)}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 10px 28px rgba(247,108,34,.42)}
.btn-outline-secondary{--bs-btn-color:var(--ink);--bs-btn-border-color:rgba(15,3,57,.14);
  --bs-btn-hover-bg:var(--peach);--bs-btn-hover-border-color:var(--brand);--bs-btn-hover-color:var(--brand)}
.btn-outline-primary{--bs-btn-color:var(--brand);--bs-btn-border-color:var(--brand);
  --bs-btn-hover-bg:var(--brand);--bs-btn-hover-border-color:var(--brand)}

/* ── Forms — soft glow focus, no rigid outline ────────────────────────────── */
.form-control,.form-select{border-radius:var(--r-sm);border-color:rgba(15,3,57,.10);transition:var(--t)}
.form-control:focus,.form-select:focus{border-color:var(--brand);box-shadow:0 0 0 4px var(--peach)}
.form-check-input:checked{background-color:var(--brand);border-color:var(--brand)}
.form-check-input:focus{border-color:var(--brand);box-shadow:0 0 0 4px var(--peach)}

/* ── Navbar / chrome — violet-night, not black ────────────────────────────── */
.navbar.bg-dark,.bg-dark{background-color:var(--ink)!important}
.navbar-brand{font-weight:600}

/* ── Status colours — soft-filled pills for the bg-* badges used on statuses ─ */
.badge.bg-success{background-color:rgba(22,163,74,.12)!important;color:var(--green)!important}
.badge.bg-info{background-color:rgba(37,99,235,.12)!important;color:var(--blue)!important}
.badge.bg-warning{background-color:rgba(247,108,34,.14)!important;color:var(--brand)!important}
.badge.bg-secondary{background-color:rgba(15,3,57,.06)!important;color:var(--muted)!important}
.badge.bg-primary{background-color:var(--peach)!important;color:var(--brand)!important}
.badge.rounded-pill{font-weight:600}

/* ── Alerts — softer ──────────────────────────────────────────────────────── */
.alert{border-radius:var(--r-sm)}
.alert-success{--bs-alert-bg:#f0faf3;--bs-alert-border-color:rgba(22,163,74,.22);--bs-alert-color:#136c33}
.alert-danger{--bs-alert-bg:#fdf1f1;--bs-alert-border-color:rgba(220,38,38,.2);--bs-alert-color:#a71d1d}

/* ── Accessibility ────────────────────────────────────────────────────────── */
:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
@media (prefers-reduced-motion: reduce){
  *,.btn,.card{transition:none!important}
  .btn:hover,.card.shadow-sm:hover,.btn-dark:hover,.btn-primary:hover{transform:none}
}

/* ── Component-library helpers (used by templates/components/ui.html) ──────── */
.text-brand{color:var(--brand)!important}
.bg-peach{background:var(--peach)!important}
/* Initials-fallback avatars — peach + brand (like the mockup), not grey/ink.
   Applied to the inline rounded-circle avatars that keep their own px sizing. */
.avatar-initials{background:var(--peach)!important;color:var(--brand)!important;font-family:var(--fd)}
/* Bootstrap 5 has no min-width-0 utility, but templates use it to let flex children
   (message rows, job cards) shrink so text-truncate works instead of overflowing. */
.min-width-0{min-width:0!important}
.field-error .form-control,.field-error .form-select{border-color:var(--danger);box-shadow:0 0 0 4px rgba(220,38,38,.12)}
.field-err{color:var(--danger);font-size:12.5px;margin-top:6px}
/* avatar with initials fallback — circle to match the whole app (operator call
   2026-07-24); a `square` variant keeps the rounded-square token if ever needed */
.avatar{border-radius:50%;background:var(--brand);color:#fff;font-family:var(--fd);font-weight:600;
  display:inline-flex;align-items:center;justify-content:center;object-fit:cover;flex-shrink:0}
.avatar.square{border-radius:14px}
.avatar.peach{background:var(--peach);color:var(--brand)}
.avatar-sm{width:36px;height:36px;font-size:15px}
.avatar-md{width:48px;height:48px;font-size:19px}
.avatar-lg{width:64px;height:64px;font-size:24px}
.avatar-sm.square{border-radius:11px}
.avatar-lg.square{border-radius:16px}
/* stat card (ui.stat) — clickable dashboard tiles, uniform size per row */
.stat-card{transition:transform .15s ease, box-shadow .15s ease}
a:hover > .stat-card{transform:translateY(-2px);box-shadow:var(--shadow-lg)}
.stat-card .display-6{letter-spacing:-.02em}
/* empty state */
.empty-state{text-align:center;padding:44px 20px;color:var(--muted)}
.empty-state .glyph{width:60px;height:60px;border-radius:18px;background:var(--peach);color:var(--brand);
  margin:0 auto 16px;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm)}
.empty-state .es-title{font-family:var(--fd);font-weight:600;color:var(--ink);font-size:17px;letter-spacing:-.02em}
/* Work-Folio entries — ONE card language for the three places they render: the
   editable list on the talent profile, and the read-only grid the profile view
   and the business candidate page both include. The read-only grid used to be
   bare Bootstrap (`border rounded`, 0.75rem inline type) next to the styled
   editable list, so the talent's own stories looked unfinished to the business
   reading them. */
.wf-entry{border:1px solid rgba(15,3,57,.08);border-radius:var(--r-md);background:var(--surface);
  overflow:hidden;transition:border-color .15s ease, box-shadow .15s ease}
/* Masonry, via CSS columns rather than a Bootstrap row. Covers keep their own
   height (no crop, no fixed band), so a row grid made every row as tall as its
   tallest card: a portrait next to a text-only story left half a screen blank.
   Cards now fill a column and continue in the next one, so the only whitespace
   left is the gap between them. Reading order becomes top-to-bottom per column,
   which is what a portfolio wants anyway. */
.wf-grid{column-count:2;column-gap:16px}
.wf-grid > .wf-entry{display:block;width:100%;margin-bottom:16px;
  -webkit-column-break-inside:avoid;break-inside:avoid}
@media (max-width:575.98px){.wf-grid{column-count:1}}
.wf-entry:hover{border-color:rgba(247,108,34,.35);box-shadow:var(--shadow-sm)}
.wf-entry .wf-title{font-family:var(--fd);font-weight:600;letter-spacing:-.01em}
.wf-entry .wf-meta{color:var(--muted)}
.wf-entry summary{list-style:none}
.wf-entry summary::-webkit-details-marker{display:none}
/* The editable entry's action row. Closed, the <details> is only its summary, so
   [Edit] and [Delete] sit side by side. Open, the summary labels a form that is
   already on screen — it goes, the form takes the whole row, and Save drops in
   beside Delete under the fields. Save is hidden while the form is collapsed:
   there is nothing on screen for it to submit. */
.wf-form[open]{flex:1 0 100%}
.wf-form[open] > summary{display:none}
.wf-form:not([open]) ~ .wf-buttons .wf-save{display:none}
/* Cover photo: the image keeps its OWN ratio, capped in height. Never cropped —
   a Work-Folio photo IS the story, and filling a frame cut the subject out of any
   shot that wasn't already 2:1.
   No fixed band either: forcing every photo into one ratio and letterboxing the
   rest left a panorama as a strip in a sea of mat and a portrait as a stamp. A
   wide photo now spans the card edge to edge with no mat at all; only a tall one
   shows the ground on its sides, where there is genuinely nothing to draw.
   Centres itself and carries its own mat, so the rule holds whether or not the
   photo is wrapped in the lightbox trigger. The mat is the card's own surface,
   not `--ground`: a tinted block behind a tall photo read as a second frame
   drawn around it, which is exactly the noise this rule exists to remove. */
.wf-cover{display:block;max-width:100%;max-height:320px;width:auto;height:auto;
  object-fit:contain;margin-inline:auto;background:var(--surface)}
/* Same no-crop rule at thumbnail size, on the editable list. */
.wf-thumb{width:56px;height:56px;border-radius:var(--r-sm);object-fit:contain;
  background:var(--ground);flex-shrink:0}
/* Space held for a photo that isn't there — reserved, never painted. An empty
   mat would read as a photo that failed to load. */
.wf-thumb-none{background:none}
/* The cover is a button (it opens the lightbox) but must render as the bare image.
   It carries the mat and centres the photo, so a tall shot sits in the middle of
   the card instead of hugging one edge. Resetting `background` and `border` is not
   cosmetic: unstyled, a <button> falls back to the UA's grey ButtonFace + border. */
.wf-shot{display:flex;align-items:center;justify-content:center;width:100%;
  padding:0;border:0;background:var(--surface);cursor:zoom-in}
/* Lightbox: the photo at viewport size over the backdrop, with the entry's own
   caption under it so the image keeps its meaning once it leaves the card. */
.wf-lightbox .modal-content{background:none;border:0}
.wf-lightbox .wf-lb-img{width:100%;max-height:76vh;object-fit:contain;border-radius:var(--r-md)}
/* The caption carries its own dark panel rather than trusting the backdrop:
   over a pale photo or a light page the white text was barely there. Centred
   because `contain` leaves the photo narrower than the dialog. */
.wf-lightbox .wf-lb-caption{color:#fff;background:rgba(15,3,57,.72);
  border-radius:var(--r-md);padding:12px 16px;text-align:center;
  width:fit-content;max-width:100%;margin-inline:auto}
.wf-lightbox .wf-lb-caption .wf-title{color:#fff}
.wf-lightbox .wf-lb-caption > div:first-child{justify-content:center}
.wf-lightbox .wf-lb-meta{color:rgba(255,255,255,.75)}
/* The description keeps the talent's own line breaks, reads left-aligned (a
   centred paragraph is a ragged block, not a caption) and stops at a measure
   the eye can follow — the dialog is far wider than a comfortable line. */
.wf-lightbox .wf-lb-desc{color:rgba(255,255,255,.9);white-space:pre-wrap;
  text-align:left;max-width:60ch;margin-inline:auto}
/* thin-stroke icon helper */
.ico{width:20px;height:20px;stroke:currentColor;stroke-width:1.5;fill:none;
  stroke-linecap:round;stroke-linejoin:round;display:inline-block;vertical-align:middle}

/* ── Chrome — navbars & sidebars (#design-system phase 2) ─────────────────── */
.navbar.bg-white{border-bottom:0!important;box-shadow:0 1px 0 rgba(15,3,57,.04), var(--shadow-sm)}
.navbar-brand{font-family:var(--fd);font-weight:600;letter-spacing:-.02em}
.border-end{border-color:rgba(15,3,57,.06)!important}
.border-bottom{border-color:rgba(15,3,57,.06)!important}
/* nav links: rounded, orange on hover, peach+orange when active */
.nav-link{border-radius:var(--r-sm);transition:var(--t)}
.sidebar .nav-link,.border-end .nav-link{margin:1px 8px}
.nav-link:hover{color:var(--brand)}
.nav-link.active,.border-end .nav-link.bg-light{
  background:var(--peach)!important;color:var(--brand)!important;font-weight:600}
/* dropdown menus: soft, rounded, floating */
.dropdown-menu{border:1px solid rgba(15,3,57,.05);border-radius:var(--r-md);
  box-shadow:var(--shadow-lg);padding:6px}
.dropdown-item{border-radius:var(--r-sm);transition:var(--t)}
.dropdown-item:active,.dropdown-item.active{background:var(--brand)}
.dropdown-item:hover{background:var(--peach);color:var(--brand)}

/* ── Polish pass (review 2026-07-23) ──────────────────────────────────────── */
/* Focus: orange, never Bootstrap's blue. --bs-focus-ring-color is what form-check /
   nav-link / btn use for their ring; it defaulted to blue. */
:root{--bs-focus-ring-color:rgba(247,108,34,.25)}
.form-check-input:focus,.form-control:focus,.form-select:focus,.nav-link:focus,
.btn:focus,.btn:focus-visible,.page-link:focus{
  border-color:var(--brand)!important;box-shadow:0 0 0 .22rem rgba(247,108,34,.22)!important}

/* Radios & checkboxes: clean, brand-coloured, decent tap target, no blue */
.form-check-input{width:1.2em;height:1.2em;margin-top:.16em;border:1.5px solid rgba(15,3,57,.28);
  background-color:#fff;transition:var(--t);cursor:pointer}
.form-check-input:checked{background-color:var(--brand);border-color:var(--brand)}
.form-check-label{cursor:pointer}

/* Badges: always centred regardless of the text */
.badge{display:inline-flex;align-items:center;justify-content:center;text-align:center;line-height:1}

/* Segmented control (real component) — active = solid orange + white, rest = ink */
.segmented{display:inline-flex;background:var(--surface);border:1px solid rgba(15,3,57,.05);
  border-radius:999px;padding:5px;gap:4px;box-shadow:var(--shadow-sm);max-width:100%;overflow-x:auto}
.segmented .seg{font-weight:600;font-size:14px;padding:9px 22px;border-radius:999px;color:var(--ink);
  border:0;background:transparent;cursor:pointer;transition:var(--t);text-decoration:none;white-space:nowrap;
  display:inline-flex;align-items:center;justify-content:center;flex:1 0 auto}
.segmented .seg:hover:not(.active){background:var(--peach);color:var(--brand)}
.segmented .seg.active{background:var(--brand);color:#fff;box-shadow:var(--glow-brand)}
.segmented .seg:focus,.segmented .seg:focus-visible{box-shadow:0 0 0 .22rem rgba(247,108,34,.25)}
.segmented.block{display:flex;width:100%}
.segmented.block .seg{flex:1 1 0}

/* Select control (closed) matches; the NATIVE open list is OS-rendered and not
   stylable — migrate real selects to TomSelect (already vendored) for a themed list. */
.form-select{cursor:pointer}

/* Chat message bubbles — the timestamp tucks inline (short messages stay a tidy
   single line instead of a wide bubble with the time dumped below), and long
   words/URLs break instead of overflowing the flex item. */
.msg-bubble{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:10px;row-gap:2px;
  overflow-wrap:anywhere;min-width:0}
.msg-bubble .msg-time{margin-left:auto;font-size:.68rem;opacity:.7;white-space:nowrap}

/* Ranked preferences (read-only) — the talent ranks their job priorities and that
   order is the answer, so the position is rendered as content rather than implied by
   list order. Same 24px disc as the edit form's .priority-rank, minus the inline
   styles: this one is shared by the talent's own profile and the business's
   candidate view, so it lives in the token layer. */
.pref-rank{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:24px;height:24px;border-radius:50%;background:var(--peach);color:var(--brand);
  font-weight:700;font-size:.72rem;line-height:1}

/* Legal document (Terms & Conditions) — Markdown shipped from lib/content/legal/
   and rendered as-is, so the styling has to come from the container rather than
   from classes on the elements. It stays a scroll box: the agreement checkbox and
   the button must remain reachable without paging through 18 sections, and the box
   is what tells the reader there is more text than the screen shows.
   Sized in vh, not px — a phone and a laptop disagree about how much 400px is. */
.legal-doc{max-height:58vh;overflow-y:auto;font-size:.875rem;line-height:1.55;
  overflow-wrap:anywhere}
/* The document carries its own H1 (its legal title). The page's H1 above it names
   the onboarding step, so the document's is stepped down to read as a title inside
   the box rather than competing with it. */
/* Body font on the document's own headings, against the site-wide rule above.
   Clash Display draws a 0.15em word space (a system face draws ~0.26em) and the
   heading rule tightens it further — fine on a short, large page title, but a
   15px "6.3 How We Use Your Data" comes out with its words touching. A contract
   is read, not staged, so its headings take the same face as its body text. */
.legal-doc h1,.legal-doc h2,.legal-doc h3,.legal-doc h4,.legal-doc h5,.legal-doc h6{
  font-family:var(--bs-body-font-family);letter-spacing:normal}
.legal-doc h1{font-size:1.05rem;font-weight:700;margin:0 0 .5rem}
.legal-doc h2{font-size:.98rem;font-weight:700;margin:1.35rem 0 .4rem}
.legal-doc h3{font-size:.9rem;font-weight:600;margin:1rem 0 .3rem}
.legal-doc h1:first-child,.legal-doc h2:first-child{margin-top:0}
.legal-doc p,.legal-doc ul,.legal-doc ol{margin-bottom:.6rem}
.legal-doc li{margin-bottom:.2rem}
.legal-doc hr{margin:1.1rem 0;opacity:.15}
/* A table inside a 58vh box has nowhere to overflow to, so it scrolls sideways on
   its own instead of widening the whole document. */
.legal-doc table{width:100%;margin-bottom:.75rem;border-collapse:collapse;display:block;
  overflow-x:auto;white-space:nowrap}
.legal-doc th,.legal-doc td{border:1px solid rgba(15,3,57,.12);padding:.35rem .55rem;
  text-align:left;vertical-align:top}
.legal-doc th{background:rgba(15,3,57,.04);font-weight:600}
