/* =====================================================================
   TripMate - core design system
   Tokens, reset, layout primitives, and shared components.
   Loaded on every page; page-specific rules live in their own files.
   ===================================================================== */

:root {
  color-scheme: light;

  /* ==================================================================
     TripMate brand palette — the single source of truth.

     Change a colour HERE and it moves everywhere. Nothing else in the
     project should hardcode a brand hex: the legacy token names below
     alias onto these, and every stylesheet consumes the legacy names.

     Navy gives structure and trust, blue carries interaction, orange
     supplies personality in small doses, and the page stays light.
     ================================================================== */
  --tm-primary:        #0F2D5B;
  --tm-primary-hover:  #0A2247;

  --tm-secondary:      #3882F6;
  --tm-secondary-hover:#2563EB;
  --tm-secondary-light:#93B8FB;  /* legible blue on a navy surface */
  --tm-secondary-tint: #EAF1FE;  /* selected rows, soft interactive fills */

  --tm-accent:         #FF7A45;
  --tm-accent-hover:   #F06432;
  --tm-accent-light:   #FFC978;
  --tm-accent-tint:    #FFF1E8;

  /* ---- Accessible variants -----------------------------------------
     The brand hues above are correct for fills, rails, borders and
     decoration, but several fail WCAG AA as *text*. Measured on white:
       #3882F6  3.69:1   #FF7A45  2.59:1   #FFC978  1.51:1
     all short of the 4.5:1 normal-text bar. So brand colour is kept for
     surfaces and these darker siblings carry anything a user must read.
     Use the ones below for text and small icons; the ones above for
     everything else. ------------------------------------------------- */
  --tm-link:           #2563EB;  /* 5.17:1 on white */
  --tm-accent-text:    #B4451F;  /* 5.51:1 on white, 4.98:1 on the tint */
  --tm-amber-icon:     #D97706;  /* 3.19:1 — clears the 3:1 icon bar */
  --tm-on-accent:      #10233F;  /* 6.09:1 navy on orange; white is 2.59:1 */

  --tm-background:     #F8FAFF;
  --tm-surface:        #FFFFFF;
  --tm-surface-warm:   #FFF6ED;
  --tm-surface-subtle: #EFF4FC;  /* table headers, tracks, inert chips */

  --tm-text-primary:   #10233F;
  --tm-text-body:      #475569;
  --tm-text-secondary: #64748B;
  --tm-text-light:     #94A3B8;

  --tm-border:         #E6EBF2;
  --tm-border-strong:  #CBD5E1;

  /* ---- Legacy aliases ----------------------------------------------
     These names predate the palette above and are referenced ~800 times
     across nine stylesheets, so they are kept and simply pointed at the
     new tokens. Renaming them would mean touching every stylesheet for
     a change that carries no visual benefit. Read them as:
       navy-*  = deep navy   (headings, dark surfaces, footer)
       teal-*  = travel blue (links, primary interactive accents)
       sky-*   = light blue  (tints, on-dark accents, focus ring)
       coral-* = warm orange (accent, highlights, personality)
     ------------------------------------------------------------------ */
  --navy-900: var(--tm-text-primary);
  --navy-800: var(--tm-primary);
  --navy-700: var(--tm-primary-hover);
  --teal-700: var(--tm-secondary-hover);
  --teal-600: var(--tm-secondary);
  --sky-500:  var(--tm-secondary-hover);
  --sky-400:  var(--tm-secondary-light);
  --sky-100:  var(--tm-secondary-tint);
  --coral-600:var(--tm-accent);
  --coral-500:var(--tm-accent-hover);
  --coral-100:var(--tm-accent-tint);

  /* Neutrals — cool greys, to sit under the light blue background. */
  --ink-900: var(--tm-text-primary);
  --ink-700: var(--tm-text-body);
  --ink-500: var(--tm-text-secondary);
  --ink-400: var(--tm-text-light);
  --line-300:var(--tm-border-strong);
  --line-200:var(--tm-border);
  --surface:  var(--tm-surface);
  --surface-2:var(--tm-background);
  --surface-3:var(--tm-surface-subtle);

  /* Status ------------------------------------------------------------
     Semantic only, and deliberately independent of the brand palette:
     green still means success, amber warning, red danger, blue info.
     Green was removed from TripMate's *identity*, not from its status
     vocabulary, where it carries meaning users rely on. */
  --success-600:#15803D;
  --success-100:#DCFCE7;
  --warning-600:#B45309;
  --warning-100:#FEF3C7;
  --danger-600: #B91C1C;
  --danger-100: #FEE2E2;
  --info-600:   #1D4ED8;
  --info-100:   #DBEAFE;

  /* Type -------------------------------------------------------------
     No webfont: the Content-Security-Policy sets `font-src 'self' data:`,
     so a hosted family would simply be blocked, and self-hosting one
     costs a render-blocking round trip on every page. The pairing below
     is an editorial serif for display headings against the platform UI
     sans for everything a user has to read or operate.
     ------------------------------------------------------------------ */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-base: 1rem;
  --fs-lg: 1.125rem;
  --fs-xl: clamp(1.25rem, 1.15rem + 0.4vw, 1.4rem);
  --fs-2xl: clamp(1.5rem, 1.3rem + 0.9vw, 1.95rem);
  --fs-3xl: clamp(1.85rem, 1.5rem + 1.5vw, 2.6rem);
  --fs-4xl: clamp(2.3rem, 1.6rem + 3.1vw, 3.9rem);

  /* Space, radius, shadow ------------------------------------------ */
  --sp-1: 0.25rem; --sp-2: 0.5rem;  --sp-3: 0.75rem; --sp-4: 1rem;
  --sp-5: 1.5rem;  --sp-6: 2rem;    --sp-7: 3.25rem; --sp-8: 4.5rem;
  --r-sm: 6px; --r-md: 11px; --r-lg: 18px; --r-xl: 26px; --r-pill: 999px;
  /* Navy-tinted rather than neutral black: a grey shadow over a cool
     background reads as dirt. Elevated, but never floating. */
  --shadow-sm: 0 1px 2px rgba(15, 45, 91, .03), 0 1px 3px rgba(15, 45, 91, .05);
  --shadow-md: 0 1px 2px rgba(15, 45, 91, .03), 0 8px 24px rgba(15, 45, 91, .07);
  --shadow-lg: 0 2px 4px rgba(15, 45, 91, .03), 0 12px 32px rgba(15, 45, 91, .11);
  --ring: 0 0 0 3px rgba(56, 130, 246, .30);

  --container: 1200px;
  --header-h: 72px;
  --ease: cubic-bezier(.2, .7, .3, 1);
  --transition: 180ms cubic-bezier(.2, .7, .3, 1);
}

