/* Turno design system — Apple HIG adapted for web/PWA.
   Semantic tokens auto-adapt to light/dark; all sizes scale with Dynamic Type. */

:root {
  /* System colors — light */
  --sys-blue: #007AFF;
  --sys-blue-dark: #0040DD;
  --sys-green: #34C759;
  --sys-green-dark: #248A3D;

  /* Accessible pairs. Vivid system colors are tuned for large glyphs, so plain
     `#007AFF` only reaches ~4.0:1 on white and white-on-`#34C759` ~1.9:1.
     `-fill` sits behind white text, `-text` is used for text/icons. Both clear AA. */
  --sys-blue-fill: #0067D6;
  --sys-blue-text: #0A5AAE;
  --sys-green-fill: #1D7A34;
  --sys-green-text: #1D7A34;
  --sys-red-fill: #C0261E;
  --sys-red-text: #C0261E;
  --sys-orange-fill: #8A5200;
  --sys-orange-text: #8A5200;
  --sys-red: #FF3B30;
  --sys-red-dark: #D70015;
  --sys-orange: #FF9500;
  --sys-indigo: #5856D6;
  --sys-teal: #30B0C7;
  --sys-gray: #8E8E93;

  /* Semantic labels.
     Apple's secondaryLabel is 60% alpha, which composites to #8A8A8E on white
     (3.3:1) and fails WCAG AA for small text. Nudged to 72% for ~4.7:1 while
     keeping the tonal hierarchy intact. */
  --label: #000000;
  --label-secondary: rgba(60, 60, 67, 0.76);
  --label-tertiary: rgba(60, 60, 67, 0.48);
  --label-quaternary: rgba(60, 60, 67, 0.22);
  --label-inverse: #FFFFFF;

  /* Backgrounds */
  --bg: #FFFFFF;
  --bg-secondary: #F2F2F7;
  --bg-tertiary: #FFFFFF;
  --bg-grouped: #F2F2F7;
  --bg-grouped-secondary: #FFFFFF;
  --bg-elevated: #FFFFFF;

  /* Fills — for non-text UI on top of backgrounds */
  --fill: rgba(120, 120, 128, 0.20);
  --fill-secondary: rgba(120, 120, 128, 0.16);
  --fill-tertiary: rgba(118, 118, 128, 0.12);
  --fill-quaternary: rgba(116, 116, 128, 0.08);

  /* Separators */
  --separator: rgba(60, 60, 67, 0.29);
  --separator-opaque: #C6C6C8;

  /* Materials */
  --material-thick: rgba(255, 255, 255, 0.80);
  --material-regular: rgba(255, 255, 255, 0.72);
  --material-thin: rgba(255, 255, 255, 0.60);
  --material-blur: saturate(180%) blur(20px);

  /* Tint — brand accent maps to systemBlue family */
  --tint: var(--sys-blue);
  --tint-pressed: #0062CC;

  /* Elevation — Apple uses soft, low-spread shadows */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.06);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-3: 0 8px 28px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.06);

  /* Continuous-corner radii */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-2xl: 26px;

  /* Standard Apple timing curves */
  --ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Hairline — 1 physical pixel on retina */
  --hairline: 0.5px;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --sys-blue: #0A84FF;
    --sys-blue-dark: #409CFF;
    --sys-green: #30D158;
    --sys-green-dark: #30DB5B;
    --sys-red: #FF453A;
    --sys-red-dark: #FF6961;
    --sys-orange: #FF9F0A;

    /* On dark, vivid fills need white text kept but pushed darker for AA;
       text colors instead go lighter than the base hue. */
    --sys-blue-fill: #0A6FD8;
    --sys-blue-text: #6FB6FF;
    --sys-green-fill: #1F7A38;
    --sys-green-text: #4EE06E;
    --sys-red-fill: #C8342A;
    --sys-red-text: #FF8A80;
    --sys-orange-fill: #9A5F00;
    --sys-orange-text: #FFB84D;
    --sys-indigo: #5E5CE6;
    --sys-teal: #40C8E0;
    --sys-gray: #8E8E93;

    --label: #FFFFFF;
    --label-secondary: rgba(235, 235, 245, 0.60);
    --label-tertiary: rgba(235, 235, 245, 0.30);
    --label-quaternary: rgba(235, 235, 245, 0.18);
    --label-inverse: #000000;

    --bg: #000000;
    --bg-secondary: #1C1C1E;
    --bg-tertiary: #2C2C2E;
    --bg-grouped: #000000;
    --bg-grouped-secondary: #1C1C1E;
    --bg-elevated: #1C1C1E;

    --fill: rgba(120, 120, 128, 0.36);
    --fill-secondary: rgba(120, 120, 128, 0.32);
    --fill-tertiary: rgba(118, 118, 128, 0.24);
    --fill-quaternary: rgba(116, 116, 128, 0.18);

    --separator: rgba(84, 84, 88, 0.65);
    --separator-opaque: #38383A;

    --material-thick: rgba(28, 28, 30, 0.80);
    --material-regular: rgba(28, 28, 30, 0.72);
    --material-thin: rgba(28, 28, 30, 0.60);

    --tint-pressed: #409CFF;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.30);
    --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.40);
    --shadow-3: 0 8px 28px rgba(0, 0, 0, 0.55);
  }
}

