/* Portico design system — token layer + base foundation.

   Light and dark are peers. :root holds the light values; an explicit
   data-bs-theme on <html> always wins; the prefers-color-scheme block applies
   dark only when no explicit theme is set, so the native iOS/Android shells
   follow the system theme by default.

   Component styles live in custom.css as pc- blocks. */

:root {
  /* Neutrals — sage to forest. Green-tinted throughout, never a cool gray. */
  --pc-neutral-0: #ffffff;
  --pc-neutral-50: #eef1ea;
  --pc-neutral-100: #e3e8df;
  --pc-neutral-150: #dfe4d8;
  --pc-neutral-200: #cdd5c3;
  --pc-neutral-300: #b3bfa6;
  --pc-neutral-400: #7d8c7f;
  --pc-neutral-500: #5e6d60;
  --pc-neutral-600: #47584b;
  --pc-neutral-700: #34443a;
  --pc-neutral-800: #2a3830;
  --pc-neutral-900: #22372c;
  --pc-neutral-950: #16261d;

  /* Accent — golden ochre. Kept under the `brass` name for continuity with the
     design system's own token names, which the name now happens to fit. */
  --pc-brass-300: #e8c884;
  --pc-brass-400: #cba244;
  --pc-brass-500: #b8862a;
  --pc-brass-600: #976c1e;

  /* Dark base values, hand-tuned rather than derived from light by opacity. */
  --pc-dark-bg-0: #121a15;
  --pc-dark-bg-1: #1a251e;
  --pc-dark-bg-2: #24332a;
  --pc-dark-bg-3: #2e4034;
  --pc-dark-border-subtle: #26332b;
  --pc-dark-border-default: #33443a;
  --pc-dark-border-strong: #46594c;
  --pc-dark-text-primary: #eef2e9;
  --pc-dark-text-secondary: #b8c6ba;
  --pc-dark-text-tertiary: #7e8f81;
  /* Brightened on dark so ochre still reads as the one accent. */
  --pc-dark-brass: #e9c069;
  --pc-dark-brass-hover: #f4d083;

  /* On dark, ochre carries the primary action — forest green sinks into
     the background. */
  --pc-dark-primary-bg: #e2b95e;
  --pc-dark-primary-bg-active: #cba34b;
  --pc-dark-primary-fg: #1f1705;

  /* Pending's amber is deliberately duller than the accent — with the accent
     now in the same family, a saturated pending would read as a brand colour
     rather than as a status. */
  --pc-dark-status-pending-bg: #4f4420;
  --pc-dark-status-pending-fg: #eee0c0;
  --pc-dark-status-pending-dot: #cbb26a;
  --pc-dark-status-progress-bg: #1c463b;
  --pc-dark-status-progress-fg: #bfe6d8;
  --pc-dark-status-progress-dot: #4fb6cb;
  --pc-dark-status-ready-bg: #1f4a2b;
  --pc-dark-status-ready-fg: #c7eccb;
  --pc-dark-status-ready-dot: #3fcf6d;
  --pc-dark-status-delivered-bg: #2a2f28;
  --pc-dark-status-delivered-fg: #cfd4c8;
  --pc-dark-status-delivered-dot: #8f9585;
  --pc-dark-status-cancelled-bg: #2e332c;
  --pc-dark-status-cancelled-fg: #9aa094;
  --pc-dark-status-cancelled-dot: #6f766a;

  /* Status system — light. Pending is desaturated against the accent for the
     reason given on the dark pending values above. */
  --pc-status-pending-bg: #ece5d4;
  --pc-status-pending-fg: #6f5c22;
  --pc-status-pending-dot: #b09441;
  --pc-status-progress-bg: #dde9e2;
  --pc-status-progress-fg: #2c6152;
  --pc-status-progress-dot: #3d8a99;
  --pc-status-ready-bg: #dbe9d6;
  --pc-status-ready-fg: #34632f;
  --pc-status-ready-dot: #3f8a4d;
  --pc-status-delivered-bg: #e7e9e2;
  --pc-status-delivered-fg: #5b6356;
  --pc-status-delivered-dot: #8f8574;
  --pc-status-cancelled-bg: #e8e8e2;
  --pc-status-cancelled-fg: #82877c;
  --pc-status-cancelled-dot: #a3a89b;

  /* Semantic aliases — light */
  --surface-app: var(--pc-neutral-50);
  --surface-card: var(--pc-neutral-0);
  --surface-card-raised: #ffffff;
  --surface-elevated: #ffffff;
  --surface-sunken: var(--pc-neutral-100);
  --surface-overlay: rgba(22, 38, 29, .5);
  --surface-inverse: var(--pc-neutral-900);

  /* Light carries elevation with shadow; dark steps surface lightness instead.
     Every shadow scales by this strength so dark gets flat surfaces for free. */
  --elevation-shadow-strength: 1;

  --border-subtle: var(--pc-neutral-150);
  --border-default: var(--pc-neutral-200);
  --border-strong: var(--pc-neutral-300);

  --text-primary: var(--pc-neutral-900);
  --text-secondary: var(--pc-neutral-600);
  --text-tertiary: var(--pc-neutral-400);
  --text-inverse: var(--pc-neutral-0);
  --text-link: var(--pc-brass-600);
  --text-link-hover: var(--pc-brass-500);

  --action-primary-bg: var(--pc-neutral-900);
  --action-primary-bg-active: var(--pc-neutral-800);
  --action-primary-fg: var(--pc-neutral-0);
  --action-secondary-bg: transparent;
  --action-secondary-border: var(--pc-neutral-300);
  --action-secondary-fg: var(--pc-neutral-900);
  --action-accent: var(--pc-brass-500);
  --action-danger-fg: #a4402f;
  --action-danger-border: #d8b2a6;
  --focus-ring: var(--pc-brass-400);
  --focus-ring-alpha: .35;

  /* Edge ring for user-uploaded photos, which arrive at unpredictable
     brightness and otherwise bleed into the surface behind them. */
  --media-ring: rgba(22, 38, 29, .12);
  --media-fallback-bg: var(--surface-sunken);

  color-scheme: light;

  /* Type */
  --font-display: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-body: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --text-2xs: .75rem;
  --text-xs: .8125rem;
  --text-sm: .9375rem;
  --text-base: 1rem;
  --text-md: 1.0625rem;
  --text-lg: 1.1875rem;
  --text-xl: 1.375rem;
  --text-2xl: 1.625rem;
  --text-3xl: 2rem;
  --text-4xl: 2.5rem;

  --leading-tight: 1.15;
  --leading-snug: 1.3;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  --tracking-tight: -.01em;
  --tracking-wide: .04em;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-black: 800;

  /* Spacing and mobile layout constants */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;

  --gutter-screen: 1rem;
  --touch-target-min: 48px;
  --input-font-size: 16px;
  --bottom-nav-height: 64px;
  --safe-area-bottom: env(safe-area-inset-bottom, 0px);
  --safe-area-top: env(safe-area-inset-top, 0px);

  /* Radius */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-pill: 999px;

  /* Elevation */
  --shadow-xs: 0 1px 2px rgba(34, 55, 44, calc(.06 * var(--elevation-shadow-strength)));
  --shadow-sm: 0 2px 6px rgba(34, 55, 44, calc(.08 * var(--elevation-shadow-strength)));
  --shadow-md: 0 6px 16px rgba(34, 55, 44, calc(.10 * var(--elevation-shadow-strength)));
  --shadow-lg: 0 12px 32px rgba(34, 55, 44, calc(.14 * var(--elevation-shadow-strength)));

  /* Mixed from --focus-ring rather than restating the accent as a literal
     triplet, so the ring can never drift out of sync with the accent again. */
  --shadow-focus: 0 0 0 3px color-mix(in srgb, var(--focus-ring) calc(var(--focus-ring-alpha) * 100%), transparent);

  /* Motion */
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;
  --ease-standard: cubic-bezier(.2, 0, 0, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --flash-duration: 1100ms;

  /* Bootstrap bridge. Only vars Bootstrap reads from the root cascade belong
     here — anything it re-declares on a component class (--bs-card-*,
     --bs-btn-*) is set inside that component's pc- block instead, where it
     actually wins. */
  --bs-body-bg: var(--surface-app);
  --bs-body-color: var(--text-primary);
  --bs-body-font-family: var(--font-body);
  --bs-body-font-size: var(--text-base);
  --bs-body-line-height: var(--leading-normal);
  --bs-emphasis-color: var(--text-primary);
  --bs-heading-color: var(--text-primary);
  --bs-border-color: var(--border-default);
  --bs-border-radius: .625rem;
  --bs-border-radius-lg: .875rem;
  --bs-border-radius-sm: .375rem;
  --bs-border-radius-pill: var(--radius-pill);
  --bs-primary: var(--pc-neutral-900);
  --bs-primary-rgb: 34, 55, 44;
  --bs-secondary: var(--pc-neutral-500);
  --bs-warning: var(--pc-status-pending-dot);
  --bs-info: var(--pc-status-progress-dot);
  --bs-success: var(--pc-status-ready-dot);
  --bs-danger: var(--action-danger-fg);

  /* Bootstrap composes link color from an rgb triplet plus an opacity, so a
     hex token can't drive it — these mirror --pc-brass-600 / --pc-brass-500. */
  --bs-link-color-rgb: 151, 108, 30;
  --bs-link-hover-color-rgb: 184, 134, 42;

  /* Bridging these lets the stock text-body-secondary / text-body-tertiary
     utilities and .is-invalid / .invalid-feedback carry Portico's tokens, so
     the markup needs no custom classes for them. */
  --bs-secondary-color: var(--text-secondary);
  --bs-tertiary-color: var(--text-tertiary);
  --bs-secondary-bg: var(--surface-sunken);
  --bs-tertiary-bg: var(--surface-sunken);
  --bs-form-invalid-color: var(--action-danger-fg);
  --bs-form-invalid-border-color: var(--action-danger-fg);
}

/* Explicit dark — wins over the OS preference. */
[data-bs-theme="dark"] {
  --surface-app: var(--pc-dark-bg-0);
  --surface-card: var(--pc-dark-bg-1);
  --surface-card-raised: var(--pc-dark-bg-2);
  --surface-elevated: var(--pc-dark-bg-2);
  --surface-sunken: var(--pc-dark-bg-2);
  --surface-overlay: rgba(0, 0, 0, .65);
  --surface-inverse: var(--pc-neutral-50);
  --elevation-shadow-strength: 0;

  --border-subtle: var(--pc-dark-border-subtle);
  --border-default: var(--pc-dark-border-default);
  --border-strong: var(--pc-dark-border-strong);

  --text-primary: var(--pc-dark-text-primary);
  --text-secondary: var(--pc-dark-text-secondary);
  --text-tertiary: var(--pc-dark-text-tertiary);
  --text-inverse: var(--pc-neutral-900);
  --text-link: var(--pc-dark-brass);
  --text-link-hover: var(--pc-dark-brass-hover);

  --action-primary-bg: var(--pc-dark-primary-bg);
  --action-primary-bg-active: var(--pc-dark-primary-bg-active);
  --action-primary-fg: var(--pc-dark-primary-fg);
  --action-secondary-border: var(--pc-dark-border-strong);
  --action-secondary-fg: var(--pc-dark-text-primary);
  --action-accent: var(--pc-dark-brass);
  --action-danger-fg: #e8927b;
  --action-danger-border: #5c3830;
  --focus-ring: var(--pc-dark-brass);
  --focus-ring-alpha: .4;

  --media-ring: rgba(238, 242, 233, .15);

  --pc-status-pending-bg: var(--pc-dark-status-pending-bg);
  --pc-status-pending-fg: var(--pc-dark-status-pending-fg);
  --pc-status-pending-dot: var(--pc-dark-status-pending-dot);
  --pc-status-progress-bg: var(--pc-dark-status-progress-bg);
  --pc-status-progress-fg: var(--pc-dark-status-progress-fg);
  --pc-status-progress-dot: var(--pc-dark-status-progress-dot);
  --pc-status-ready-bg: var(--pc-dark-status-ready-bg);
  --pc-status-ready-fg: var(--pc-dark-status-ready-fg);
  --pc-status-ready-dot: var(--pc-dark-status-ready-dot);
  --pc-status-delivered-bg: var(--pc-dark-status-delivered-bg);
  --pc-status-delivered-fg: var(--pc-dark-status-delivered-fg);
  --pc-status-delivered-dot: var(--pc-dark-status-delivered-dot);
  --pc-status-cancelled-bg: var(--pc-dark-status-cancelled-bg);
  --pc-status-cancelled-fg: var(--pc-dark-status-cancelled-fg);
  --pc-status-cancelled-dot: var(--pc-dark-status-cancelled-dot);

  /* Shadows are near-invisible on dark ground, so they only deepen the well
     under raised chrome rather than carrying elevation. */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, .4);
  --shadow-md: 0 4px 10px rgba(0, 0, 0, .45);
  --shadow-lg: 0 10px 24px rgba(0, 0, 0, .5);
  /* --shadow-focus is not restated: it mixes --focus-ring at
     --focus-ring-alpha, and both are overridden for dark above. */

  color-scheme: dark;
  --bs-body-bg: var(--surface-app);
  --bs-body-color: var(--text-primary);
  --bs-emphasis-color: var(--text-primary);
  --bs-border-color: var(--border-default);
  --bs-link-color-rgb: 233, 192, 105;
  --bs-link-hover-color-rgb: 244, 208, 131;
}

