/* ==========================================================================
   Palu Fuel — buyer portal design layer
   Covers the account + auth screens (/login, /register, /forgot-password,
   /reset, /dashboard, /dashboard/fuelpasses/<id>, /dashboard/settings).

   Everything is scoped to `body.portal-body`, which base.html adds only for
   `account.*` endpoints — the marketing pages keep the original public chrome.
   The portal intentionally keeps the public pill buttons and Space Grotesk
   headings; what it gains is the admin console's *quality* bar: brand (not
   Bootstrap-blue) links, WCAG-passing muted ink, real target sizes, sticky
   tables, proper empty states and a dark theme.
   ========================================================================== */

body.portal-body {
  --p-surface: #fff;
  --p-surface-2: var(--paper);
  --p-line: var(--line);
  --p-ink: var(--navy);
  --p-ink-soft: #3d4f63;
  --p-muted: #5c6b7d;          /* 5.05:1 on the sand page — #8a97a6 was 2.98:1 */
  --p-link: var(--blue);       /* 8.27:1 — Bootstrap's #0d6efd was exactly 4.5:1 */
  --p-link-hover: var(--red-deep);
  --p-red-ink: var(--red);
  --p-ring: rgba(11, 79, 130, .32);
  --p-header: rgba(253, 251, 246, .92);
  /* deliberate backgrounds (kept separate from the ink tokens — in dark mode the
     ink is light, so reusing it as a background inverted the table header) */
  --p-thead-bg: var(--navy);
  --p-thead-fg: #fff;
  --p-active-bg: var(--navy);
  --p-active-fg: #fff;

  /* status chip tones */
  --p-chip-green-bg: #eef7f0; --p-chip-green-fg: #1F5B33;
  --p-chip-grey-bg: #eef1f4;  --p-chip-grey-fg: #4f5f70;
  --p-chip-red-bg: #fdecec;   --p-chip-red-fg: #a13a35;
  --p-chip-amber-bg: #fff8e6; --p-chip-amber-fg: #7a5b00;

  /* banners */
  --p-warn-bg: #fff8e6; --p-warn-bd: #f0dca8; --p-warn-fg: #7a5b00;
  --p-good-bg: #eef7f0; --p-good-bd: #bfe3c8; --p-good-fg: #1F5B33;
  --p-bad-bg: #fdecec;  --p-bad-bd: #f2b6b6;  --p-bad-fg: #8f1f1f;
  --p-info-bg: #eef1f4; --p-info-bd: #d7dee6; --p-info-fg: #4f5f70;
}

/* Dark theme — a token swap plus overrides for the shared public chrome
   (header, footer, cards, inputs) that lives outside this stylesheet. */
html[data-theme="dark"] body.portal-body {
  --p-surface: #151c24;
  --p-surface-2: #1b242e;
  --p-line: #2a3540;
  --p-ink: #e9eff5;
  --p-ink-soft: #c3ced9;
  --p-muted: #94a3b3;
  --p-link: #8cc0e8;
  --p-link-hover: #a9d3f2;
  --p-red-ink: #ff8095;
  --p-ring: rgba(140, 192, 232, .45);
  --p-header: rgba(12, 17, 22, .92);
  --p-thead-bg: #1d2732;
  --p-thead-fg: #e9eff5;
  --p-active-bg: #2f7ab5;
  --p-active-fg: #fff;

  --p-chip-green-bg: #102a1c; --p-chip-green-fg: #7ee0a8;
  --p-chip-grey-bg: #1e262f;  --p-chip-grey-fg: #b9c6d3;
  --p-chip-red-bg: #2b1417;   --p-chip-red-fg: #fca5a5;
  --p-chip-amber-bg: #2a2210; --p-chip-amber-fg: #fcd34d;

  --p-warn-bg: #2a2210; --p-warn-bd: #4a3b18; --p-warn-fg: #fcd34d;
  --p-good-bg: #102a1c; --p-good-bd: #1c4630; --p-good-fg: #7ee0a8;
  --p-bad-bg: #2b1417;  --p-bad-bd: #4c2126;  --p-bad-fg: #fca5a5;
  --p-info-bg: #1e262f; --p-info-bd: #2f3d4b; --p-info-fg: #b9c6d3;

  background: #0c1116;
  color: var(--p-ink-soft);
  color-scheme: dark;
}

/* --- links: brand ink, not Bootstrap blue -------------------------------
   Scoped to the content area and excluding every component that carries its
   own text colour — a bare `a { color }` would repaint .btn-red, .nav-link,
   .p-tab and the footer links too. */