/* Browser-forced dark mode must not repaint our surfaces. We ship a
   light identity only; locking these values keeps text readable instead
   of letting the UA invert backgrounds and wash out contrast. */
@media (prefers-color-scheme: dark) {
  :root { color-scheme: light; }
  /* Same values the light rendering uses, so a dark OS changes nothing. */
  html, body { background: var(--surface-2); color: var(--ink-700); }
  input, select, textarea, button {
    background-color: var(--surface);
    color: var(--ink-900);
    -webkit-text-fill-color: var(--ink-900);
  }
  /* Chromium renders the native date/time picker glyphs from the OS theme;
     without this they turn white-on-white in a dark OS. */
  input[type="date"], input[type="time"], input[type="datetime-local"] { color-scheme: light; }
}

/* Chromium paints autofilled fields with its own background, overriding the
   rules above. The inset shadow is the only reliable way to restore ours. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
select:-webkit-autofill,
textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--ink-900);
  -webkit-box-shadow: 0 0 0 1000px var(--surface) inset;
  box-shadow: 0 0 0 1000px var(--surface) inset;
  caret-color: var(--ink-900);
}

/* ---- Reset ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--ink-700);
  background: var(--surface-2);
  /* Guards against any single wide child creating a horizontal scrollbar. */
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
/* Any component rule that sets `display` outranks the `hidden` attribute,
   which silently reveals elements meant to start closed. Declared with
   !important so a component never has to remember to re-hide itself. */
