/* ============================================================
   sotiris.site — shared chrome
   ------------------------------------------------------------
   Linked from every page BEFORE its own <style> block, so a page
   can still override anything here at equal specificity.

   Before this file existed there was no CSS file in the repo at
   all: nine pages each carried their own copy of everything
   below, and they had already drifted apart.
   ============================================================ */

/* ---------- Tokens ----------
   Every token any page needs, defined once. Where pages overlapped
   the values were already identical; the only real divergences were
   --ink (#000000 on the landing page, #0F414A everywhere else) and
   partner-signup's deliberate teal accent. Both still override below.
   ---------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* ground */
  --bg: #EFE8DF;
  --bg-elevated: #E4DBCC;

  /* brand */
  --maroon: #7F0303;
  --maroon-soft: #9C1F1F;
  --midnight: #0F414A;
  --tan: #D8BA98;
  --tan-light: #F0E2D1;
  --skyblue: #96C0CE;
  --green: #2E6B4F;
  --green-dim: rgba(46, 107, 79, 0.1);

  /* ink */
  --ink: #0F414A;
  --ink-dim: #4A5A5C;
  --ink-faint: #8A8378;

  /* surfaces */
  --glass-border: rgba(15, 65, 74, 0.14);
  --glass-bg: rgba(255, 255, 255, 0.4);

  /* accent — a page may repoint this; everything accented follows */
  --accent: var(--maroon);
  --accent-soft: var(--midnight);
  --accent-dim: rgba(127, 3, 3, 0.08);

  /* feedback — deliberately NOT tied to --accent, so an error stays red on a
     page that repoints the accent (partner-signup makes its accent teal) */
  --danger: #7F0303;
  --danger-dim: rgba(127, 3, 3, 0.08);
  --danger-line: rgba(127, 3, 3, 0.2);

  /* data — used by the dashboard charts */
  --chart-revenue: #C42032;
  --chart-cash: #7B47E0;
  --chart-in: #4ADE80;
  --chart-out: #FB7185;
  --chart-panel-ink: #E8F0F2;

  /* Lighter and darker stops of the two series colours. The client dashboard
     had these as loose hex in seven places, which read as a third red and a
     third purple rather than as ramps of the two that already existed. */
  --chart-revenue-lift: #E6394E;
  --chart-revenue-deep: #A3132A;
  --chart-revenue-deepest: #6B0210;
  --chart-cash-lift: #A279F2;
  --chart-cash-deep: #6B3FD4;
  --chart-cash-deepest: #3D2280;
  --green-bright: #2E9E5B;

  /* ---- Type scale ----
     Replaces the 28 distinct font sizes that were in use, seven of them
     half-pixel values. Steps are chosen at the centres of the clusters that
     were already there, so most declarations move by a pixel or less. */
  --text-2xs: 0.6875rem;   /* 11px — uppercase micro labels */
  --text-xs:  0.8125rem;   /* 13px — captions, table text */
  --text-sm:  0.9375rem;   /* 15px — body */
  --text-md:  1.0625rem;   /* 17px — lead paragraphs */
  --text-lg:  1.3125rem;   /* 21px — card and section headings */
  --text-xl:  1.6875rem;   /* 27px — big figures */
  --text-2xl: 2.5rem;      /* 40px — the largest number on a page */

  /* Headings stay fluid. One h2 step, not the two that had drifted apart. */
  --text-display: clamp(2.4rem, 4.6vw, 3.6rem);
  --text-h2:      clamp(1.7rem, 3.2vw, 2.3rem);

  /* ---- Leading and tracking ----
     Both are size-specific: large text needs tighter leading and negative
     tracking, small uppercase text needs positive tracking. A single value
     for either is wrong somewhere. */
  --leading-tight:   1.08;
  --leading-snug:    1.3;
  --leading-normal:  1.5;
  --leading-relaxed: 1.62;
  --tracking-display: -0.02em;
  --tracking-tight:   -0.01em;
  --tracking-label:    0.06em;

  /* ---- Radius ---- replaces 18 distinct values, including both 100px and
     999px used for pills in the same file. */
  --radius-1: 6px;
  --radius-2: 10px;
  --radius-3: 16px;
  --radius-4: 22px;
  --radius-pill: 999px;

  /* ---- Elevation ---- replaces 37 hand-tuned shadows. Three steps, tinted
     with the ink colour rather than neutral black, plus one accent glow. */
  --shadow-1: 0 1px 2px rgba(15, 65, 74, 0.05), 0 2px 8px -4px rgba(15, 65, 74, 0.12);
  --shadow-2: 0 2px 6px rgba(15, 65, 74, 0.05), 0 12px 28px -14px rgba(15, 65, 74, 0.30);
  --shadow-3: 0 4px 10px rgba(15, 65, 74, 0.05), 0 30px 60px -26px rgba(15, 65, 74, 0.38);
  --shadow-accent: 0 6px 26px -8px rgba(127, 3, 3, 0.42);
  --shadow-accent-soft: 0 6px 26px -8px rgba(15, 65, 74, 0.34);

  /* ---- Motion ----
     Four durations replace ten, two curves replace the browser default.
     ease-in is deliberately absent: it delays the first frame, which is the
     one the eye is on, so it reads as slower at the same duration. */
  --press: 0.97;          /* controls: a real, felt press */
  --press-settle: 0.995;  /* rows and cards: settle, do not shrink */
  --dur-press: 120ms;
  --dur-fast:  180ms;
  --dur-base:  240ms;
  --dur-slow:  400ms;
  --dur-reveal: 700ms;    /* scroll reveals: one value, replacing 0.55/0.6/0.625/0.7/0.8/0.9s */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* ---- Space ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 18px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  /* The film grain, written out once. It was pasted verbatim four times. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* type */
  --font-display: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-serif: 'Playfair Display', Georgia, serif;
  --font-body: 'Inter', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
}