body.portal-body section a:not(.btn):not(.nav-link):not(.navbar-brand):not(.p-tab) { color: var(--p-link); }
body.portal-body section a:not(.btn):not(.nav-link):not(.navbar-brand):not(.p-tab):hover { color: var(--p-link-hover); }
body.portal-body section p a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; }

/* --- focus ------------------------------------------------------------- */
body.portal-body a:focus-visible,
body.portal-body button:focus-visible,
body.portal-body input:focus-visible,
body.portal-body select:focus-visible,
body.portal-body summary:focus-visible {
  outline: 2px solid var(--p-link);
  outline-offset: 2px;
  border-radius: .35rem;
}

/* --- header ------------------------------------------------------------ */
body.portal-body .wordmark small { color: var(--p-muted); font-size: .6875rem; }
body.portal-body .p-theme-toggle { margin-left: .15rem; }

/* --- page header ------------------------------------------------------- */
body.portal-body .p-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: 1rem; }
body.portal-body .p-meta { color: var(--p-muted); font-size: .875rem; }
body.portal-body .p-hint { color: var(--p-muted); font-weight: 400; }
body.portal-body .p-note { color: var(--p-muted); font-size: .8125rem; margin: .35rem 0 0; }
body.portal-body .p-foot-note { color: var(--p-muted); font-size: .85rem; }
body.portal-body .p-section-title {
  font-size: 1.4rem; margin: 3rem 0 1rem;
}

/* --- segmented tab/filter control ------------------------------------- */
body.portal-body .p-tabs {
  display: flex; flex-wrap: wrap; gap: .25rem;
  background: var(--p-surface-2); border: 1px solid var(--p-line);
  border-radius: 999px; padding: .25rem; width: fit-content; max-width: 100%;
}
body.portal-body .p-tab {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 2.25rem; padding: .35rem 1rem;
  border-radius: 999px; font-size: .875rem; font-weight: 600;
  color: var(--p-ink-soft); text-decoration: none; white-space: nowrap;
}
body.portal-body .p-tab:hover { background: var(--p-surface); color: var(--p-ink); }
body.portal-body .p-tab.is-active {
  background: var(--p-active-bg); color: var(--p-active-fg);
  box-shadow: 0 6px 16px -8px rgba(11, 47, 74, .55);
}
body.portal-body .p-tab.is-active:hover { color: var(--p-active-fg); }
body.portal-body .p-tab .p-tab-count {
  font-variant-numeric: tabular-nums; font-size: .75rem; font-weight: 700;
  background: rgba(11, 47, 74, .08); border-radius: 999px; padding: 0 .4rem;
}
body.portal-body .p-tab.is-active .p-tab-count { background: rgba(255, 255, 255, .22); }

/* --- FuelPass cards ---------------------------------------------------- */
body.portal-body .p-pass {
  position: relative; height: 100%; display: flex; flex-direction: column;
  padding: 1.25rem 1.3rem; overflow: hidden;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
body.portal-body .p-pass::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 4px;
  background: var(--p-chip-green-fg); opacity: .85;
}
body.portal-body .p-pass[data-bucket="used"]::before { background: #8494a6; }
body.portal-body .p-pass[data-bucket="expired"]::before { background: var(--p-chip-red-fg); }
body.portal-body .p-pass:hover { transform: translateY(-2px); box-shadow: 0 18px 34px -18px rgba(11, 47, 74, .3); }
body.portal-body .p-pass-top { display: flex; justify-content: space-between; align-items: flex-start; gap: .6rem; }
body.portal-body .p-pass-amount {
  font-family: 'Space Grotesk', sans-serif; font-size: 1.7rem; font-weight: 700;
  letter-spacing: -.03em; color: var(--p-red-ink); line-height: 1.1;
}
body.portal-body .p-pass-for { color: var(--p-ink-soft); font-size: .95rem; margin-top: .5rem; }
body.portal-body .p-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: auto; padding-top: 1.1rem; }

/* --- status chips ------------------------------------------------------ */
body.portal-body .p-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .2rem .6rem; border-radius: 999px;
  font-size: .75rem; font-weight: 700; white-space: nowrap;
  border: 1px solid transparent;
}
body.portal-body .p-chip::before {
  content: ""; width: .375rem; height: .375rem; border-radius: 50%;
  background: currentColor; flex-shrink: 0;
}
body.portal-body .p-chip--unused   { background: var(--p-chip-green-bg); color: var(--p-chip-green-fg); }
body.portal-body .p-chip--used     { background: var(--p-chip-grey-bg);  color: var(--p-chip-grey-fg); }
body.portal-body .p-chip--expired  { background: var(--p-chip-red-bg);   color: var(--p-chip-red-fg); }
body.portal-body .p-chip--expiring { background: var(--p-chip-amber-bg); color: var(--p-chip-amber-fg); }