[hidden] { display: none !important; }

/* h1/h2 carry the editorial serif; h3 and below are interface text and
   stay in the UI sans so dashboards and cards remain highly legible. */
h1, h2, h3, h4, h5, h6 { margin: 0 0 var(--sp-3); line-height: 1.2; font-weight: 700; color: var(--navy-900); }
h1, h2 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.011em;
  line-height: 1.12;
  text-wrap: balance;
}
h1 { font-size: var(--fs-3xl); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-xl); letter-spacing: -0.008em; }
h4 { font-size: var(--fs-lg); letter-spacing: -0.005em; }
p  { margin: 0 0 var(--sp-4); text-wrap: pretty; }
a  { color: var(--tm-link); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--tm-primary); }
ul, ol { margin: 0 0 var(--sp-4); padding-left: var(--sp-5); }
small { font-size: var(--fs-sm); }
hr { border: 0; border-top: 1px solid var(--line-300); margin: var(--sp-5) 0; }
strong, b { color: var(--navy-900); font-weight: 700; }
/* Prices, counts and table figures line up column-to-column. */
.table td, .table th, .stat__value, .money { font-variant-numeric: tabular-nums; }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: var(--sp-4); top: -100px; z-index: 200;
  background: var(--navy-900); color: #fff; padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-sm); transition: top var(--transition);
}
.skip-link:focus { top: var(--sp-4); color: #fff; }

/* ---- Layout ------------------------------------------------------ */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--sp-4); }
.section { padding-block: var(--sp-7); }
.section--tight { padding-block: var(--sp-6); }
.section--alt { background: var(--surface); }

.stack > * + * { margin-top: var(--sp-4); }
.row { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.row--between { justify-content: space-between; align-items: center; }
.row--center { justify-content: center; align-items: center; }
.row--middle { align-items: center; }
.grid { display: grid; gap: var(--sp-5); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
/* auto-fill (not auto-fit) so a row with one or two cards keeps them at their
   normal column width instead of stretching a lone card - and its image -
   across the whole row. */
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.section-head { margin-bottom: var(--sp-6); gap: var(--sp-4); }
.section-head h2 { margin-bottom: var(--sp-2); }
.section-head p { color: var(--ink-500); margin: 0; max-width: 62ch; font-size: var(--fs-lg); line-height: 1.55; }
/* Small caps label with a short rule, so section openers read as editorial
   kickers rather than another line of bold text. */
.eyebrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--tm-link);
  margin-bottom: var(--sp-3);
}
.eyebrow::before {
  content: ""; width: 22px; height: 1px; background: currentColor; opacity: .55; flex-shrink: 0;
}
.text-center .eyebrow { justify-content: center; }

/* ---- Buttons ----------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font: inherit; font-weight: 600; line-height: 1;
  letter-spacing: -0.005em;
  padding: 0.8rem 1.35rem;
  border: 1px solid transparent; border-radius: var(--r-md);
  cursor: pointer; text-align: center; white-space: nowrap;
  transition: background var(--transition), color var(--transition),
              border-color var(--transition), transform var(--transition),
              box-shadow var(--transition);
  min-height: 46px; /* touch target */
}
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; transform: none; }

/* Button hierarchy
   ----------------
   primary / teal : travel blue — the standard action, used site-wide.
   outline        : white with navy text — the quiet companion action.
   secondary      : solid navy — for dark or image-backed surfaces.
   accent         : warm orange — applied further down to the handful of
                    places that genuinely warrant extra attention, rather
                    than to every call to action.
   Each hover shadow is tinted with its own button's hue so it reads as
   light rather than grime. */