/* ---------- Reset and document base ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.5;
  overflow-x: hidden;
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;

  /* Android paints a grey box on tap. Safe to drop now that every
     pressable element has its own :active feedback. */
  -webkit-tap-highlight-color: transparent;
}

a { color: inherit; text-decoration: none; }

/* ---------- Keyboard access — a focus ring that cannot be lost by accident, and a skip link ---------- */
/* Several controls clear their outline for looks; put a ring back for
   keyboard users only, so nothing changes on click. */
:focus-visible {
  /* !important because several controls clear their outline in a rule
     more specific than this one, and one does it inline. A focus ring
     should not be losable by accident. */
  outline: 2px solid var(--accent-soft) !important;
  outline-offset: 2px !important;
}

/* Lets a keyboard user jump the nav straight to the page content. Hidden
   until it is focused. */
.skip-link {
  position: absolute;
  left: 12px;
  top: 0;
  z-index: 100;
  background: var(--accent-soft);
  color: #fff;
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 10px 16px;
  border-radius: 0 0 8px 8px;
  transform: translateY(-140%);
  transition: transform var(--dur-fast) var(--ease-out);
}

.skip-link:focus { transform: translateY(0); }

/* ---------- Page furniture — the ambient wash, the grain, the container ---------- */
.ambient {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 900px 600px at 15% -5%, rgba(216, 186, 152, 0.3), transparent 60%),
    radial-gradient(ellipse 700px 500px at 90% 15%, rgba(150, 192, 206, 0.2), transparent 60%),
    radial-gradient(ellipse 800px 800px at 50% 100%, rgba(127, 3, 3, 0.04), transparent 60%);
}

.noise {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.02;
  mix-blend-mode: multiply;
  background-image: var(--grain);
}

.wrap {
  position: relative;
  z-index: 2;
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 32px;
  width: 100%;
}

main {
  position: relative;
  z-index: 2;
  flex: 1;
  padding: 48px 0 64px;
}

/* The auth pages centre a single card instead of flowing content down the page.
   Before this existed each of the four carried its own copy, and signup.html's
   had drifted to 72px where the other three were 56px. */
body.auth main {
  display: flex;
  align-items: center;
  padding: 56px 0;
}

/* ---------- Navigation ---------- */
nav {
  position: relative;
  z-index: 2;
  /* saturate compensates for the desaturation a blur causes, so the warm
     ground still reads warm through the bar */
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  background: rgba(239, 232, 223, 0.75);
  border-bottom: 1px solid var(--glass-border);
}

.nav-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 18px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.logo {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.01em;
}

.logo span { color: var(--accent-soft); }

.nav-back {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink-dim);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: color var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-out);
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.btn-logout {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink-dim);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  padding: 8px 16px;
  border-radius: var(--radius-2);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-out);
}

