/* ================================================================
   MARKO REAL ESTATE — Design System v3
   Premium real-estate platform · Restrained, photography-first
   Typography: Raleway (display/headings) + Inter (UI/body)
   ----------------------------------------------------------------
   Tokens, reset, base typography, focus and utilities. Every other
   stylesheet in this folder builds on the custom properties declared
   here, so this file loads first on every page.

   Load order (see views/layout.php and views/public/layout.php):
     design-system → layout → components → pages/* → responsive
   responsive.css is last on purpose: its narrow-width rules override
   component defaults and must win on source order.
   ================================================================ */

/* Both families are self-hosted — no CDN, works fully offline. */
@import url('../vendor/inter/inter.css');
@import url('../vendor/raleway/raleway.css');

/* ─── Tokens ────────────────────────────────────────────── */
:root {
  /* This is a light-only product, and saying so matters. The parts of a
     form the browser paints itself — <select> dropdown lists, scrollbars,
     autofill, date pickers — follow the OS scheme unless the page declares
     one. On a dark-mode Windows that meant Chrome drew the option list in
     pale system text over the white background --surface sets below, so
     agent and owner names came out white on white and looked empty. */
  color-scheme: light;

  /* ── Typefaces ─────────────────────────────────────────
     --font        UI + body copy (Inter: superb at small sizes)
     --font-display Headings (Raleway: elegant, property-brand feel)
     --font-mono   Codes, IDs, receipts                          */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Raleway', 'Inter', -apple-system, 'Segoe UI', sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Monaco, Consolas, monospace;

  /* ── Type scale ────────────────────────────────────────
     Fluid where it matters, fixed where consistency matters. */
  /* Fluid headings are tuned from the phone end first: a 36px hero title
     eats a third of a 393px screen before the search box is reached, so the
     lower bound is set to what reads well at 360-430px and the upper bound
     is left where it was for desktop. */
  --fs-display: clamp(1.9rem, 1.29rem + 2.66vw, 3.35rem); /* hero h1  31px @390 */
  --fs-h1:      clamp(1.65rem, 1.25rem + 1.75vw, 2.6rem); /* page title  */
  --fs-h2:      clamp(1.4rem, 1.12rem + 1.25vw, 2.1rem);  /* section     */
  --fs-h3:      1.3rem;                                   /* card lead   */
  --fs-h4:      1.05rem;                                  /* card title  */
  --fs-body:    0.95rem;
  --fs-sm:      0.86rem;
  --fs-xs:      0.78rem;
  --fs-2xs:     0.72rem;                                  /* labels/meta */

  --lh-tight: 1.2;
  --lh-snug:  1.4;
  --lh-body:  1.65;
  --lh-loose: 1.75;

  /* ── Brand ─────────────────────────────────────────────
     A confident architectural blue. Reads as trust + finance
     without the coldness of pure navy. AA on white (4.9:1). */
  --primary: #0075c0;
  --primary-hover: #005f9e;
  --primary-dark: #004f84;
  --primary-light: #e6f2fa;   /* tinted fill for badges/icons */
  --primary-tint: #f2f8fc;    /* faintest wash                */
  --primary-ring: rgba(0,117,192,.18);
  --primary-border: rgba(0,117,192,.28);
  /* Text-on-tint variant. --primary is 4.28:1 on --primary-light, which
     fails AA for anything under 18.66px bold. This is 5.9:1 on the same
     tint and 6.7:1 on white, so it is safe for labels, tags and chips. */
  --primary-ink: #005f9e;

  /* ── Neutral surfaces ──────────────────────────────────
     Cool-tinted so white photography sits cleanly on top. */
  --bg: #f6fafc;
  --surface: #ffffff;
  --surface-2: #fafcfd;
  --surface-3: #eef3f6;

  /* Deep "ink" surfaces — footers, CTA bands, dark sections. */
  --ink: #10222c;
  --ink-2: #1a3341;
  --ink-3: #244353;

  /* ── Borders ───────────────────────────────────────────
     Hairlines. The reference gets its calm from thin borders
     doing the work that heavy shadows usually do. */
  --border: #e4eaee;
  --border-strong: #cdd8df;

  /* ── Text ──────────────────────────────────────────────
     Headings are near-black slate; body is warmer and softer
     so long descriptions don't fatigue. All AA on white.  */
  --text: #1d3340;        /* headings              14.0:1 */
  --text-body: #4c566a;   /* paragraphs             7.6:1 */
  --text-muted: #5f6b7e;  /* secondary/meta         6.0:1 */
  --text-subtle: #6b7688; /* tertiary, still AA     5.1:1 */

  /* Sidebar (admin shell) — deep navy rail
     The rail is the one dark surface in a light product. That is deliberate:
     it separates "where you are in the system" from "what you are looking
     at", so the white content column reads as the whole page rather than a
     panel floating inside a frame.

     Every value below is measured against --sidebar-bg, because a dark
     surface fails quietly — grey that is comfortable on white disappears
     here. Resting labels 8.6:1, section headings and meta 5.3:1, and the
     active row is a solid brand fill (white on --primary is 4.9:1) rather
     than a tint, which has nowhere near enough separation on navy. */
  /* A true navy rather than the teal-leaning ink used elsewhere. It is the
     bluest this can go and still clear every threshold: pushing further
     toward #152a45 drops the active pill's edge to 2.97:1 against the rail,
     under the 3:1 a filled control needs to read as a distinct surface. */
  --sidebar-bg: #14263d;
  --sidebar-bg-soft: rgba(255,255,255,.055);   /* profile card, search field */
  --sidebar-border: rgba(255,255,255,.09);
  --sidebar-border-strong: rgba(255,255,255,.16);
  --sidebar-text: #a9c0d0;        /* resting nav label        8.1:1 */
  --sidebar-text-strong: #ffffff; /* brand, active, profile  15.3:1 */
  --sidebar-muted: #7d97a9;       /* headings, meta, kbd      5.0:1 */
  --sidebar-active-bg: var(--primary);
  --sidebar-active-text: #ffffff;
  --sidebar-hover-bg: rgba(255,255,255,.07);
  /* One column width for the icon box, so every label starts on the same
     x regardless of how wide each glyph happens to draw. */
  --sidebar-icon-col: 20px;
  --sidebar-width: 248px;

  /* ── Status ────────────────────────────────────────────
     Kept semantic: green still means available/paid, never brand. */
  --success: #15803d;
  --success-bg: #ecfdf3;
  --warning: #b45309;
  --warning-bg: #fffbeb;
  --danger: #c81e1e;
  --danger-bg: #fef2f2;
  --info: #005f9e;
  --info-bg: #e6f2fa;
  --purple: #6d28d9;
  --purple-bg: #f5f3ff;
  --orange: #c2410c;
  --orange-bg: #fff7ed;
  --gold: #d97706;        /* rating stars */

  /* ── Geometry ──────────────────────────────────────────
     Tight radii read as architectural/editorial. Large radii
     read as consumer-app; the reference stays at 6-8px.    */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius: 8px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  /* ── Spacing scale (4px base) ──────────────────────────  */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;
  --space-4: 16px;  --space-5: 20px;  --space-6: 24px;
  --space-8: 32px;  --space-10: 40px; --space-12: 48px;
  --space-16: 64px; --space-20: 80px; --space-24: 96px;

  /* ── Table density ─────────────────────────────────────
     Declared here, not only in tokens-app.css, because .table lives in
     components.css and components.css ships in all three bundles — a
     token defined only for the application would resolve to nothing on
     a public page and collapse the cell padding to zero.

     These are the values the table has always had. tokens-app.css
     raises them for the console; the marketing site keeps them. */
  --cell-x: 16px;
  --cell-y: 13px;
  --cell-head-y: 11px;

  /* Card rhythm and the card heading size. tokens-app.css sets the
     figures the console actually uses; these exist so the shared
     components.css ships no unresolved var() in the public bundle.
     The marketing site renders none of .card, .badge, .table or the
     stat tiles — it has its own components — so these are a
     correctness measure rather than a visual one. */
  --card-radius: 10px;
  --card-pad-x: 18px;
  --card-pad-y: 13px;
  --fs-title: 1.0625rem;

  /* Control heights. These live here, not in tokens-app.css, because .btn is
     in components.css and components.css ships in all three bundles — the
     marketing site has 64 buttons. Declared only for the console, the height
     resolved to `auto` there while `padding:0 16px` still applied, which
     collapsed every public button to its line box. */
  --control-h:    40px;
  --control-h-sm: 34px;
  --control-h-lg: 44px;

  /* Vertical rhythm for marketing sections */
  --section-y: 80px;
  --section-y-sm: 56px;
  --section-head-gap: 48px;
  --container: 1240px;
  --gutter: 24px;

  /* ── Elevation ─────────────────────────────────────────
     Deliberately faint. Depth comes from borders + imagery.
     Two-layer from --sm upward: a tight contact shadow keeps the card
     anchored to the page while the wider, softer layer does the lifting,
     which is what stops a raised card looking like it is floating free. */
  --shadow-xs: 0 1px 2px rgba(29,51,64,.05);
  --shadow-sm: 0 1px 2px rgba(29,51,64,.05), 0 2px 6px -2px rgba(29,51,64,.06);
  --shadow-md: 0 2px 4px -2px rgba(29,51,64,.06), 0 8px 20px -6px rgba(29,51,64,.11);
  --shadow-lg: 0 4px 10px -4px rgba(29,51,64,.07), 0 16px 38px -10px rgba(29,51,64,.15);
  --shadow-xl: 0 20px 48px rgba(29,51,64,.14);
  --ring: 0 0 0 3px var(--primary-ring);

  /* ── Motion ────────────────────────────────────────────
     Three durations and three curves, chosen by what is moving rather
     than copied from one blanket value:

       --dur-fast   a colour or a border changing under the cursor
       --dur-base   something appearing in place — a menu, a panel
       --dur-slow   something crossing the screen — a drawer, a sheet

     The curves carry direction. Things arriving decelerate, things
     leaving accelerate, and an exit is deliberately quicker than the
     matching entrance: a dialog that takes as long to go as it took to
     arrive reads as unresponsive.

     --transition and --transition-slow are kept and re-derived from
     the durations, so every `transition: x var(--transition)` already
     written across these stylesheets picks the system up without being
     touched. --transition keeps its exact previous value.           */
  --dur-fast: 120ms;
  --dur-base: 180ms;
  --dur-slow: 280ms;

  --ease-standard: cubic-bezier(.4,0,.2,1);   /* symmetric, in-place  */
  --ease-enter:    cubic-bezier(.16,1,.3,1);  /* decelerate, arriving */
  --ease-exit:     cubic-bezier(.4,0,1,1);    /* accelerate, leaving  */

  --transition-fast: var(--dur-fast) var(--ease-standard);
  --transition:      var(--dur-base) var(--ease-standard);
  --transition-slow: var(--dur-slow) var(--ease-standard);
  /* Retained name — --ease-enter is the same curve under the label the
     rest of the system now uses. Both resolve identically. */
  --ease-out: cubic-bezier(.16,1,.3,1);

  /* Drives both the admin topbar and the sidebar's brand row, so the two
     stay on one line across the top of the shell. Every pixel here is one
     the dashboard does not get, so it is kept to what the 38px controls
     inside it actually need. */
  --header-height: 62px;
  --navbar-height: 72px;
}