.btn--primary { background: var(--tm-secondary-hover); color: #fff; box-shadow: 0 1px 2px rgba(56, 130, 246, .22); }
.btn--primary:hover:not(:disabled) { background: #1D4ED8; color: #fff; box-shadow: 0 6px 16px -5px rgba(56, 130, 246, .45); transform: translateY(-1px); }
.btn--primary:active { transform: translateY(0); }
/* Historically a separate colour; now the same action as --primary, kept as
   an alias so the ~40 templates using it need no edit. */
.btn--teal { background: var(--tm-secondary-hover); color: #fff; box-shadow: 0 1px 2px rgba(56, 130, 246, .22); }
.btn--teal:hover:not(:disabled) { background: #1D4ED8; color: #fff; box-shadow: 0 6px 16px -5px rgba(56, 130, 246, .45); transform: translateY(-1px); }
.btn--secondary { background: var(--tm-primary); color: #fff; }
.btn--secondary:hover:not(:disabled) { background: var(--tm-primary-hover); color: #fff; box-shadow: 0 6px 16px -5px rgba(15, 45, 91, .35); transform: translateY(-1px); }
.btn--outline { background: var(--surface); color: var(--tm-primary); border-color: var(--line-300); }
.btn--outline:hover:not(:disabled) { border-color: var(--tm-secondary); color: var(--tm-secondary-hover); background: var(--sky-100); }

/* Warm orange, reserved for the few actions that carry the most weight on
   their screen: the header sign-up, the hero's leading call to action, and
   the assistant launcher. Deliberately not a class the templates apply, so
   the accent cannot spread across the product one commit at a time. */
.header__actions .btn--primary,
.hero__actions .btn--primary {
  background: var(--tm-accent); color: var(--tm-on-accent);
  box-shadow: 0 1px 2px rgba(255, 122, 69, .25);
}
.header__actions .btn--primary:hover:not(:disabled),
.hero__actions .btn--primary:hover:not(:disabled) {
  background: var(--tm-accent-hover); color: var(--tm-on-accent);
  box-shadow: 0 6px 16px -5px rgba(255, 122, 69, .5);
}
.btn--ghost { background: transparent; color: var(--ink-700); }
.btn--ghost:hover:not(:disabled) { background: var(--surface-3); color: var(--navy-900); }
.btn--danger { background: var(--danger-600); color: #fff; }
.btn--danger:hover:not(:disabled) { background: #B91C1C; color: #fff; }
.btn--link { background: transparent; color: var(--tm-link); padding-left: 0; padding-right: 0; min-height: 0; text-decoration: none; }
.btn--link:hover:not(:disabled) { color: var(--navy-900); }

/* One-time-code entry: a centred, focused block rather than a lonely field
   floating on the left of the form. */
.otp-entry {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-2);
  padding: var(--sp-5) var(--sp-4);
  margin-bottom: var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--line-200);
  border-radius: var(--r-lg);
}
.otp-entry__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  color: var(--tm-link);
  background: var(--sky-100);
  margin-bottom: var(--sp-1);
}
.otp-entry .label { margin: 0; font-weight: 600; }
.otp-entry .field__hint, .otp-entry .field__error { text-align: center; }

/* The code box itself: large, evenly spaced digits, centred. The right
   padding offsets trailing letter-spacing so the text sits truly centred. */
.input--otp {
  font-size: 1.6rem;
  line-height: 1.2;
  letter-spacing: .5em;
  text-align: center;
  font-weight: 700;
  font-family: Consolas, 'Courier New', monospace;
  max-width: 15rem;
  width: 100%;
  padding-left: calc(var(--sp-3) + .5em);
  padding-right: var(--sp-3);
  padding-top: var(--sp-3);
  padding-bottom: var(--sp-3);
}
.input--otp:focus {
  border-color: var(--teal-600);
  box-shadow: 0 0 0 3px var(--sky-100);
}

/* Resend / edit links under the code box. */
.otp-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-top: var(--sp-4);
}
.otp-actions .btn[disabled] { opacity: .6; }
.btn--sm { padding: .5rem .85rem; font-size: var(--fs-sm); min-height: 36px; }
.btn--lg { padding: .95rem 1.75rem; font-size: var(--fs-lg); min-height: 52px; }
.btn--block { width: 100%; }

/* Compact controls are sized for a mouse. On a touch screen the same
   buttons have to be reachable, so they grow to the 44px target there
   only — desktop tables and toolbars keep their density. */
@media (pointer: coarse) {
  .btn--sm { min-height: 44px; padding-inline: 1rem; }
  .dropdown__item { min-height: 44px; }
  .fav-btn { min-width: 44px; min-height: 44px; }
}

/* Inline spinner shown while an async action is in flight. */
.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
  content: ""; position: absolute; width: 18px; height: 18px;
  border: 2px solid rgba(255,255,255,.45); border-top-color: #fff;
  border-radius: 50%; animation: spin .7s linear infinite;
}
.btn--outline.is-loading::after, .btn--ghost.is-loading::after {
  border-color: rgba(15, 45, 91, .3); border-top-color: var(--navy-800);
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- Cards ------------------------------------------------------- */
.card {
  background: var(--surface); border: 1px solid var(--line-200);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
}
.card--hover:hover { box-shadow: var(--shadow-lg); transform: translateY(-4px); border-color: var(--line-300); }
.card__body { padding: var(--sp-5); }
.card__title { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); letter-spacing: -0.01em; }
.card__meta { color: var(--ink-500); font-size: var(--fs-sm); line-height: 1.55; }
.card__media { position: relative; aspect-ratio: 16 / 10; background: var(--surface-3); overflow: hidden; }
.card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 400ms var(--ease);
}
/* A restrained 3% push-in on hover: enough to feel alive, not enough to
   soften the crop or shift the card's perceived size. */
.card--hover:hover .card__media img { transform: scale(1.03); }
.card__footer {
  padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--line-200);
  background: var(--surface-2);
}

/* ---- Badges ------------------------------------------------------ */
.badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  padding: .28rem .65rem; border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.45;
  letter-spacing: .02em;
  background: var(--surface-3); color: var(--ink-700);
  border: 1px solid transparent;
}
.badge--verified { background: var(--success-100); color: var(--success-600); border-color: rgba(21, 128, 61, .22); }
.badge--pending  { background: var(--warning-100); color: var(--warning-600); border-color: rgba(180, 83, 9, .22); }
.badge--danger   { background: var(--danger-100);  color: var(--danger-600); border-color: rgba(220, 38, 38, .22); }
.badge--info     { background: var(--info-100);    color: var(--info-600); border-color: rgba(29, 78, 216, .22); }
.badge--teal     { background: var(--sky-100);     color: var(--teal-700); border-color: rgba(56, 130, 246, .22); }
.badge--coral    { background: var(--coral-100);   color: var(--tm-accent-text); border-color: rgba(255, 122, 69, .3); }
.badge--muted    { background: var(--surface-3);   color: var(--ink-500); }
/* Status is carried by the label text and the icon, never by colour alone. */
.badge--verified::before {
  content: ""; width: 12px; height: 12px; flex-shrink: 0;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.6 14.9 4l3.7-.3 1 3.6 3 2.2-1.6 3.4 1.6 3.4-3 2.2-1 3.6-3.7-.3L12 24l-2.9-2.4-3.7.3-1-3.6-3-2.2L3 12.9 1.4 9.5l3-2.2 1-3.6L9.1 4z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.6 14.9 4l3.7-.3 1 3.6 3 2.2-1.6 3.4 1.6 3.4-3 2.2-1 3.6-3.7-.3L12 24l-2.9-2.4-3.7.3-1-3.6-3-2.2L3 12.9 1.4 9.5l3-2.2 1-3.6L9.1 4z'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ---- Forms ------------------------------------------------------- */
.field { margin-bottom: var(--sp-4); }
.label {
  display: block; font-weight: 600; font-size: var(--fs-sm);
  margin-bottom: var(--sp-2); color: var(--navy-900); letter-spacing: -0.003em;
}
.label .req { color: var(--danger-600); }

.input, .select, .textarea {
  width: 100%; font: inherit; color: var(--ink-900);
  background: var(--surface); border: 1px solid var(--line-300);
  border-radius: var(--r-md); padding: .75rem .9rem;
  min-height: 48px;
  transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
  -webkit-appearance: none; appearance: none;
}
.input:hover:not(:disabled), .select:hover:not(:disabled), .textarea:hover:not(:disabled) { border-color: var(--ink-400); }
.textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
.select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748B' d='M1.4.6 6 5.2 10.6.6 12 2l-6 6-6-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .9rem center;
  padding-right: 2.4rem;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--teal-600); box-shadow: var(--ring);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-400); }