/* ---------- Footer ---------- */
footer {
  position: relative;
  z-index: 2;
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 32px 36px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--text-xs);
  color: var(--ink-faint);
  width: 100%;
}

.footer-links { display: flex; gap: 22px; }

/* ---------- The eyebrow pill ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 600;
  font-size: var(--text-xs);
  color: var(--accent-soft);
  background: var(--accent-dim);
  border: 1px solid var(--glass-border);
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  margin-bottom: 20px;
}

.eyebrow .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-soft);
  box-shadow: 0 0 8px var(--accent-soft);
}

/* ---------- Auth: shell, headings, card ---------- */
.form-shell {
  width: 100%;
  max-width: 440px;
  margin: 0 auto;
}

.form-head {
  text-align: center;
  margin-bottom: 36px;
}

.form-head h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-h2);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 10px;
}

.form-head h1 .accent-italic {
  /* --accent, not --maroon: partner-signup repoints the accent to teal and
     was rendering one maroon word above a teal button and a teal eyebrow. */
  color: var(--accent);
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 600;
}

.form-head p {
  font-size: var(--text-sm);
  color: var(--ink-dim);
}

.form-card {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-3);
  padding: 36px;
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
}

/* ---------- Auth: fields ---------- */
.field { margin-bottom: 20px; }

.field:last-of-type { margin-bottom: 0; }

.field label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 8px;
}

.field input {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink);
  background: rgba(255,255,255,0.55);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-2);
  padding: 12px 14px;
  outline: none;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.field input::placeholder { color: var(--ink-faint); }

.field input:focus {
  border-color: var(--accent-soft);
  background: rgba(255,255,255,0.8);
}

/* ---------- Auth: submit and errors ---------- */
.btn-submit {
  width: 100%;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  padding: 14px 24px;
  border-radius: var(--radius-2);
  background: var(--accent);
  color: #fff;
  border: none;
  cursor: pointer;
  margin-top: 28px;
  transition: box-shadow var(--dur-base) var(--ease-out), transform var(--dur-press) var(--ease-out);
}

.btn-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.form-error {
  display: none;
  font-size: var(--text-xs);
  color: var(--danger);
  background: var(--danger-dim);
  border: 1px solid var(--danger-line);
  border-radius: var(--radius-2);
  padding: 10px 14px;
  margin-top: 18px;
}

/* ---------- Auth: the pending panel shown after signup ---------- */
/* ---------- PENDING PANEL (shown if account not yet verified) ---------- */
.pending-panel {
  display: none;
  text-align: center;
  padding: 12px 4px 4px;
}

.pending-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--accent-dim);
  border: 1px solid var(--glass-border);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 22px;
}

.pending-icon svg {
  width: 24px;
  height: 24px;
  color: var(--accent-soft);
}

.pending-panel h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  margin-bottom: 10px;
  line-height: 1.3;
}

.pending-panel .pending-sub {
  font-size: var(--text-xs);
  color: var(--ink-faint);
  max-width: 320px;
  margin: 0 auto;
}

/* ---------- Phone ----------
   Everything here was written for a 1180px canvas. 64px of gutter out of a
   390px screen is a sixth of it. admin-dashboard had a block like this of its
   own; partner-dashboard and client-detail had nothing, so they shipped the
   desktop canvas to a phone. It belongs to the shared chrome, not to one page. */
@media (max-width: 640px) {
  .wrap { padding-left: 16px; padding-right: 16px; }
  .nav-inner { padding: 13px 16px; gap: 10px; }
  .logo { font-size: var(--text-xs); line-height: 1.25; }
  .nav-actions { gap: 7px; flex-shrink: 0; }

  footer { flex-direction: column; gap: 12px; text-align: center; padding: 24px 16px 32px; }
  .footer-links { gap: 18px; }

  /* A four-across tab row does not fit; scroll it rather than wrap it. */
  .tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tab-btn { white-space: nowrap; flex-shrink: 0; }
}

@media (max-width: 500px) {
  .form-card { padding: 28px 24px; }
}

/* ---------- Touch targets ----------
   A 30px close button is under half the area a thumb needs. The icon inside
   stays the size it was; only the target grows. */