/* --- banners (status + verify) ---------------------------------------- */
body.portal-body .p-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: .7rem;
  border: 1px solid var(--p-info-bd); background: var(--p-info-bg); color: var(--p-info-fg);
  border-radius: .9rem; padding: .85rem 1.05rem;
  font-size: .9rem; margin-top: 1.5rem;
}
body.portal-body .p-banner--warn  { background: var(--p-warn-bg); border-color: var(--p-warn-bd); color: var(--p-warn-fg); }
body.portal-body .p-banner--good  { background: var(--p-good-bg); border-color: var(--p-good-bd); color: var(--p-good-fg); }
body.portal-body .p-banner--bad   { background: var(--p-bad-bg);  border-color: var(--p-bad-bd);  color: var(--p-bad-fg); }
body.portal-body .p-banner .p-banner-icon { font-size: 1rem; line-height: 1; }
body.portal-body .p-banner .p-banner-body { flex: 1; min-width: 14rem; }
body.portal-body .p-banner a { color: inherit; text-decoration: underline; }

/* --- empty states ------------------------------------------------------ */
body.portal-body .p-empty {
  display: flex; flex-direction: column; align-items: center; gap: .55rem;
  text-align: center; padding: 2.4rem 1.2rem; margin-top: 1rem;
}
body.portal-body .p-empty .p-empty-icon {
  width: 2.9rem; height: 2.9rem; border-radius: .85rem;
  background: var(--p-surface-2); border: 1px solid var(--p-line);
  display: grid; place-items: center; font-size: 1.3rem; color: var(--p-muted);
}
body.portal-body .p-empty h2 { font-size: 1.05rem; margin: .2rem 0 0; }
body.portal-body .p-empty p { color: var(--p-muted); font-size: .9rem; margin: 0; max-width: 32rem; }

/* --- purchase history table ------------------------------------------- */
body.portal-body .p-table-wrap {
  border: 1px solid var(--p-line); border-radius: 1.15rem;
  background: var(--p-surface); overflow: auto;
  max-height: min(70vh, 40rem);
}
body.portal-body .p-table { width: 100%; margin: 0; border-collapse: separate; border-spacing: 0; font-size: .9rem; }
body.portal-body .p-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--p-thead-bg); color: var(--p-thead-fg);
  font-family: 'Inter', sans-serif; font-weight: 600; font-size: .78rem;
  letter-spacing: .04em; text-transform: uppercase;
  text-align: left; padding: .8rem 1rem; white-space: nowrap;
}
body.portal-body .p-table tbody td {
  padding: .8rem 1rem; border-top: 1px solid var(--p-line);
  color: var(--p-ink-soft); vertical-align: middle; background: var(--p-surface);
}
body.portal-body .p-table tbody tr:nth-child(even) td { background: var(--p-surface-2); }
body.portal-body .p-table tbody tr:hover td { background: rgba(11, 79, 130, .05); }
body.portal-body .p-table .p-table-strong { font-weight: 600; color: var(--p-ink); }
body.portal-body .p-table .p-table-num { font-variant-numeric: tabular-nums; }
body.portal-body .p-table .p-table-open { width: 2.5rem; text-align: right; }
body.portal-body .p-muted { color: var(--p-muted); }
/* Bootstrap's .visually-hidden sets no colour, so it fell back to Bootstrap's
   default dark ink even in dark mode. Inherit the themed ink instead. */
body.portal-body .visually-hidden { color: inherit; }

/* --- clickable purchase-history rows -----------------------------------
   The row is the target: the voucher link is stretched across it with an
   absolutely-positioned ::after, so the whole row is in the hit area while the
   accessible name stays on a real link in the Voucher cell. `position:relative`
   on a <tr> is supported by current Chromium/Firefox/Safari; if it were not,
   the overlay would simply cover the cell instead of the row — the link still
   works either way. */