.input:disabled, .select:disabled, .textarea:disabled { background: var(--surface-3); color: var(--ink-500); cursor: not-allowed; }
.input.is-invalid, .select.is-invalid, .textarea.is-invalid { border-color: var(--danger-600); }

.field__error { display: block; color: var(--danger-600); font-size: var(--fs-sm); margin-top: var(--sp-2); }
.field__hint  { display: block; color: var(--ink-500); font-size: var(--fs-sm); margin-top: var(--sp-2); }

.check { display: flex; align-items: flex-start; gap: var(--sp-2); font-size: var(--fs-sm); cursor: pointer; }
.check input[type="checkbox"], .check input[type="radio"] {
  width: 18px; height: 18px; margin-top: 2px; accent-color: var(--teal-600); flex-shrink: 0;
}

.input-group { position: relative; }
.input-group .input { padding-right: 3rem; }
.input-group__btn {
  position: absolute; right: .35rem; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer; color: var(--ink-500);
  padding: .5rem; border-radius: var(--r-sm); line-height: 0;
}
.input-group__btn:hover { color: var(--tm-link); background: var(--surface-3); }

/* ---- Alerts ------------------------------------------------------ */
.alert {
  padding: var(--sp-4); border-radius: var(--r-md);
  border: 1px solid transparent; margin-bottom: var(--sp-4); font-size: var(--fs-sm);
}
.alert--success { background: var(--success-100); border-color: #A7E3BC; color: #14532D; }
.alert--error   { background: var(--danger-100);  border-color: #F7BDBD; color: #991B1B; }
.alert--warning { background: var(--warning-100); border-color: #F5D48A; color: #92400E; }
.alert--info    { background: var(--info-100);    border-color: #B9D2FC; color: #1E40AF; }

/* ---- Toasts ------------------------------------------------------ */
.toast-stack {
  position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: 120;
  display: flex; flex-direction: column; gap: var(--sp-2);
  max-width: min(360px, calc(100vw - 2rem));
}
.toast {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  background: var(--navy-900); color: #fff;
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); font-size: var(--fs-sm);
  animation: toast-in 220ms ease;
}
.toast--success { background: #14532D; }
.toast--error   { background: #991B1B; }
.toast--warning { background: #92400E; }
.toast__close { background: none; border: 0; color: inherit; opacity: .7; cursor: pointer; padding: 0 0 0 var(--sp-2); font-size: 1.1rem; line-height: 1; }
.toast__close:hover { opacity: 1; }
@keyframes toast-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* ---- Modals ------------------------------------------------------ */
.modal {
  position: fixed; inset: 0; z-index: 130;
  display: none; align-items: center; justify-content: center;
  padding: var(--sp-4); background: rgba(16, 35, 63, .55);
}
.modal.is-open { display: flex; animation: fade-in 160ms ease; }
.modal__panel {
  background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  width: 100%; max-width: 520px; max-height: 90vh; overflow-y: auto;
  animation: modal-in 200ms ease;
}
.modal__panel--sm { max-width: 420px; }
.modal__header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-5); border-bottom: 1px solid var(--line-200);
}
.modal__header h3 { margin: 0; }
.modal__body { padding: var(--sp-5); }
.modal__footer {
  display: flex; justify-content: flex-end; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--line-200);
  background: var(--surface-2); flex-wrap: wrap;
}
.modal__close { background: none; border: 0; font-size: 1.5rem; line-height: 1; cursor: pointer; color: var(--ink-500); padding: var(--sp-1); }
.modal__close:hover { color: var(--danger-600); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-in { from { opacity: 0; transform: translateY(16px) scale(.98); } to { opacity: 1; transform: none; } }
body.modal-open { overflow: hidden; }

/* ---- Empty & loading states -------------------------------------- */
.empty-state {
  text-align: center; padding: var(--sp-7) var(--sp-4); color: var(--ink-500);
  border: 1px dashed var(--line-300); border-radius: var(--r-lg);
  background: var(--surface-2);
}
.empty-state__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; margin: 0 auto var(--sp-4);
  border-radius: 50%; background: var(--surface-3); color: var(--ink-400);
  font-size: 1.75rem; opacity: 1;
}
.empty-state h3 { color: var(--navy-900); margin-bottom: var(--sp-2); }
.empty-state p { max-width: 46ch; margin-inline: auto; }
/* Inside a panel the dashed frame would double up on the panel border. */
.panel__body > .empty-state, .card__body > .empty-state { border: 0; background: none; }

.skeleton {
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--line-200) 37%, var(--surface-3) 63%);
  background-size: 400% 100%; animation: shimmer 1.3s ease infinite;
  border-radius: var(--r-sm);
}
.skeleton--text { height: 12px; margin-bottom: var(--sp-2); }
.skeleton--title { height: 20px; width: 60%; margin-bottom: var(--sp-3); }
.skeleton--media { aspect-ratio: 16/10; border-radius: 0; }
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ---- Info lists ---------------------------------------------------
   Label/value pairs in side panels. Lives here rather than in a page
   stylesheet because the planner, budget, and profile panels all use it;
   when it sat in listing.css those pages rendered raw bullet points with
   the label and value run together. */
.info-list { list-style: none; padding: 0; margin: 0; }
.info-list li {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) 0; border-bottom: 1px solid var(--line-200);
  font-size: var(--fs-sm);
}
.info-list li:last-child { border-bottom: 0; }
.info-list dt, .info-list .key { color: var(--ink-500); white-space: nowrap; flex-shrink: 0; }
.info-list dd, .info-list .val {
  margin: 0; font-weight: 600; color: var(--navy-900);
  /* Long values (e.g. a multi-window best season) must wrap within their
     column rather than overflow the panel; short ones still sit on one line. */
  text-align: right; min-width: 0; overflow-wrap: anywhere;
}