/* ─── Reset / Base ──────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{font-size:16px;scroll-behavior:smooth}
body{
  font-family:var(--font);
  font-size:var(--fs-body);
  color:var(--text-body);
  background:var(--bg);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  font-feature-settings:"cv02","cv03","cv04","cv11";
}
h1,h2,h3,h4,h5,h6{
  font-family:var(--font-display);
  color:var(--text);
  line-height:var(--lh-tight);
  font-weight:700;
  letter-spacing:-.01em;
}
a{color:var(--primary);text-decoration:none;transition:color var(--transition)}
a:hover{color:var(--primary-hover)}
img{max-width:100%;display:block}
button{cursor:pointer;font-family:inherit}
input,select,textarea{font-family:inherit;font-size:var(--fs-sm);color:var(--text)}
::selection{background:var(--primary-light);color:var(--text)}

/* Safety net for engines that render the dropdown list before honouring
   color-scheme. Only under a dark OS, where the bug lives — the light path
   is left alone so the list keeps its native highlight and hover feel. */
@media (prefers-color-scheme: dark){
  select option,select optgroup{background-color:var(--surface);color:var(--text)}
  select option:checked{background-color:var(--primary-light);color:var(--primary-ink)}
  select option:disabled{color:var(--text-subtle)}
  select optgroup{font-weight:600;color:var(--text-muted)}
}