body.portal-body .p-table tbody tr.p-row-link { position: relative; cursor: pointer; }
body.portal-body .p-table tbody tr.p-row-link .p-row-primary::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
}
body.portal-body .p-table tbody tr.p-row-link:hover td { background: rgba(11, 79, 130, .07); }
body.portal-body .p-table tbody tr.p-row-link:focus-within td { background: rgba(11, 79, 130, .07); }
body.portal-body .p-table tbody tr.p-row-link:hover td:first-child,
body.portal-body .p-table tbody tr.p-row-link:focus-within td:first-child {
  box-shadow: inset 3px 0 0 var(--p-link);
}
body.portal-body .p-table .p-row-primary { font-weight: 600; }
body.portal-body .p-table .p-row-primary:focus-visible { outline-offset: 3px; }
body.portal-body .p-table .p-row-ref {
  display: block; font-weight: 400; font-size: .75rem;
  color: var(--p-muted); font-variant-numeric: tabular-nums;
}
body.portal-body .p-table .p-row-ref--warn { color: var(--p-chip-amber-fg); font-weight: 600; }
body.portal-body .p-table .p-row-chevron { color: var(--p-muted); transition: transform .15s ease, color .15s ease; }
body.portal-body .p-table tbody tr.p-row-link:hover .p-row-chevron,
body.portal-body .p-table tbody tr.p-row-link:focus-within .p-row-chevron {
  color: var(--p-link); transform: translateX(2px);
}
@media (prefers-reduced-motion: reduce) {
  body.portal-body .p-table .p-row-chevron { transition: none; }
}

/* --- voucher (FuelPass detail) ---------------------------------------- */
body.portal-body .p-perf {
  position: relative; padding: 1.9rem 1.5rem; overflow: hidden;
}
body.portal-body .p-perf::before,
body.portal-body .p-perf::after {
  content: ""; position: absolute; width: 1.4rem; height: 1.4rem; border-radius: 50%;
  background: var(--sand); border: 1px solid var(--p-line);
  top: 50%; transform: translateY(-50%);
}
body.portal-body .p-perf::before { left: -0.75rem; }
body.portal-body .p-perf::after { right: -0.75rem; }
body.portal-body .p-perf-brand {
  letter-spacing: .28em; font-size: .72rem; font-weight: 600; color: var(--p-muted);
  text-transform: uppercase;
}
body.portal-body .p-perf-amount {
  font-family: 'Space Grotesk', sans-serif; font-size: 2.6rem; font-weight: 700;
  letter-spacing: -.03em; color: var(--p-red-ink); margin: .35rem 0; line-height: 1;
}
body.portal-body .p-perf-for { color: var(--p-ink-soft); }
body.portal-body .p-perf-station { color: var(--p-muted); font-size: .85rem; }
body.portal-body .p-qr { max-width: min(100%, 420px); border-radius: .9rem; border: 1px solid var(--p-line); }
body.portal-body .p-code-label { font-size: .72rem; letter-spacing: .18em; color: var(--p-muted); text-transform: uppercase; }
body.portal-body .p-code {
  font-family: 'Space Grotesk', sans-serif; font-size: 2rem; font-weight: 700;
  letter-spacing: .35em; color: var(--p-ink); font-variant-numeric: tabular-nums;
}
body.portal-body .p-resend-status { font-size: .85rem; color: var(--p-muted); min-height: 1.2rem; }

/* --- forms ------------------------------------------------------------- */
body.portal-body .form-label { color: var(--p-ink); }
body.portal-body .p-card-title { font-size: 1.15rem; margin: 0 0 1rem; }
body.portal-body .p-auth-state { font-size: .9rem; }
body.portal-body .p-auth-alt { color: var(--p-muted); font-size: .9rem; }
body.portal-body .p-benefits { color: var(--p-ink-soft); padding-left: 1.1rem; }
body.portal-body .p-benefits li + li { margin-top: .45rem; }
body.portal-body .p-benefits li::marker { color: var(--p-red-ink); }

body.portal-body .p-help-list { display: grid; gap: .55rem; padding: 0; margin: 0; list-style: none; }
body.portal-body .p-help-list li { display: flex; gap: .55rem; align-items: flex-start; color: var(--p-ink-soft); font-size: .93rem; }
body.portal-body .p-help-list i { color: var(--p-chip-green-fg); margin-top: .2rem; }

/* --- theme toggle in the header --------------------------------------- */
body.portal-body .p-theme-toggle {
  width: 2.35rem; height: 2.35rem; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--p-line); background: var(--p-surface);
  border-radius: 999px; color: var(--p-ink-soft); font-size: 1rem; cursor: pointer;
}
body.portal-body .p-theme-toggle:hover { background: var(--p-surface-2); color: var(--p-ink); }

/* ==========================================================================
   Dark theme — overrides for the shared public chrome
   ========================================================================== */