/* ---- Activity feed ------------------------------------------------
   Timestamped "who did what" list. Shared by the planner and by the admin
   and guide dashboards, so it lives here rather than in planner.css. */
.activity-feed { list-style: none; margin: 0; padding: 0; }
.activity-feed li {
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line-200);
  font-size: var(--fs-sm); color: var(--ink-700);
}
.activity-feed li:last-child { border-bottom: 0; }
.activity-feed strong { color: var(--navy-900); }
.activity-feed time { display: block; color: var(--ink-400); font-size: var(--fs-xs); margin-top: 2px; }

/* ---- Tables ------------------------------------------------------ */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--r-md); }
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); background: var(--surface); }
.table th, .table td { padding: var(--sp-3) var(--sp-4); text-align: left; border-bottom: 1px solid var(--line-200); }
.table th {
  background: var(--surface-3); color: var(--ink-500); white-space: nowrap;
  font-weight: 700; font-size: var(--fs-xs);
  text-transform: uppercase; letter-spacing: .07em;
}
.table td { color: var(--ink-700); }
.table tbody tr { transition: background var(--transition); }
.table tbody tr:hover { background: var(--surface-2); }
.table tbody tr:last-child td { border-bottom: 0; }
.table td.numeric, .table th.numeric { text-align: right; }

