/*
 * PADUM design tokens — shared by the admin app and the public site.
 *
 * Colours come from the 2024 CI guideline (PADUM-CI-gudeline.pdf, p.8) and
 * carry the semantic roles the requirements doc assigns (§8.1). The two
 * sources are complementary: the brand book supplies hexes, the spec supplies
 * meanings.
 *
 * Typography follows the CI's own choices where they are web-licensable.
 * IBM Plex Sans / IBM Plex Sans Thai are exactly what the brand book
 * specifies for subheads and body. The headline faces are not: DIN Condensed
 * and FC Bluewhale are both commercial, so Barlow Condensed stands in for DIN
 * (same grotesk-derived condensed character) and IBM Plex Sans Thai Bold for
 * Thai headlines. Swapping in licensed files later is a change to
 * --font-head alone.
 */

:root {
  /* --- brand, from CI p.8 primary + supporting ------------------------- */
  --brand:        #244D78;   /* primary: nav, headers, primary buttons     */
  --brand-dark:   #1A3A5C;   /* pressed states, high-contrast text on pale */
  --brand-mid:    #346B8F;   /* supporting: secondary surfaces             */
  --brand-soft:   #539DB8;   /* supporting: links, quiet accents           */
  --brand-pale:   #95D1EB;   /* supporting: pills, tinted backgrounds      */
  --brand-wash:   #E8F2F8;   /* derived: lightest tint for table stripes   */

  /* CI yellow. A FILL, never a button with white text — #FAC669 against
     white is ~1.6:1 and fails WCAG at any size. Dark text only. */
  --accent:       #FAC669;
  --accent-warm:  #EEA570;
  --accent-wash:  #FEF4E0;
  --accent-ink:   #7A4E06;   /* readable text on the yellow wash           */

  /* CI coral. Also a primary brand colour, so it does NOT mean "error" —
     it means "a person has to do something here": overdue, blocking, or
     destructive. Used sparingly enough to keep that signal. */
  --danger:       #D2564E;
  --danger-wash:  #FBEDEC;
  --danger-tint:  #F8CFCB;   /* badge fill over a photo; --danger-ink = 5.30 */
  --danger-ink:   #96322B;

  --warn:         #B45309;   /* kept for prose warnings on tinted panels   */
  --warn-wash:    #FEF3C7;

  /* Green is off-palette on purpose: it is the only colour meaning "done
     and needs nothing from you" — fully booked, paid, complete. Never use
     it decoratively or it stops carrying that. */
  --success:      #1F8A5F;
  --success-wash: #E4F5EE;
  --success-tint: #A8E6C7;   /* badge fill over a photo; --success-ink = 5.26 */
  --success-ink:  #15613F;

  /*
   * Status scale (§8.1). Five roles, and every status pill in either app
   * resolves to one of them:
   *
   *   green   full · paid · complete        — done, needs nothing
   *   blue    open · upcoming · normal      — healthy, in progress
   *   yellow  partly filled · pending · needs input
   *   coral   needs action now · overdue · blocking
   *   grey    staff · inactive · n/a
   */

  /* --- neutrals -------------------------------------------------------- */
  --bg:           #F6F6F6;
  --surface:      #FFFFFF;
  --surface-alt:  #EEF1F5;
  --border:       #DDE2E8;
  --border-strong:#C3CCD6;
  --text:         #1B2733;
  --text-muted:   #5C6577;
  --text-faint:   #8A94A3;

  /* --- type ------------------------------------------------------------ */
  --font-head: 'Barlow Condensed', 'IBM Plex Sans Thai', 'Arial Narrow', sans-serif;
  --font-body: 'IBM Plex Sans', 'IBM Plex Sans Thai', system-ui, -apple-system, sans-serif;

  /* Six sizes, and only six.
   *
   * The admin stylesheet had grown eighteen distinct font-size values, which
   * is how the Bookings table (.9375rem) and the Activity table (.8125rem)
   * ended up different sizes for the same kind of content — nobody chose that,
   * it accumulated. A rule that wants a size picks the nearest of these
   * instead of inventing one.
   *
   * The steps are ~1.2x apart, except body→meta which is tighter: those two
   * sit side by side inside a table cell all over the app, and a full step
   * between them reads as a hierarchy that isn't there.
   */
  --fs-page:  1.8rem;    /* the h1 naming a page; 2.1rem on desktop        */
  --fs-head:  1.25rem;   /* section and panel headings                     */
  --fs-sub:   1rem;      /* card titles, h4                                */
  --fs-body:  .9375rem;  /* the default: table cells, fields, prose        */
  --fs-meta:  .8125rem;  /* second lines, .muted-sm, timestamps            */
  --fs-micro: .6875rem;  /* column headings, tab bar, uppercase labels     */

  /* --- banks ------------------------------------------------------------
   * One accent per bank, taken from that bank's own identity so an account is
   * recognised before its name is read.
   *
   * Every one is measured against both surfaces and clears 3:1, the threshold
   * for a non-text mark. Two are darkened from the bank's literal colour
   * because the literal one cannot be seen on white: Krungthai's #01A0E2 sits
   * at 2.95 and Krungsri's #FEC43B at 1.59. These are used as a stripe and a
   * dot, never behind text — that would need 4.5:1 and none of them would pass.
   */
  --bank-kbank: #138F2D;   /* Kasikorn green            4.20 on white */
  --bank-ttb:   #1C4E9C;   /* ttb blue                  8.02 */
  --bank-ktb:   #0083BA;   /* Krungthai, darkened       4.24 */
  --bank-bay:   #A87400;   /* Krungsri gold, darkened   4.07 */
  --bank-cimb:  #EC1C24;   /* CIMB red                  4.41 */
  --bank-none:  #8A94A3;   /* no bank recorded */

  /* --- controls ---------------------------------------------------------
   * ONE size for every text box, select and date input in the admin.
   *
   * There were nine. A form field rendered 44.4px at 16px while the cabin box
   * beside it in the same dialog rendered 31.75px at 13px — 40% apart — and
   * four controls in the Set price dialog had no CSS at all and fell through
   * to the browser.
   *
   * The height was never the real lever: `font: inherit` resolves to the body's
   * 16px, so a field's content box alone came to 44.4px and the declared
   * `min-height: 44px` did nothing. Naming the font size is what fixes it,
   * exactly as .btn already does for buttons a few rules below.
   *
   * 40px on a phone keeps a usable touch target; 34px from 768px up matches
   * the cabin box, which is the one that reads right on a desktop.
   */
  /* Tick boxes. The only token this file gains for the admin redesign — it
     lives here rather than in admin.css because checkboxes exist in both
     apps, and one number is the whole point. */
  --check-size:    20px;

  --control-h:     40px;
  --control-h-sm:  34px;
  --control-pad:   .4rem .55rem;
  --control-pad-sm:.3rem .5rem;

  /* --- shape ----------------------------------------------------------- */
  --radius:    8px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --shadow:    0 1px 2px rgba(27, 39, 51, .06), 0 1px 3px rgba(27, 39, 51, .10);
  --shadow-lg: 0 8px 28px rgba(27, 39, 51, .16);

  /* The shape of every cover photo: a card on the trips list and on /boats, a
     boat page's hero, and the crop preview in the admin's cover dialog. Here,
     not in site.css, because the admin shows staff the same crop before they
     upload, and one number is what keeps the trip and boat cards alike. */
  --cover-ratio: 4 / 3;

  /* Height of the mobile bottom tab bar, so page content can reserve room
     for it in one place rather than every view guessing. */
  --tabbar-h: 60px;
  --topbar-h: 56px;
}

