/*
 * KeyToRental design system — one stylesheet for every screen.
 *
 * Linked first by every page (the app at /app, the classic app at /app2, the
 * public pages and every server-rendered page through brand.publicPageShell),
 * so a text box, a button, a card or a notice looks the same on a landlord's
 * desktop and on a tenant's phone. The rules are written down in
 * docs/design/design-system.md and checked by test/design-system.test.js.
 *
 * - Colour values come from src/lib/brand.js TOKENS (the test keeps them equal).
 *   Never type a hex value into a page: use a token.
 * - Every component rule is wrapped in :where(), so it has zero specificity and
 *   a page can still adjust layout. Pages must NOT restyle what this file owns
 *   (input look, button look, font sizes on phones, tap sizes).
 * - Breakpoints: 520px (phone), 720px (large phone / small tablet: touch sizes
 *   switch on here), 960px (app shell: sidebar vs bottom bar). No others.
 * - Dark mode is opt-in: <html data-ds-dark="auto"> follows the device, and
 *   <html data-theme="dark"> forces it. Public pages stay light.
 */

:root{
  /* colour */
  --bg:#FAF8F3; --surface:#FFFFFF; --inset:#F1EEE6; --line:#E7E3D8; --line2:#D8D2C3;
  --ink:#141B2C; --ink2:#48516C; --ink3:#687087;
  --navy:#101A38;
  --blue:#2B59D4; --blue-deep:#1C3E9E; --blue-tint:#E8EEFC; --blue-ink:#2B59D4;
  --gold:#F0A92A; --gold-ink:#8F620A; --gold-tint:#FBF2DE;
  --good:#187A48; --good-tint:#E2F3E9; --warn:#A16508; --warn-tint:#FAF0DC; --bad:#C13A2E; --bad-tint:#FBE9E7;
  --on-accent:#FFFFFF; --on-gold:#3A2A05;
  --shadow:0 1px 2px rgba(20,27,44,.05),0 4px 16px rgba(20,27,44,.06);
  --shadow-lg:0 8px 40px rgba(20,27,44,.18); --scrim:rgba(16,22,38,.44);
  --focus-ring:0 0 0 3px rgba(43,89,212,.18);
  /* older names some pages still read; they point at the tokens above */
  --card:var(--surface); --paper:var(--bg); --warn-bg:var(--warn-tint);

  /* type */
  --font-body:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  --font-display:"Bricolage Grotesque","Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --fs-xs:12px; --fs-sm:13px; --fs-base:15px; --fs-md:16px; --fs-lg:18px; --fs-xl:22px; --fs-2xl:28px; --fs-3xl:36px;

  /* shape and size */
  --r-sm:8px; --r-control:10px; --r-card:16px; --r-pill:999px;
  --control-h:40px; --control-h-sm:32px; --tap:44px;
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px; --sp-8:32px;
}