/* ---- Pagination -------------------------------------------------- */
.pagination { display: flex; flex-wrap: wrap; gap: var(--sp-2); justify-content: center; margin-top: var(--sp-6); padding: 0; list-style: none; }
.pagination a, .pagination span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; height: 44px; padding: 0 var(--sp-3);
  border: 1px solid var(--line-300); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink-700); font-size: var(--fs-sm); font-weight: 600;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.pagination a:hover { border-color: var(--teal-600); color: var(--teal-700); background: var(--sky-100); }
.pagination .is-active { background: var(--navy-900); border-color: var(--navy-900); color: #fff; }
.pagination .is-disabled { opacity: .45; pointer-events: none; }

/* ---- Rating stars ------------------------------------------------ */
.stars { display: inline-flex; align-items: center; gap: 2px; color: var(--tm-amber-icon); line-height: 1; }
.stars svg { width: 16px; height: 16px; }
.rating-line { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); }
.rating-bar { flex: 1; height: 8px; background: var(--surface-3); border-radius: var(--r-pill); overflow: hidden; }
.rating-bar__fill { height: 100%; background: var(--tm-amber-icon); border-radius: var(--r-pill); }

/* ---- Progress ---------------------------------------------------- */
.progress { height: 10px; background: var(--surface-3); border-radius: var(--r-pill); overflow: hidden; }
.progress__fill { height: 100%; background: var(--teal-600); border-radius: var(--r-pill); transition: width 300ms ease; }
.progress__fill--warn   { background: var(--warning-600); }
.progress__fill--danger { background: var(--danger-600); }