*, *::before, *::after { box-sizing: border-box; }

/* Any explicit `display` on an element beats the UA stylesheet's
   `[hidden] { display: none }`, so a hidden panel with `display: grid` stays
   on screen. This restores `hidden` as a reliable switch — without it the
   admin app renders its login screen and its dashboard simultaneously. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
}

/*
 * Barlow Condensed at 700 is very dense — condensed letterforms plus heavy
 * weight plus tight leading read as a solid block. 600 with more leading and
 * a little tracking keeps the CI's condensed voice and stays legible at the
 * small sizes this app actually uses.
 */
h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: .015em;
  margin: 0 0 .4em;
}

/* The CI specifies all-caps for DIN Condensed headlines (p.9). Applied to
   the top level only — all-caps Thai is not a thing, and the Thai fallback
   face inherits this rule otherwise. */
h1 { font-size: 2rem; text-transform: uppercase; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.15rem; }
:lang(th) h1 { text-transform: none; }

a { color: var(--brand); }

/* ------------------------------------------------------- brochure prose */
/* Shared because /shared/prose.js builds this markup for both apps. */
/*
 * Brochure fields are one item per line. As a single pre-formatted block a
 * seven-item exclusion list read as a paragraph; as a list it reads as a list.
 */
.prose-list {
  margin: 0;
  padding-left: 1.15rem;
  display: grid;
  gap: .3rem;
  font-size: .9375rem;
  line-height: 1.55;
}
.prose-list li { padding-left: .15rem; }
.prose-list li::marker { color: var(--brand-soft); }