@media (prefers-color-scheme: dark){
  :root[data-ds-dark="auto"]:not([data-theme="light"]){
    --bg:#0C1120; --surface:#151C30; --inset:#1C2440; --line:#26304D; --line2:#33405F;
    --ink:#EEF2FB; --ink2:#ACB5CB; --ink3:#7A849C;
    --blue:#3E68DF; --blue-deep:#5F86EC; --blue-tint:#1B2A52; --blue-ink:#93ACF4;
    --gold:#F0A92A; --gold-ink:#F5B84D; --gold-tint:#33270F;
    --good:#3FB877; --good-tint:#12301F; --warn:#E0A33E; --warn-tint:#332508; --bad:#E4695C; --bad-tint:#3A1512;
    --shadow:0 1px 2px rgba(0,0,0,.3),0 4px 16px rgba(0,0,0,.25);
    --shadow-lg:0 8px 40px rgba(0,0,0,.5); --scrim:rgba(4,7,15,.6);
    --focus-ring:0 0 0 3px rgba(147,172,244,.28);
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#0C1120; --surface:#151C30; --inset:#1C2440; --line:#26304D; --line2:#33405F;
  --ink:#EEF2FB; --ink2:#ACB5CB; --ink3:#7A849C;
  --blue:#3E68DF; --blue-deep:#5F86EC; --blue-tint:#1B2A52; --blue-ink:#93ACF4;
  --gold:#F0A92A; --gold-ink:#F5B84D; --gold-tint:#33270F;
  --good:#3FB877; --good-tint:#12301F; --warn:#E0A33E; --warn-tint:#332508; --bad:#E4695C; --bad-tint:#3A1512;
  --shadow:0 1px 2px rgba(0,0,0,.3),0 4px 16px rgba(0,0,0,.25);
  --shadow-lg:0 8px 40px rgba(0,0,0,.5); --scrim:rgba(4,7,15,.6);
  --focus-ring:0 0 0 3px rgba(147,172,244,.28);
  color-scheme:dark;
}

/* ---------------------------------------------------------------- base --- */
:where(*,*::before,*::after){box-sizing:border-box}
:where(html){-webkit-text-size-adjust:100%;text-size-adjust:100%}
:where(body){margin:0;font-family:var(--font-body);font-size:var(--fs-base);line-height:1.5;color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
:where(h1,h2,h3){font-family:var(--font-display);letter-spacing:-.02em;line-height:1.15;text-wrap:balance;color:var(--ink)}
/* A dark panel carries .surface-dark (Oct-22). The heading rule above gives
   every h1-h3 --ink, which is invisible on navy unless each panel remembers
   to override it -- the landing page's final CTA forgot and its headline
   vanished. On a .surface-dark the panel sets the text colour and headings
   INHERIT it. test/e05-contrast-sweep renders every page and view, light and
   dark, and fails on any text below a 3:1 ratio against what it sits on. */
:where(.surface-dark){color:var(--on-accent)}
:where(.surface-dark) :where(h1,h2,h3,h4){color:inherit}
:where(button,input,select,textarea){font-family:inherit;color:inherit}
:where(img,video,canvas,svg){max-width:100%}
:where(a){color:var(--blue-ink)}
:where(button,a,[tabindex],input,select,textarea):focus-visible{outline:2px solid var(--blue-ink);outline-offset:2px}
@media (prefers-reduced-motion: reduce){:where(*,*::before,*::after){animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* ------------------------------------------------------- inputs (one look) --- */
:where(.input, input:not([type]), input[type="text"], input[type="email"], input[type="number"], input[type="date"],
  input[type="datetime-local"], input[type="time"], input[type="month"], input[type="tel"], input[type="search"],
  input[type="password"], input[type="url"], select, textarea){
  display:block;width:100%;min-height:var(--control-h);
  padding:9px 14px;border:1px solid var(--line2);border-radius:var(--r-control);
  background:var(--surface);color:var(--ink);
  font:400 var(--fs-base)/1.35 var(--font-body);
  box-shadow:0 1px 2px rgba(0,0,0,.03);
  transition:border-color .15s,box-shadow .15s;
}
:where(textarea){min-height:96px;resize:vertical;line-height:1.45}
:where(select){cursor:pointer;appearance:none;-webkit-appearance:none;padding-right:36px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23687087' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 4.5 3 3 3-3'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 13px center}
:where(.input, input, select, textarea)::placeholder{color:var(--ink3);opacity:1}
:where(.input, input, select, textarea):focus{outline:none;border-color:var(--blue);box-shadow:var(--focus-ring)}
:where(.input, input, select, textarea):disabled{background:var(--inset);color:var(--ink3);cursor:not-allowed}
:where(.input, input, select, textarea)[aria-invalid="true"]{border-color:var(--bad)}
:where(.input, input, select, textarea)[readonly]{background:var(--inset);color:var(--ink2)}
:where(.input.sm, input.sm, select.sm){min-height:var(--control-h-sm);padding:5px 10px;font-size:var(--fs-sm);border-radius:var(--r-sm)}
:where(select.sm){padding-right:30px;background-position:right 10px center}
:where(input[type="checkbox"], input[type="radio"]){width:18px;height:18px;accent-color:var(--blue);vertical-align:-3px}

/* Labelled field: <div class="fld"><label for="x">Rent</label><input id="x" class="input"><p class="hint">…</p></div> */
:where(.fld){display:flex;flex-direction:column;gap:6px;min-width:0}
:where(.fld > label, .lbl){font-size:var(--fs-sm);font-weight:600;color:var(--ink2)}
:where(.fld .hint, .hint){font-size:var(--fs-xs);color:var(--ink3);margin:0}
:where(.fld .err, .field-err){font-size:var(--fs-xs);color:var(--bad);margin:0}

/* Two or three fields side by side; one column on a phone. */
:where(.ds-grid2){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3)}
:where(.ds-grid3){display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-3)}
@media (max-width:520px){:where(.ds-grid2,.ds-grid3){grid-template-columns:minmax(0,1fr)}}
@media (min-width:521px) and (max-width:720px){:where(.ds-grid3){grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ------------------------------------------------------------- buttons --- */
:where(.btn){display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:var(--control-h);padding:8px 16px;border:1px solid transparent;border-radius:var(--r-control);
  background:var(--surface);color:var(--ink);
  font:600 14px/1.25 var(--font-body);letter-spacing:.1px;text-decoration:none;text-align:center;
  cursor:pointer;transition:filter .15s,background .15s}
:where(.btn svg){width:16px;height:16px;flex:none}
:where(.btn.primary){background:var(--blue);color:var(--on-accent)}
:where(.btn.primary):hover{background:var(--blue-deep)}
:where(.btn.ghost, .btn.secondary){background:var(--surface);border-color:var(--line2);color:var(--ink)}
:where(.btn.ghost, .btn.secondary):hover{background:var(--inset)}
:where(.btn.gold, .btn.goldb){background:var(--gold);color:var(--on-gold)}
:where(.btn.danger){background:var(--bad-tint);border-color:var(--bad);color:var(--bad)}
:where(.btn.danger.solid){background:var(--bad);color:var(--on-accent)}
:where(.btn.link){background:none;border-color:transparent;color:var(--blue-ink);padding-left:8px;padding-right:8px}
:where(.btn.link):hover{text-decoration:underline}
:where(.btn.sm, .btn.xs){min-height:var(--control-h-sm);padding:5px 12px;font-size:var(--fs-sm);border-radius:var(--r-sm)}
:where(.btn.lg){min-height:48px;padding:12px 20px;font-size:var(--fs-base)}
:where(.btn.wide){display:flex;width:100%}
:where(.btn):disabled, :where(.btn[aria-disabled="true"]){opacity:.55;cursor:not-allowed;filter:none}
/* Square icon-only button (close, delete a photo, more). Always has aria-label. */
:where(.icon-btn){display:inline-grid;place-items:center;width:var(--control-h);height:var(--control-h);flex:none;
  border:0;border-radius:var(--r-control);background:transparent;color:var(--ink2);cursor:pointer}
:where(.icon-btn):hover{background:var(--inset);color:var(--ink)}
:where(.icon-btn svg){width:18px;height:18px}
/* A row of actions that drops onto its own lines instead of squeezing the title. */
:where(.ds-actions){display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2)}
:where(.ds-head){display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--sp-3)}
:where(.ds-head > :first-child){min-width:min(100%,220px);flex:1 1 220px}

/* ---------------------------------------------------- touch: phones/tablets --- */
/* 16px stops iOS Safari zooming the page when a field is tapped. 44px is the
   smallest comfortable tap. These two win over any page rule on purpose. */
@media (max-width:720px), (pointer:coarse){
  :where(.input, input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]), select, textarea){font-size:16px!important;min-height:var(--tap)}
  :where(.input.sm, input.sm, select.sm){min-height:40px}
  :where(.btn){min-height:var(--tap)}
  :where(.btn.sm, .btn.xs){min-height:40px;padding-left:14px;padding-right:14px}
  :where(.btn.lg){min-height:48px}
  :where(.icon-btn){width:var(--tap);height:var(--tap)}
}