/* ---- Utilities --------------------------------------------------- */
.text-center { text-align: center; }
.text-right  { text-align: right; }
.text-muted  { color: var(--ink-500); }
.text-sm { font-size: var(--fs-sm); }
.text-xs { font-size: var(--fs-xs); }
.fw-600 { font-weight: 600; }
.fw-700 { font-weight: 700; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }
.mt-2 { margin-top: var(--sp-2); } .mb-2 { margin-bottom: var(--sp-2); }
.mt-3 { margin-top: var(--sp-3); } .mb-3 { margin-bottom: var(--sp-3); }
.mt-4 { margin-top: var(--sp-4); } .mb-4 { margin-bottom: var(--sp-4); }
.mt-5 { margin-top: var(--sp-5); } .mb-5 { margin-bottom: var(--sp-5); }
.gap-2 { gap: var(--sp-2); } .gap-3 { gap: var(--sp-3); }
.flex-1 { flex: 1; }
.hidden { display: none !important; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Long unbroken strings (emails, URLs) must never widen the layout. */
.break-word { overflow-wrap: anywhere; word-break: break-word; }

/* ---- Responsive -------------------------------------------------- */
/* The display sizes scale continuously via clamp(), so only the spacing
   rhythm is stepped down here. */
@media (max-width: 900px) {
  :root { --sp-7: 2.5rem; --sp-8: 3.25rem; }
}
@media (max-width: 640px) {
  :root { --sp-7: 2.25rem; --sp-8: 2.75rem; }
  .container { padding-inline: var(--sp-3); }
  .grid { gap: var(--sp-4); }
  .modal__footer { flex-direction: column-reverse; }
  .modal__footer .btn { width: 100%; }
  .card__body { padding: var(--sp-4); }
}
@media (max-width: 380px) {
  :root { --fs-base: 0.95rem; }
  .btn { padding: .7rem 1rem; }
}

@media print {
  .no-print, .site-header, .site-footer, .toast-stack, .assistant-fab { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; border-color: #ccc; break-inside: avoid; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