/* Increase Contrast support */
@media (prefers-contrast: more) {
  :root {
    --label-secondary: rgba(60, 60, 67, 0.85);
    --label-tertiary: rgba(60, 60, 67, 0.60);
    --separator: rgba(60, 60, 67, 0.65);
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --label-secondary: rgba(235, 235, 245, 0.90);
      --label-tertiary: rgba(235, 235, 245, 0.65);
      --separator: rgba(84, 84, 88, 1);
    }
  }
}

/* ── Typography ─────────────────────────────────────────────
   Apple text styles. rem-based so browser/OS font scaling works. */

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

/* ── Overflow containment ──────────────────────────────────
   Long unbroken strings (emails, clinic names, URLs) must never widen the
   page. On phones that shifts the layout sideways instead of scrolling,
   because the app screens are position:fixed and clip rather than scroll.

   `clip` rather than `hidden`: per spec a non-visible overflow-x makes
   overflow-y compute to `auto`, so `hidden` turned both html and body into
   scroll containers and Android Chrome then refused to scroll with one
   finger (two-finger panning still worked). `clip` leaves overflow-y
   `visible`. The `hidden` line stays as the fallback for pre-Safari-16. */
html, body { max-width: 100%; overflow-x: hidden; overflow-x: clip; }

/* Flex and grid children default to min-width:auto, so they refuse to shrink
   below their content and push the row past the viewport. */
.flex > *, .grid > * { min-width: 0; }

/* A column flex with centered items sizes children to max-content, so an
   unbroken string makes the child wider than the row and it spills out both
   sides. min-width:0 alone does not stop that — the cap has to be explicit. */
.flex > *, .grid > * { max-width: 100%; }

/* But avatars, icon chips, dots and dividers carry an explicit width and must
   keep it — min-width:0 would otherwise let them squash into ovals.
   Leading space in the match avoids catching max-w-* on text blocks. */
.flex > [class^="w-"]:not([class*="w-full"]):not([class*="w-auto"]),
.flex > [class*=" w-"]:not([class*="w-full"]):not([class*="w-auto"]),
.flex > .mi,
.flex > .spinner { flex-shrink: 0; }

/* Six fixed 48px boxes plus gaps exceed a 320px screen, so the OTP row is
   fluid: each field shares the width instead of holding a hard size.
   The width override is needed because Tailwind's w-12 would otherwise
   pin each box at 48px regardless of flex-basis. */
#otp-fields { display: flex; gap: 0.5rem; justify-content: center; width: 100%; }
#otp-fields > input {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  max-width: 3rem;
  padding-left: 0;
  padding-right: 0;
  /* align-self:stretch above would collapse these to the row's 40px */
  align-self: auto;
  height: 3.5rem;
  min-height: 3.5rem;
}