/* -------------------------------------------------------------- surfaces --- */
:where(.card){background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);box-shadow:var(--shadow)}
:where(.card.pad){padding:var(--sp-5)}
@media (max-width:520px){:where(.card.pad){padding:var(--sp-4)}}

/* Status chip: always a word, never colour alone. */
:where(.chip){display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:var(--r-pill);
  font-size:var(--fs-xs);font-weight:600;line-height:1.35;white-space:nowrap;background:var(--inset);color:var(--ink2)}
:where(.chip.good){background:var(--good-tint);color:var(--good)}
:where(.chip.warn){background:var(--warn-tint);color:var(--warn)}
:where(.chip.bad){background:var(--bad-tint);color:var(--bad)}
:where(.chip.blue){background:var(--blue-tint);color:var(--blue-ink)}
:where(.chip.gold){background:var(--gold-tint);color:var(--gold-ink)}
:where(.chip.plain){background:var(--inset);color:var(--ink2)}

/* Notice: an inline message box. .info (default) .good .warn .bad */
:where(.notice){display:block;padding:12px 14px;border-radius:var(--r-control);border:1px solid var(--line);
  border-left:4px solid var(--blue);background:var(--blue-tint);color:var(--ink);font-size:14px;line-height:1.45;overflow-wrap:anywhere}