html[data-theme="dark"] body.portal-body .site-header { background: var(--p-header); border-bottom-color: var(--p-line); }
html[data-theme="dark"] body.portal-body .wordmark { color: var(--p-ink); }
html[data-theme="dark"] body.portal-body .wordmark small { color: var(--p-muted); }
html[data-theme="dark"] body.portal-body .navbar-nav .nav-link { color: #a9b8c6; }
html[data-theme="dark"] body.portal-body .navbar-nav .nav-link:hover,
html[data-theme="dark"] body.portal-body .navbar-nav .nav-link.active { color: #fff; }
html[data-theme="dark"] body.portal-body .navbar-toggler { border-color: var(--p-line); }
html[data-theme="dark"] body.portal-body .navbar-toggler-icon { filter: invert(1) grayscale(1) brightness(1.9); }
html[data-theme="dark"] body.portal-body .nav-link[style] { color: #cfdae5 !important; }

html[data-theme="dark"] body.portal-body section { background: transparent; }
html[data-theme="dark"] body.portal-body h1,
html[data-theme="dark"] body.portal-body h2,
html[data-theme="dark"] body.portal-body h3,
html[data-theme="dark"] body.portal-body h4,
html[data-theme="dark"] body.portal-body h5 { color: var(--p-ink); }
html[data-theme="dark"] body.portal-body .sec-lead,
html[data-theme="dark"] body.portal-body .sec-eyebrow { color: var(--p-muted); }
html[data-theme="dark"] body.portal-body .sec-eyebrow { color: var(--p-red-ink); }
html[data-theme="dark"] body.portal-body .card-soft { background: var(--p-surface); border-color: var(--p-line); }
html[data-theme="dark"] body.portal-body .p-table-wrap { border-color: var(--p-line); }

html[data-theme="dark"] body.portal-body .input-lg {
  background: var(--p-surface); border-color: var(--p-line); color: var(--p-ink);
}
html[data-theme="dark"] body.portal-body .input-lg::placeholder { color: #7b8899; }
html[data-theme="dark"] body.portal-body .input-lg:focus { border-color: var(--p-link); box-shadow: 0 0 0 4px rgba(140, 192, 232, .18); }
html[data-theme="dark"] body.portal-body .form-control,
html[data-theme="dark"] body.portal-body .form-select { background: var(--p-surface); border-color: var(--p-line); color: var(--p-ink); }

html[data-theme="dark"] body.portal-body .btn-navy { background: #1d4a6e; color: #fff; }
html[data-theme="dark"] body.portal-body .btn-navy:hover { background: #24618f; color: #fff; }
html[data-theme="dark"] body.portal-body .btn-outline-navy { border-color: #4a6b86; color: #cfe0ee; }
html[data-theme="dark"] body.portal-body .btn-outline-navy:hover { background: #1d4a6e; color: #fff; border-color: #1d4a6e; }

html[data-theme="dark"] body.portal-body footer { background: #0a1219; color: #b9c6d3; }
html[data-theme="dark"] body.portal-body footer a { color: #b9c6d3; }
html[data-theme="dark"] body.portal-body footer a:hover { color: #fff; }
html[data-theme="dark"] body.portal-body footer .bottom { color: #93a3b4; }
html[data-theme="dark"] body.portal-body footer .bottom a { color: #93a3b4; }

html[data-theme="dark"] body.portal-body .p-perf::before,
html[data-theme="dark"] body.portal-body .p-perf::after { background: #0c1116; }

html[data-theme="dark"] body.portal-body .alert-success { background: #102a1c; border-color: #1c4630; color: #7ee0a8; }
html[data-theme="dark"] body.portal-body .alert-danger { background: #2b1417; border-color: #4c2126; color: #fca5a5; }

@media (prefers-reduced-motion: reduce) {
  body.portal-body .p-pass { transition: none; }
  body.portal-body .p-pass:hover { transform: none; }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* The public nav is already dense (7 links + 3 actions) and has almost no slack
   between 992px and the point where the links wrap, so the toggle only appears
   where it actually fits — without this the extra ~48px overflows the navbar.
   Declared last so it beats the base `display` on source order. */
@media (max-width: 1199.98px) {
  body.portal-body .p-theme-toggle { display: none; }
}

@media (max-width: 640px) {
  body.portal-body .p-section-title { margin-top: 2.2rem; }
  body.portal-body .p-tabs { width: 100%; justify-content: space-between; }
  body.portal-body .p-tab { flex: 1; justify-content: center; padding-inline: .6rem; }
  body.portal-body .p-perf { padding: 1.4rem 1.1rem; }
  body.portal-body .p-code { font-size: 1.6rem; letter-spacing: .22em; }
}