/* Global keyboard focus. Never removed — only restyled, and always
   visible against both light surfaces and dark/ink sections. */
:focus-visible{
  outline:2px solid var(--primary);
  outline-offset:2px;
  border-radius:var(--radius-xs);
}
.on-ink :focus-visible,.section--dark :focus-visible{outline-color:#fff}

/* ─── Utilities ─────────────────────────────────────────── */
/* Screen-reader-only text. Visible to assistive tech, invisible on screen,
   and becomes visible if it ever receives focus — which is what makes it
   safe to use on a skip link as well as on a label. Every bundle gets it:
   an icon-only control needs a name on the admin side just as much as on
   the marketing site. */
/* Skip link: the first tab stop on every page, invisible until it has focus.
   It lived in public.css, which meant the one on the sign-in page rendered
   unstyled and permanently visible — and the application shell, the place
   with a long rail to tab past, had none at all. */
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:9999;
  background:var(--primary);color:#fff;
  padding:12px 20px;border-radius:0 0 var(--radius) 0;
  font-size:var(--fs-sm);font-weight:600;
}
.skip-link:focus{left:0;color:#fff}

.sr-only{
  position:absolute!important;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
.sr-only:focus,.sr-only:focus-within{
  position:static!important;width:auto;height:auto;
  margin:0;overflow:visible;clip:auto;white-space:normal;
}

.text-muted{color:var(--text-muted)!important}
.text-subtle{color:var(--text-subtle)!important}
.text-primary{color:var(--primary)!important}
.text-success{color:var(--success)!important}
.text-danger{color:var(--danger)!important}
.text-warning{color:var(--warning)!important}
.mt-1{margin-top:8px}.mt-2{margin-top:16px}.mt-3{margin-top:24px}
.mb-1{margin-bottom:8px}.mb-2{margin-bottom:16px}.mb-3{margin-bottom:24px}
.d-flex{display:flex}.align-center{align-items:center}.gap-1{gap:8px}.gap-2{gap:16px}
.justify-between{justify-content:space-between}
.justify-end{justify-content:flex-end}
.w-100{width:100%}