/* Text containers wrap mid-word only when there is no other option. */
p, h1, h2, h3, h4, span, div, label, td, th, li, a, button {
  overflow-wrap: break-word;
}

img, svg, video, canvas { max-width: 100%; }

body {
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display',
               'Inter', 'Segoe UI', Roboto, system-ui, sans-serif;
  font-size: 1.0625rem;      /* 17pt body */
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--label);
  background: var(--bg-grouped);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.t-large-title { font-size: 2.125rem; line-height: 1.206; font-weight: 700; letter-spacing: 0.008em; }
.t-title-1     { font-size: 1.75rem;  line-height: 1.214; font-weight: 700; letter-spacing: 0.007em; }
.t-title-2     { font-size: 1.375rem; line-height: 1.273; font-weight: 700; letter-spacing: 0.008em; }
.t-title-3     { font-size: 1.25rem;  line-height: 1.25;  font-weight: 600; letter-spacing: 0.012em; }
.t-headline    { font-size: 1.0625rem;line-height: 1.294; font-weight: 600; letter-spacing: -0.024em; }
.t-body        { font-size: 1.0625rem;line-height: 1.294; font-weight: 400; letter-spacing: -0.024em; }
.t-callout     { font-size: 1rem;     line-height: 1.3125;font-weight: 400; letter-spacing: -0.020em; }
.t-subhead     { font-size: 0.9375rem;line-height: 1.333; font-weight: 400; letter-spacing: -0.016em; }
.t-footnote    { font-size: 0.8125rem;line-height: 1.385; font-weight: 400; letter-spacing: -0.006em; }
.t-caption-1   { font-size: 0.75rem;  line-height: 1.333; font-weight: 400; letter-spacing: 0; }
.t-caption-2   { font-size: 0.6875rem;line-height: 1.182; font-weight: 400; letter-spacing: 0.006em; }

/* Numeric readouts (token numbers, counts, timers) — tabular so digits don't jitter */
.t-numeric {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  letter-spacing: -0.02em;
}

/* ── Touch targets ─────────────────────────────────────────
   HIG minimum is 44×44pt. Applied via pseudo-element so small
   glyph buttons keep their visual size but gain a full hit area. */
.hit-44 { position: relative; min-width: 44px; min-height: 44px; }
button, [role="button"], .tab, a.btn { touch-action: manipulation; }

button:not(.no-min), [role="button"]:not(.no-min) { min-height: 44px; }

/* Circular glyph buttons are sized by matching w-/h- classes. The 44px floor
   above stretches a 40px circle into an oval, so restore their own height and
   give them the required hit area through a pseudo-element instead. */
button.rounded-full[class*="w-"][class*="h-"]:not(.no-min) {
  min-height: 0;
  position: relative;
}
button.rounded-full[class*="w-"][class*="h-"]:not(.no-min)::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: max(100%, 44px);
  height: max(100%, 44px);
}

/* ── Materials ─────────────────────────────────────────────
   Translucent control layers that sit above content. */
.material-bar {
  background: var(--material-regular);
  -webkit-backdrop-filter: var(--material-blur);
  backdrop-filter: var(--material-blur);
}
.material-thick {
  background: var(--material-thick);
  -webkit-backdrop-filter: var(--material-blur);
  backdrop-filter: var(--material-blur);
}

/* Fallback when backdrop-filter is unsupported — must stay opaque for legibility */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .material-bar, .material-thick { background: var(--bg); }
}