/* OS dark — applies only when the app hasn't pinned a theme. Duplicates the
   block above because plain CSS can't share a declaration set across a
   media-query boundary. */
@media (prefers-color-scheme: dark) {
  :root:not([data-bs-theme="light"]):not([data-bs-theme="dark"]) {
    --surface-app: var(--pc-dark-bg-0);
    --surface-card: var(--pc-dark-bg-1);
    --surface-card-raised: var(--pc-dark-bg-2);
    --surface-elevated: var(--pc-dark-bg-2);
    --surface-sunken: var(--pc-dark-bg-2);
    --surface-overlay: rgba(0, 0, 0, .65);
    --surface-inverse: var(--pc-neutral-50);
    --elevation-shadow-strength: 0;

    --border-subtle: var(--pc-dark-border-subtle);
    --border-default: var(--pc-dark-border-default);
    --border-strong: var(--pc-dark-border-strong);

    --text-primary: var(--pc-dark-text-primary);
    --text-secondary: var(--pc-dark-text-secondary);
    --text-tertiary: var(--pc-dark-text-tertiary);
    --text-inverse: var(--pc-neutral-900);
    --text-link: var(--pc-dark-brass);
    --text-link-hover: var(--pc-dark-brass-hover);

    --action-primary-bg: var(--pc-dark-primary-bg);
    --action-primary-bg-active: var(--pc-dark-primary-bg-active);
    --action-primary-fg: var(--pc-dark-primary-fg);
    --action-secondary-border: var(--pc-dark-border-strong);
    --action-secondary-fg: var(--pc-dark-text-primary);
    --action-accent: var(--pc-dark-brass);
    --action-danger-fg: #e8927b;
    --action-danger-border: #5c3830;
    --focus-ring: var(--pc-dark-brass);
    --focus-ring-alpha: .4;

    --media-ring: rgba(238, 242, 233, .15);

    --pc-status-pending-bg: var(--pc-dark-status-pending-bg);
    --pc-status-pending-fg: var(--pc-dark-status-pending-fg);
    --pc-status-pending-dot: var(--pc-dark-status-pending-dot);
    --pc-status-progress-bg: var(--pc-dark-status-progress-bg);
    --pc-status-progress-fg: var(--pc-dark-status-progress-fg);
    --pc-status-progress-dot: var(--pc-dark-status-progress-dot);
    --pc-status-ready-bg: var(--pc-dark-status-ready-bg);
    --pc-status-ready-fg: var(--pc-dark-status-ready-fg);
    --pc-status-ready-dot: var(--pc-dark-status-ready-dot);
    --pc-status-delivered-bg: var(--pc-dark-status-delivered-bg);
    --pc-status-delivered-fg: var(--pc-dark-status-delivered-fg);
    --pc-status-delivered-dot: var(--pc-dark-status-delivered-dot);
    --pc-status-cancelled-bg: var(--pc-dark-status-cancelled-bg);
    --pc-status-cancelled-fg: var(--pc-dark-status-cancelled-fg);
    --pc-status-cancelled-dot: var(--pc-dark-status-cancelled-dot);

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, .4);
    --shadow-md: 0 4px 10px rgba(0, 0, 0, .45);
    --shadow-lg: 0 10px 24px rgba(0, 0, 0, .5);
    /* See the note on --shadow-focus in the explicit-dark block above. */

    color-scheme: dark;
    --bs-body-bg: var(--surface-app);
    --bs-body-color: var(--text-primary);
    --bs-emphasis-color: var(--text-primary);
    --bs-border-color: var(--border-default);
    --bs-link-color-rgb: 233, 192, 105;
    --bs-link-hover-color-rgb: 244, 208, 131;
  }
}

/* ---- Base foundation ---- */

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Bootstrap emits no heading font-family custom property — $headings-font-family
   is a Sass variable that compiles away — so the display face is set here. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
}

/* Mobile-first type scale: these are the phone sizes, stepped up at md. */
h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4, h5, h6 { font-size: var(--text-md); }

@media (min-width: 768px) {
  h1 { font-size: var(--text-3xl); }
  h2 { font-size: var(--text-2xl); }
  h3 { font-size: var(--text-xl); }
}

:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

::selection {
  background: var(--pc-brass-300);
  color: var(--pc-neutral-950);
}

/* Themed to survive dark mode; the previous hardcoded grays did not. */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--surface-sunken); }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--radius-sm); }

/* A frame mid-fetch reads as inert rather than broken. */
turbo-frame[busy] {
  opacity: .6;
  pointer-events: none;
}

@keyframes pc-row-flash {
  0% { background-color: var(--pc-brass-300); opacity: .28; }
  100% { background-color: transparent; opacity: 0; }
}

@keyframes pc-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes pc-spin {
  to { transform: rotate(360deg); }
}