:where(.notice.good){border-left-color:var(--good);background:var(--good-tint)}
:where(.notice.warn){border-left-color:var(--warn);background:var(--warn-tint)}
:where(.notice.bad){border-left-color:var(--bad);background:var(--bad-tint)}
:where(.notice[hidden], .hide, [hidden]){display:none!important}
/* Visually hidden, still read by screen readers. */
:where(.sr-only, .vh){position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Empty state: icon, one line, one action. */
:where(.empty){text-align:center;padding:32px 16px;color:var(--ink3)}
:where(.empty .empty-title){font-weight:600;color:var(--ink2);margin:8px 0 4px}

/* Tables scroll inside their own box on a phone; the page never scrolls sideways. */
:where(.table-wrap){width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
:where(.table-wrap > table){min-width:100%}
:where(td, th){overflow-wrap:anywhere}

/* Conversation: one bubble for every thread (app, tenant portal, listing chat).
   .them = the other person (blue), .agent = the AI agent (green), .me = you (gold),
   .note = a system line. Name in .who, time in .meta. */
:where(.thread){display:flex;flex-direction:column;gap:8px}
:where(.bubble){align-self:flex-start;max-width:min(80%,560px);padding:10px 14px;border-radius:16px 16px 16px 6px;
  background:var(--inset);color:var(--ink);font-size:var(--fs-base);line-height:1.45;overflow-wrap:anywhere;white-space:pre-wrap}
:where(.bubble.them){background:var(--blue-tint)}
:where(.bubble.agent){background:var(--good-tint)}
:where(.bubble.me){align-self:flex-end;background:var(--gold-tint);border-radius:16px 16px 6px 16px}
:where(.bubble.note){align-self:center;background:none;padding:2px 8px;color:var(--ink3);font-size:var(--fs-sm);text-align:center}
:where(.bubble .who){display:block;margin-bottom:2px;font-size:var(--fs-xs);font-weight:600;color:var(--ink2);white-space:normal}
:where(.bubble .meta){display:block;margin-top:4px;font-size:var(--fs-xs);color:var(--ink3);white-space:normal}
:where(.bubble.rich){white-space:normal;max-width:min(95%,640px)}
@media (max-width:520px){:where(.bubble){max-width:88%}}

/* Picker chips for 2-5 choices (condition, priority, yes/no). */
:where(.choice){display:inline-flex;align-items:center;justify-content:center;min-height:var(--control-h);padding:8px 14px;
  border:1px solid var(--line2);border-radius:var(--r-control);background:var(--surface);color:var(--ink);font:600 14px/1.2 var(--font-body);cursor:pointer}
:where(.choice[aria-pressed="true"], .choice.on, input:checked + .choice){border-color:var(--blue);background:var(--blue-tint);color:var(--blue-ink)}
:where(.choice.good[aria-pressed="true"], .choice.good.on){border-color:var(--good);background:var(--good-tint);color:var(--good)}
:where(.choice.warn[aria-pressed="true"], .choice.warn.on){border-color:var(--warn);background:var(--warn-tint);color:var(--warn)}
:where(.choice.bad[aria-pressed="true"], .choice.bad.on){border-color:var(--bad);background:var(--bad-tint);color:var(--bad)}
@media (max-width:720px), (pointer:coarse){:where(.choice){min-height:var(--tap)}}

/* File picker: a label that wraps the input, so the gallery and the camera are both offered. */
:where(.filepick){display:flex;align-items:center;justify-content:center;gap:8px;min-height:var(--tap);padding:12px 16px;
  border:1.5px dashed var(--line2);border-radius:var(--r-control);background:var(--inset);color:var(--ink2);font-weight:600;cursor:pointer;text-align:center}
:where(.filepick input[type="file"]){position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
:where(.filepick){position:relative;flex-wrap:wrap}
:where(.filepick .hint){flex-basis:100%}
:where(.filepick > span){min-width:0;overflow-wrap:anywhere}
:where(.filepick:focus-within){border-color:var(--blue);box-shadow:var(--focus-ring)}

/* --------------------------------------------- public page shell (brand.js) --- */
:where(.ds-page){width:100%;max-width:var(--page-w,560px);margin:0 auto;padding:24px 16px 48px}
:where(.ds-brand){display:flex;align-items:center;gap:10px;margin:4px 0 22px;font-family:var(--font-display);font-weight:800;font-size:20px;letter-spacing:-.02em;color:var(--ink);text-decoration:none}
:where(.keymark){width:36px;height:36px;border-radius:11px;background:var(--navy);display:grid;place-items:center;flex:none}
:where(.keymark svg){width:19px;height:19px;stroke:var(--gold);stroke-width:2.1;fill:none;stroke-linecap:round;stroke-linejoin:round}
:where(.ds-page h1){font-size:var(--fs-xl);margin:0 0 6px}
:where(.ds-page .lead){color:var(--ink2);margin:0 0 18px;overflow-wrap:anywhere}
:where(.ds-stack){display:flex;flex-direction:column;gap:var(--sp-4)}
:where(.ds-foot){margin-top:28px;text-align:center;color:var(--ink3);font-size:var(--fs-xs)}