@media (pointer: coarse) {
  .modal-close,
  .counter-btn,
  .cal-nav-btn,
  .tracker-nav-btn,
  .btn-quiet,
  .pw-toggle { min-width: 44px; min-height: 44px; }
}

/* ---------- Pointer-only hover ----------
   A touch screen has no hover to leave, so an ungated :hover latches
   after a tap and the control stays lit until you tap something else. */
@media (hover: hover) and (pointer: fine) {
  .nav-back:hover { color: var(--ink); }

  .btn-logout:hover {
    border-color: var(--midnight);
    background: rgba(15, 65, 74, 0.06);
  }

  .footer-links a:hover { color: var(--ink); }

  .btn-submit:hover {
    box-shadow: var(--shadow-accent);
    transform: translateY(-1px);
  }
}

/* ---------- Press ----------
   Feedback on pointer-down, not on release: waiting for the click to
   land is exactly the lag that makes an interface feel dead. */
.btn-submit:active,
.btn-logout:active,
.nav-back:active {
  transform: scale(var(--press));
}

/* ---------- Reduced motion ----------
   scroll-behavior: smooth was never reset, so a reduced-motion user still got
   thrown down the page by every in-page link. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ---------- Reduced transparency ----------
   The site leans on backdrop-filter for its nav and cards. Asked for less
   transparency, make those surfaces solid rather than frosted. */
@media (prefers-reduced-transparency: reduce) {
  nav {
    background: var(--bg);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .form-card {
    background: #FBF8F4;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .ambient, .noise { display: none; }
}

/* ---------- More contrast ----------
   Hairlines at 14% alpha disappear for anyone who asked for more contrast.
   Give every edge a real border and drop the wash behind the text. */
@media (prefers-contrast: more) {
  :root {
    --glass-border: rgba(15, 65, 74, 0.55);
    --glass-bg: #FFFFFF;
    --ink-dim: #2C3A3C;
    --ink-faint: #4A4436;
  }
  nav { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
  .field input { border-width: 2px; }
  .ambient, .noise { display: none; }
}

/* ---------- Auth: the quiet secondary button ----------
   This was .btn-signup on the login page and .btn-login on both sign-up
   pages: two names, character-for-character the same rule. */
.btn-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-sm);
  padding: 11px 26px;
  border-radius: var(--radius-2);
  color: var(--ink);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  transition: border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .btn-quiet:hover { border-color: var(--midnight); background: rgba(15, 65, 74, 0.06); transform: translateY(-1px); }
}
.btn-quiet:active { transform: scale(var(--press)); }

/* ---------- Auth: password fields ----------
   The two sign-up pages ask for the password twice and offered no way to
   check what you typed. */
.field-input { position: relative; display: flex; }
.field-input input { padding-right: 46px; }
.pw-toggle {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: var(--ink-faint);
  cursor: pointer;
  border-radius: var(--radius-1);
  transition: color var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.pw-toggle:active { transform: translateY(-50%) scale(var(--press)); }
@media (hover: hover) and (pointer: fine) {
  .pw-toggle:hover { color: var(--ink); }
}
.pw-toggle .eye-open { display: none; }
.pw-toggle[aria-pressed="true"] .eye-open { display: block; }
.pw-toggle[aria-pressed="true"] .eye-shut { display: none; }

/* Chrome paints its own opaque yellow-white over autofilled inputs, which
   wipes out the glass fill on exactly the fields people autofill most.
   The inset shadow trick is the only way to override it. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 40px #F7F3EE inset;
  caret-color: var(--ink);
  transition: background-color 9999s ease-out;
}

/* ---------- Auth: the pending panel ----------
   Was a hard display swap — the form vanished and the panel appeared on the
   same frame, with no relationship between them. */
.form-shell.showing-pending .form-head,
.form-shell.showing-pending .form-panel { display: none; }
.form-shell.showing-pending .pending-panel {
  display: block;
  animation: panel-in var(--dur-base) var(--ease-out) both;
}
@keyframes panel-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .form-shell.showing-pending .pending-panel { animation: none; }
}

/* ---------- Reduced motion, everywhere ----------
   The five app pages had no prefers-reduced-motion rule of any kind, while
   carrying chart draws, growing bars and sliding sheets. The landing page
   handles its own set-pieces above; this is the backstop for everything
   else, including anything added later. Press feedback survives it: at this
   duration the scale still reads as a state change, just without travel. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