@media (prefers-reduced-transparency: reduce) {
  .material-bar, .material-thick {
    background: var(--bg);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* Hairline separators — true 1px, not Tailwind's border */
.hairline-t { border-top: var(--hairline) solid var(--separator); }
.hairline-b { border-bottom: var(--hairline) solid var(--separator); }

/* Scroll edge effect — content fades under a translucent bar */
.scroll-edge-top {
  background: linear-gradient(to bottom, var(--bg-grouped) 40%, transparent);
}

/* ── Controls ──────────────────────────────────────────────*/

/* Filled button — the primary action */
.btn-filled {
  background: var(--tint);
  color: #FFFFFF;
  border-radius: var(--r-md);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.024em;
  padding: 0.875rem 1.25rem;
  border: none;
  transition: transform 0.12s var(--ease-standard), opacity 0.12s var(--ease-standard);
}
.btn-filled:active:not(:disabled) { transform: scale(0.97); opacity: 0.85; }
.btn-filled:disabled { opacity: 0.35; }

/* Tinted button — secondary action */
.btn-tinted {
  background: color-mix(in srgb, var(--tint) 15%, transparent);
  color: var(--tint);
  border-radius: var(--r-md);
  font-weight: 600;
  border: none;
}
.btn-tinted:active:not(:disabled) { transform: scale(0.97); }

/* Plain button — tertiary / inline action */
.btn-plain {
  background: transparent;
  color: var(--tint);
  font-weight: 400;
  border: none;
}

.btn-destructive { background: var(--sys-red); color: #FFFFFF; }

/* ── Action sheet (replaces native confirm()) ─────────────────────────── */
.sheet-scrim {
  position: fixed; inset: 0; z-index: 400;
  background: rgba(0, 0, 0, 0.4);
  display: flex; align-items: flex-end; justify-content: center;
  opacity: 0; transition: opacity 0.25s var(--ease-standard);
  padding: 8px;
}
.sheet-scrim.open { opacity: 1; }
@supports (backdrop-filter: blur(4px)) {
  .sheet-scrim { backdrop-filter: blur(4px); }
}
.action-sheet {
  width: 100%; max-width: 420px;
  transform: translateY(16px);
  transition: transform 0.3s var(--ease-out);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.sheet-scrim.open .action-sheet { transform: translateY(0); }
.action-sheet .group {
  background: var(--material-thick);
  border-radius: var(--r-lg);
  overflow: hidden;
  margin-bottom: 8px;
}
@supports (backdrop-filter: blur(20px)) {
  .action-sheet .group { backdrop-filter: var(--material-blur); }
}
@supports not (backdrop-filter: blur(20px)) {
  .action-sheet .group { background: var(--bg-elevated); }
}
.action-sheet .msg {
  padding: 18px 16px 14px; text-align: center;
  border-bottom: var(--hairline) solid var(--separator);
}
.action-sheet .msg strong {
  display: block; font-size: 0.9375rem; font-weight: 600;
  color: var(--label); margin-bottom: 3px;
}
.action-sheet .msg span {
  font-size: 0.8125rem; color: var(--label-secondary); line-height: 1.35;
}
.action-sheet button {
  display: block; width: 100%; min-height: 57px;
  background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 1.25rem; color: var(--sys-blue-text);
  border-bottom: var(--hairline) solid var(--separator);
  transition: background 0.1s var(--ease-standard);
}
.action-sheet button:last-child { border-bottom: none; }
.action-sheet button:active { background: var(--fill-tertiary); }
.action-sheet button.danger { color: var(--sys-red-text); }
.action-sheet button.cancel { font-weight: 600; }
.action-sheet .group.cancel-group { margin-bottom: 0; }

/* Text inputs sit inside padded flex wrappers, so their own box can end up
   only ~20px tall. Stretch them to the full row height so the whole field is
   tappable, not just the middle sliver. */
input[type="tel"], input[type="email"], input[type="password"],
input[type="text"], input[type="number"], input[type="search"] {
  align-self: stretch;
  min-height: 40px;
}

/* iOS Safari/Chrome zoom into any field whose text is under 16px, and because
   the screens are position:fixed the zoomed viewport pans sideways and can't
   pan back. Raising the size on touch devices prevents the zoom; capping it
   with maximum-scale would work too but would also disable pinch-zoom. */
@media (hover: none) and (pointer: coarse) {
  /* The :not() chains also lift specificity above Tailwind's .text-sm, which a
     bare element selector would lose to. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select:not([hidden]),
  textarea:not([hidden]) { font-size: 16px; }
}

/* ── Skip link — visible only once focused by keyboard ───────────────── */
.skip-link {
  position: absolute; top: 0; left: 50%;
  transform: translate(-50%, -120%);
  z-index: 500;
  background: var(--bg-elevated); color: var(--sys-blue-text);
  padding: 12px 20px; border-radius: 0 0 var(--r-md) var(--r-md);
  font-size: 0.9375rem; font-weight: 600; text-decoration: none;
  box-shadow: var(--shadow-2);
  transition: transform 0.18s var(--ease-out);
}
.skip-link:focus { transform: translate(-50%, 0); }

/* ── Skeleton loaders — match layout shape instead of a bare spinner ──── */
.skeleton {
  background: linear-gradient(90deg,
    var(--fill-quaternary) 25%,
    var(--fill-tertiary) 37%,
    var(--fill-quaternary) 63%);
  background-size: 400% 100%;
  animation: skeleton-sweep 1.4s ease-in-out infinite;
  border-radius: var(--r-sm);
}
@keyframes skeleton-sweep {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
.skeleton-row {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 0;
  border-bottom: var(--hairline) solid var(--separator);
}
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

/* Colored TEXT needs the opposite treatment to colored FILLS: on dark
   backgrounds it must get lighter, not darker. Tailwind maps one token per
   scale step, so re-point the text utilities here. Doubled selectors raise
   specificity above the CDN's injected utilities. */
.text-brand-500.text-brand-500,
.text-brand-600.text-brand-600,
.text-brand-700.text-brand-700 { color: var(--sys-blue-text); }
.text-accent-500.text-accent-500,
.text-accent-600.text-accent-600,
.text-accent-700.text-accent-700 { color: var(--sys-green-text); }
.text-danger-500.text-danger-500,
.text-danger-600.text-danger-600 { color: var(--sys-red-text); }
.text-warn-500.text-warn-500,
.text-warn-600.text-warn-600 { color: var(--sys-orange-text); }

/* Text sitting on a filled colored surface stays white — the fill tokens are
   already dark enough to carry it at AA. */
.bg-brand-500 .text-brand-500, .bg-brand-600 .text-brand-600 { color: #fff; }

/* Tinted elevation. Tailwind's `shadow-color/opacity` modifier resolves to
   transparent when the palette entry is a var(), so use these instead. */
.shadow-tint  { box-shadow: 0 4px 14px color-mix(in srgb, var(--tint) 30%, transparent); }
.shadow-green { box-shadow: 0 4px 14px color-mix(in srgb, var(--sys-green) 30%, transparent); }
.shadow-red   { box-shadow: 0 4px 14px color-mix(in srgb, var(--sys-red) 30%, transparent); }

@media (prefers-color-scheme: dark) {
  .shadow-tint, .shadow-green, .shadow-red { box-shadow: var(--shadow-2); }
}
@media (prefers-reduced-transparency: reduce) {
  .shadow-tint, .shadow-green, .shadow-red { box-shadow: var(--shadow-2); }
}

/* Grouped list — the standard iOS inset table */
.list-group {
  background: var(--bg-grouped-secondary);
  border-radius: var(--r-md);
  overflow: hidden;
}
.list-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 44px;
  padding: 0.6875rem 1rem;
  background: var(--bg-grouped-secondary);
}
/* Inset separator aligns with text, not the container edge */
.list-row + .list-row { box-shadow: inset 0 var(--hairline) 0 var(--separator); }
.list-row:active { background: var(--fill-quaternary); }

/* ── Focus ─────────────────────────────────────────────────
   Visible keyboard focus without disturbing pointer users. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--tint);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ── Motion ────────────────────────────────────────────────*/
@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;
  }
}

/* ── Utility ───────────────────────────────────────────────*/
.safe-t { padding-top: env(safe-area-inset-top, 0px); }
.safe-b { padding-bottom: env(safe-area-inset-bottom, 0px); }
.safe-x { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }

::selection { background: color-mix(in srgb, var(--tint) 25%, transparent); }