/* Itinerary lines are "5 Dec: 4 dives — …"; emphasising the date turns the
   list into a schedule. */
.prose-list__label {
  font-weight: 600;
  color: var(--brand-dark);
  margin-right: .35rem;
}

/* Caveats, not items — set apart so they stop competing with the list. */
.prose-note {
  margin: .6rem 0 0;
  padding-top: .5rem;
  border-top: 1px solid var(--border);
  font-size: .8125rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--text-muted);
}
.prose-note + .prose-note { margin-top: .3rem; padding-top: 0; border-top: 0; }

/* ------------------------------------------------------------------ pills */
.pill {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  padding: .18em .7em;
  border-radius: var(--radius-pill);
  font-size: .8125rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
.pill--brand   { background: var(--brand-wash);   color: var(--brand-dark); }
.pill--accent  { background: var(--accent-wash);  color: var(--accent-ink); }
.pill--danger  { background: var(--danger-wash);  color: var(--danger-ink); }
.pill--warn    { background: var(--warn-wash);    color: var(--warn); }
.pill--success { background: var(--success-wash); color: var(--success-ink); }
.pill--muted   { background: var(--surface-alt);  color: var(--text-muted); }

/*
 * Quiet variant, for a state that is true of nearly everything.
 *
 * Every trip currently lacks an installment schedule, so 24 solid badges
 * teach staff to ignore the colour entirely. Outlined keeps the same hue and
 * the same meaning while letting a genuinely per-item urgent state — one
 * overdue payment among many — still stand out beside it.
 */
.pill--quiet {
  background: transparent;
  border: 1px solid currentColor;
  font-weight: 500;
  opacity: .85;
}

/* --------------------------------------------------- language switch */
/*
 * One control, top-right, shared by both apps. It was previously duplicated:
 * the public site had it in its header, while the admin had two separate
 * inline copies with independent state, so the two admin pages could disagree
 * about which language was showing.
 */
.lang-switch {
  display: inline-flex;
  flex: none;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface);
  overflow: hidden;
}
.lang-switch button {
  font: inherit;
  font-size: .8125rem;
  font-weight: 600;
  min-height: 36px;
  padding: .25rem .8rem;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.lang-switch button.is-active { background: var(--brand); color: #fff; }
.lang-switch button:focus-visible {
  outline: 3px solid var(--brand-soft);
  outline-offset: -3px;
}
/* On a dark bar the control needs to read as part of it, not as a hole. */
.lang-switch--on-dark {
  border-color: rgba(255, 255, 255, .45);
  background: transparent;
}
.lang-switch--on-dark button { color: rgba(255, 255, 255, .85); }
.lang-switch--on-dark button.is-active { background: #fff; color: var(--brand); }

/* ---------------------------------------------------------------- buttons */
/*
 * Two button sizes and no others: .btn at 44px for a dialog's own footer, and
 * .btn--sm at 36px everywhere else — page headers, table rows, card heads.
 *
 * The explicit font-size is not redundant. `font: inherit` alone made a button
 * 15px inside a table and 16px inside a dialog, so the same control was two
 * sizes depending on where it stood.
 */
.btn {
  font: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  padding: .6rem 1.1rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  /* 44px minimum touch target — 70% of usage is mobile (§1). */
  min-height: 44px;
}
.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-dark); }
.btn--ghost {
  background: var(--surface);
  color: var(--brand);
  border-color: var(--border-strong);
}
.btn:focus-visible {
  outline: 3px solid var(--brand-soft);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------- cards */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

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