/* ============================================================
   Atlas Portal — Mobile-first shell ("Clean Pro")
   Loaded globally by MainLayout.razor. All rules are namespaced
   under .portal-root so admin pages are unaffected.
   ============================================================ */

/* Kaapstad Naked-page bg — applied by a <head>-level script in MainLayout
   that tags <html> with .portal-bg-navy based on location.pathname. Setting
   the bg here (loaded in the initial request response) means the navy paints
   on the VERY FIRST frame, before any Blazor or per-page <style> runs.
   Without this, there's a brief white flash during the initial load of a
   portal page (tailwind's default body bg is white). */
html.portal-bg-navy,
html.portal-bg-navy body {
    background: #1A2540;
}
html.portal-bg-navy > body > .flex.flex-col.min-h-screen > .flex.flex-1 > main {
    padding: 0;
    background: transparent;
}

/* Self-hosted variable font — never CDN-loaded (offline PWA) */
@font-face {
    font-family: 'Geist';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/fonts/geist-wght-normal.woff2') format('woff2-variations');
}

:root {
    /* Core neutrals (Zinc) — bg is pure white; surface-2 only for subtle
       recessed zones (toggle-switch track, segmented-control background). */
    --portal-bg:          #FFFFFF;
    --portal-surface:     #FFFFFF;
    --portal-surface-2:   #F4F4F5;
    --portal-border:      #E4E4E7;
    --portal-border-hard: #D4D4D8;
    --portal-text:        #18181B;
    --portal-text-soft:   #52525B;
    --portal-text-muted:  #A1A1AA;

    /* Accent — single blue */
    --portal-accent:      #2563EB;
    --portal-accent-deep: #1D4ED8;
    --portal-accent-soft: #DBEAFE;
    --portal-accent-faint:#EFF6FF;

    /* Semantic */
    --portal-success:      #16A34A;
    --portal-success-soft: #DCFCE7;
    --portal-warning:      #CA8A04;
    --portal-warning-soft: #FEF3C7;
    --portal-danger:       #DC2626;
    --portal-danger-soft:  #FEE2E2;

    /* Restrained shadows */
    --portal-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
    --portal-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
    --portal-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.04);

    /* Tight radii */
    --portal-radius-sm: 8px;
    --portal-radius-md: 12px;
    --portal-radius-lg: 16px;

    --portal-font: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

    --portal-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --portal-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

    --portal-safe-bottom: env(safe-area-inset-bottom, 0px);
    --portal-safe-top:    env(safe-area-inset-top, 0px);
    --portal-tabbar-height: 64px;

    /* ============ 8-point spacing grid (use these, nothing else) ============ */
    --space-1:  4px;
    --space-2:  8px;
    --space-3:  12px;
    --space-4:  16px;
    --space-5:  20px;   /* page side padding */
    --space-6:  24px;
    --space-8:  32px;
    --space-10: 40px;

    /* ============ Typography scale ============ */
    --fs-xs:  11px;  /* eyebrow / metadata */
    --fs-sm:  13px;  /* secondary body, captions */
    --fs-md:  14px;  /* body default */
    --fs-lg:  16px;  /* card title */
    --fs-xl:  18px;  /* sub-section heading */
    --fs-2xl: 22px;  /* page title (mobile) */
    --fs-3xl: 28px;  /* hero / greeting */

    --lh-tight:   1.15;
    --lh-snug:    1.3;
    --lh-normal:  1.5;

    /* ============ Rhythm tokens ============ */
    --page-pad-x:       var(--space-5);   /* 20 */
    --page-pad-top:     var(--space-5);   /* 20 */
    --block-gap:        var(--space-3);   /* 12 between stacked cards */
    --section-gap:      var(--space-6);   /* 24 between eyebrow'd sections */
    --header-to-body:   var(--space-4);   /* 16 from h1 to first card */

    --card-pad:         18px;             /* internal card padding */
    --card-radius:      12px;
    --card-border:      1px solid var(--portal-border);
}

/* ------------------------------------------------------------
   Portal root — opt-in wrapper (layout.cssClass = "portal-root")
   ------------------------------------------------------------ */
.portal-root {
    min-height: 100vh;
    min-height: 100dvh;
    background: var(--portal-bg);
    color: var(--portal-text);
    font-family: var(--portal-font);
    font-feature-settings: "ss01", "cv11";
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    touch-action: manipulation;
    padding-top: var(--portal-safe-top);
    margin: 0;
}

/* Tabbar scroll buffer — the tricky bit. Pages set layout.cssClass = "!p-0 portal-root"
   which Tailwind compiles to `padding: 0 !important` on the wrapper. That wins over any
   single-property `padding-bottom: ... !important` at the same specificity. We bump
   specificity with a double-class selector so our padding-bottom overrides the !p-0
   shorthand. Without this, the last card on a scrolling page ends flush against the
   tab bar top edge and looks clipped. */
.portal-root.portal-root {
    padding-bottom: calc(var(--portal-tabbar-height) + var(--portal-safe-bottom) + 80px) !important;
}

/* A generic footer spacer some pages can drop in as the last row to add
   extra air at the end of a content flow (e.g. when a page has many cards
   and we want some breathing room before the tab bar backdrop starts).
   Usage: <div class="portal-footer-spacer"></div> inside any portal row. */
.portal-footer-spacer { height: var(--space-10); }

/* When a portal page loads, neutralise any admin chrome the MainLayout
   wrapper still emits so the portal-root sits edge-to-edge. */
body:has(.portal-root) {
    background: var(--portal-bg);
}
body:has(.portal-root) > .flex.flex-col.min-h-screen > .flex.flex-1 > main {
    padding: 0;
    background: transparent;
}
/* Portal wrapper has its own padding policy — the layout JSON adds the "!p-0"
   class to the wrapper to kill FileBasedPage's default p-6. We do NOT force
   padding: 0 on it here, because the portal-root rule needs padding-top +
   padding-bottom to work (tabbar scroll buffer). So we only zero horizontal
   padding on any nested .p-6 that isn't itself the portal-root. */
body:has(.portal-root) > .flex.flex-col.min-h-screen > .flex.flex-1 > main > article > .p-6:not(.portal-root),
body:has(.portal-root) > .flex.flex-col.min-h-screen > .flex.flex-1 > main > article > * > .p-6:not(.portal-root) {
    padding: 0 !important;
}

/* ------------------------------------------------------------
   Typography primitives (bound to --fs-* scale — NEVER hard-code)
   ------------------------------------------------------------ */
.portal-root h1, .portal-root h2, .portal-root h3, .portal-root h4 {
    margin: 0;
    letter-spacing: -0.01em;
    color: var(--portal-text);
    line-height: var(--lh-tight);
}
.portal-h1 {
    font-weight: 600;
    font-size: var(--fs-2xl);
    letter-spacing: -0.02em;
    line-height: var(--lh-tight);
}
.portal-h2 {
    font-weight: 600;
    font-size: var(--fs-xl);
    letter-spacing: -0.015em;
    line-height: var(--lh-snug);
}
.portal-h3 {
    font-weight: 600;
    font-size: var(--fs-lg);
    letter-spacing: -0.005em;
}
.portal-eyebrow,
.portal-section-label {
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--portal-text-muted);
    display: block;
    line-height: 1;
}
.portal-muted { color: var(--portal-text-soft); }
.portal-dim   { color: var(--portal-text-muted); }

/* ------------------------------------------------------------
   STRICT spacing enforcement inside .portal-root

   Every portal page gets the same side padding, same card rhythm,
   same eyebrow-to-card gap. This is the single source of truth — if
   a page deviates, it looks "off" because the rhythm breaks.
   ------------------------------------------------------------ */

/* Page-level outer wrapper (the FileBasedPage <div class="p-6 overflow-hidden !p-0 portal-root">).
   The top padding gives the page title breathing room off the status bar / admin-chrome top
   (without it, "Hello, Tc" / "My Rallies" / etc. feel squashed against the top edge). */
.portal-root {
    padding-top: calc(var(--portal-safe-top) + var(--space-8));
}

/* Every Atlas CardPart gets the standard margin + internal padding + border + shadow */
.portal-root section.flex.flex-col.bg-card-bg {
    background: var(--portal-surface) !important;
    border: var(--card-border) !important;
    border-radius: var(--card-radius) !important;
    box-shadow: var(--portal-shadow-sm) !important;
    color: var(--portal-text);
    margin: 0 var(--page-pad-x) var(--block-gap) !important;
    overflow: hidden;
}
.portal-root section.flex.flex-col.bg-card-bg > .flex-1 {
    padding: var(--card-pad) !important;
    color: inherit !important;
}

/* Opt-out: any Card with cssClass containing "bg-transparent" (or the
   portal convention "portal-card--bare") goes back to being a plain
   transparent wrapper — no border, no bg, no inner padding. Use for
   pages where the Card is just a container to inject HTML into, not a
   visible surface (rally list, summary stats, custom hero cards, etc.) */
.portal-root [class*="bg-transparent"] > section.flex.flex-col.bg-card-bg,
.portal-root .portal-card--bare > section.flex.flex-col.bg-card-bg {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    margin: 0 var(--page-pad-x) var(--block-gap) !important;
}
.portal-root [class*="bg-transparent"] > section > .flex-1,
.portal-root .portal-card--bare > section > .flex-1 {
    padding: 0 !important;
}
/* Opt-out with ZERO outer margin (for "full-bleed" list containers) */
.portal-root [class*="!p-0"] > section.flex.flex-col.bg-card-bg,
.portal-root [class*="p-0 "] > section.flex.flex-col.bg-card-bg {
    margin: 0 !important;
}

/* Page header (h1 Label) — fixed position: 20px x, 20px top, 16px bottom */
.portal-root [data-part-id="pageHeader"],
.portal-root [data-part-id$="Header"]:first-of-type {
    display: block !important;
    padding: 0 var(--page-pad-x) !important;
    margin: 0 0 var(--header-to-body) !important;
    font-size: var(--fs-2xl) !important;
    font-weight: 600 !important;
    letter-spacing: -0.02em !important;
    line-height: var(--lh-tight) !important;
    color: var(--portal-text) !important;
}

/* Page sub-header (Label immediately under pageHeader) */
.portal-root [data-part-id="pageSubtitle"],
.portal-root [data-part-id$="Subtitle"] {
    display: block !important;
    padding: 0 var(--page-pad-x) !important;
    margin: calc(var(--space-1) * -3) 0 var(--space-5) !important; /* tighten against header */
    font-size: var(--fs-md) !important;
    font-weight: 400 !important;
    color: var(--portal-text-soft) !important;
    line-height: var(--lh-normal) !important;
}

/* Section eyebrow labels ("YOUR NEXT RALLY", "QUICK ACTIONS", etc.) —
   consistent spacing top + below, regardless of the page's own CSS */
.portal-root .portal-section-label,
.portal-root .portal-eyebrow {
    padding: 0 var(--page-pad-x) !important;
    margin: var(--section-gap) 0 var(--space-3) !important;
    line-height: 1 !important;
}

/* First card after an eyebrow — no extra top margin (eyebrow handles the gap) */
.portal-root .portal-section-label + section.flex.flex-col.bg-card-bg,
.portal-root .portal-eyebrow + section.flex.flex-col.bg-card-bg {
    margin-top: 0 !important;
}

/* Form inputs — standard 44px height, 10px radius, 12px horizontal pad */
.portal-root input[type="text"],
.portal-root input[type="email"],
.portal-root input[type="tel"],
.portal-root input[type="password"],
.portal-root input[type="number"],
.portal-root input[type="search"],
.portal-root input[type="url"],
.portal-root input[type="date"],
.portal-root select,
.portal-root textarea {
    font-family: var(--portal-font) !important;
    font-size: var(--fs-md) !important;
    min-height: 44px;
    padding: 0 var(--space-3) !important;
    background: var(--portal-surface) !important;
    border: 1px solid var(--portal-border) !important;
    border-radius: 10px !important;
    color: var(--portal-text) !important;
    outline: none !important;
    transition: border-color 0.15s, box-shadow 0.15s;
    -webkit-appearance: none;
    appearance: none;
    box-shadow: none !important;
    width: 100%;
    box-sizing: border-box;
}
.portal-root textarea {
    min-height: 96px;
    padding: var(--space-3) !important;
    line-height: var(--lh-normal);
    resize: vertical;
}
.portal-root input:focus,
.portal-root select:focus,
.portal-root textarea:focus {
    border-color: var(--portal-accent) !important;
    box-shadow: 0 0 0 3px var(--portal-accent-faint) !important;
}
.portal-root input::placeholder,
.portal-root textarea::placeholder {
    color: var(--portal-text-muted) !important;
}

/* ------------------------------------------------------------
   Keyboard focus backstop — catches raw <a>/<button> emitted from
   HtmlContent parts + Card.Content strings that aren't .portal-btn.
   Without this, keyboard users lose focus feedback on any page-emitted
   interactive element (household edit buttons, banking copy, overdue
   CTA link, calendar event links, etc.). .portal-btn + input rings
   below take precedence via higher-specificity selectors.
   ------------------------------------------------------------ */
.portal-root a:focus-visible,
.portal-root button:focus-visible,
.portal-root [role="button"]:focus-visible {
    outline: 2px solid var(--portal-accent);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Field labels (for <label class="..."> next to inputs) — Atlas renders these
   as .form-label or inside form-group; standardise their spacing. */
.portal-root label.form-label,
.portal-root .form-group > label,
.portal-root .portal-field-label {
    display: block;
    font-size: var(--fs-sm) !important;
    font-weight: 500 !important;
    color: var(--portal-text) !important;
    margin: 0 0 var(--space-2) !important;
    letter-spacing: 0 !important;
    text-transform: none !important;
}

/* ------------------------------------------------------------
   Buttons — unified system

   Hierarchy:
     --primary    solid near-black on light, the "main action" pill
     --accent     solid blue, use sparingly for critical CTAs (Pay, Save)
     --ghost      white on border, secondary "escape" action
     --danger     destructive (Cancel booking, Delete)
     --link       text-only, inline "read more" etc.

   Sizes:
     --sm   36px, compact inline action
     default 44px, standard (touch target min)
     --lg   52px, primary hero CTAs
   ------------------------------------------------------------ */
.portal-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 18px;
    min-height: 44px;
    height: 44px;
    border: 1px solid transparent;
    border-radius: 10px;
    font-family: var(--portal-font);
    font-weight: 500;
    font-size: 14px;
    letter-spacing: -0.005em;
    cursor: pointer;
    text-decoration: none;
    user-select: none;
    white-space: nowrap;
    transition: background 0.15s var(--portal-ease-out),
                border-color 0.15s var(--portal-ease-out),
                box-shadow 0.15s var(--portal-ease-out),
                transform 0.08s var(--portal-ease-out),
                color 0.15s;
}
.portal-btn:active { transform: scale(0.98); }
.portal-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--portal-accent-faint),
                0 0 0 5px var(--portal-accent);
}
.portal-btn--block { width: 100%; }
.portal-btn--sm { min-height: 36px; height: 36px; padding: 0 14px; font-size: 13px; border-radius: 8px; }
.portal-btn--lg { min-height: 52px; height: 52px; padding: 0 22px; font-size: 15px; border-radius: 12px; }

/* Primary — dark neutral, the default "main action" */
.portal-btn--primary {
    background: var(--portal-text);
    color: var(--portal-surface);
    border-color: var(--portal-text);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.12) inset,
        0 1px 2px rgba(0, 0, 0, 0.12),
        0 1px 3px rgba(0, 0, 0, 0.05);
}
.portal-btn--primary:hover { background: #27272A; border-color: #27272A; }
.portal-btn--primary:active { background: #09090B; transform: scale(0.98); }

/* Accent — single blue, critical CTA (Pay, Save changes, Confirm booking) */
.portal-btn--accent {
    background: var(--portal-accent);
    color: #FFF;
    border-color: var(--portal-accent);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.18) inset,
        0 2px 4px rgba(37, 99, 235, 0.24),
        0 1px 2px rgba(37, 99, 235, 0.12);
}
.portal-btn--accent:hover { background: var(--portal-accent-deep); border-color: var(--portal-accent-deep); }
.portal-btn--accent:active { background: #1E40AF; transform: scale(0.98); }

/* Ghost — secondary, outlined. Use for "Back", "Cancel", "See all", etc. */
.portal-btn--ghost {
    background: var(--portal-surface);
    color: var(--portal-text);
    border: 1px solid var(--portal-border);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}
.portal-btn--ghost:hover { background: var(--portal-surface-2); border-color: var(--portal-border-hard); }
.portal-btn--ghost:active { background: #E4E4E7; }

/* Danger — destructive */
.portal-btn--danger {
    background: var(--portal-danger);
    color: #FFF;
    border-color: var(--portal-danger);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.15) inset,
        0 2px 4px rgba(220, 38, 38, 0.24);
}
.portal-btn--danger:hover { background: #B91C1C; border-color: #B91C1C; }
.portal-btn--danger:active { background: #991B1B; transform: scale(0.98); }

/* Link — inline text action */
.portal-btn--link {
    background: transparent;
    color: var(--portal-accent);
    min-height: auto;
    height: auto;
    padding: 4px 6px;
    border: none;
    font-weight: 500;
    box-shadow: none;
}
.portal-btn--link:hover { color: var(--portal-accent-deep); text-decoration: underline; }

/* Disabled shared */
.portal-btn[disabled],
.portal-btn.is-disabled {
    background: var(--portal-surface-2) !important;
    color: var(--portal-text-muted) !important;
    border-color: var(--portal-border) !important;
    cursor: not-allowed;
    box-shadow: none;
    transform: none !important;
}
.portal-btn[disabled]:active,
.portal-btn.is-disabled:active { transform: none !important; }

/* Icon sizing inside buttons */
.portal-btn i { font-size: 0.9em; line-height: 1; }
.portal-btn--sm i { font-size: 0.85em; }
.portal-btn--lg i { font-size: 1em; }

/* ------------------------------------------------------------
   Auto-theme Atlas CardPart so existing pages don't need rewrites
   ------------------------------------------------------------ */
.portal-root section.flex.flex-col.bg-card-bg {
    background: var(--portal-surface) !important;
    border: 1px solid var(--portal-border) !important;
    border-radius: var(--portal-radius-lg) !important;
    box-shadow: var(--portal-shadow-sm) !important;
    color: var(--portal-text);
    margin: 0 20px 12px;
    overflow: hidden;
}
.portal-root section.flex.flex-col.bg-card-bg > .flex-1 {
    padding: 18px !important;
    color: inherit !important;
}
/* Card headers (h3 "Membership", "Household", etc.) */
.portal-root section.flex.flex-col.bg-card-bg h1,
.portal-root section.flex.flex-col.bg-card-bg h2,
.portal-root section.flex.flex-col.bg-card-bg h3,
.portal-root section.flex.flex-col.bg-card-bg h4 {
    font-family: var(--portal-font);
    font-weight: 600;
    font-size: 15px;
    letter-spacing: -0.005em;
    color: var(--portal-text);
    margin: 0 0 14px;
}
/* If a Card has a header area, tighten and de-color it */
.portal-root section.flex.flex-col.bg-card-bg > .flex-1 > div:first-child {
    background: transparent !important;
    border: none !important;
}
/* De-emphasise Atlas card inner label/value pairs so they feel portal-like */
.portal-root section.flex.flex-col.bg-card-bg [class*="text-card-label"],
.portal-root section.flex.flex-col.bg-card-bg [class*="card-label"] {
    font-size: 11px !important;
    font-weight: 500 !important;
    color: var(--portal-text-muted) !important;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
.portal-root section.flex.flex-col.bg-card-bg [class*="text-card-value"],
.portal-root section.flex.flex-col.bg-card-bg [class*="card-value"] {
    font-size: 14px !important;
    font-weight: 500 !important;
    color: var(--portal-text) !important;
}
/* Page-level h1 "My Profile" / "My Rallies" etc. */
.portal-root > [data-part-id="pageHeader"],
.portal-root div > [data-part-id="pageHeader"] {
    padding: 20px 20px 4px !important;
    display: block;
    font-size: 24px !important;
    font-weight: 600 !important;
    letter-spacing: -0.02em;
    color: var(--portal-text) !important;
}
/* ------------------------------------------------------------
   Re-theme Atlas AtButton inside the portal so page-JSON Button
   parts (which emit Tailwind classes like bg-primary, bg-success)
   pick up the modern portal button system automatically.
   ------------------------------------------------------------ */
.portal-root button,
.portal-root a[class*="bg-primary"],
.portal-root a[class*="bg-success"],
.portal-root a[class*="bg-danger"],
.portal-root a[class*="bg-secondary"] {
    /* Shared: tighten size + modern font rendering */
    font-family: var(--portal-font) !important;
    font-weight: 500 !important;
    letter-spacing: -0.005em !important;
    border-radius: 10px !important;
    min-height: 44px !important;
    padding: 0 18px !important;
    gap: 8px !important;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.08s !important;
}
/* Primary solid (bg-primary = blue by default) → dark neutral */
.portal-root button[class*="bg-primary"]:not([class*="bg-transparent"]),
.portal-root a[class*="bg-primary"]:not([class*="bg-transparent"]) {
    background: var(--portal-text) !important;
    color: #FFFFFF !important;
    border-color: var(--portal-text) !important;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.12) inset,
        0 1px 2px rgba(0, 0, 0, 0.12),
        0 1px 3px rgba(0, 0, 0, 0.05) !important;
}
.portal-root button[class*="bg-primary"]:not([class*="bg-transparent"]):hover {
    background: #27272A !important;
    border-color: #27272A !important;
}
.portal-root button[class*="bg-primary"]:not([class*="bg-transparent"]):active {
    background: #09090B !important;
    transform: scale(0.98) !important;
}

/* Success solid (bg-success = green) → blue accent for "positive action" */
.portal-root button[class*="bg-success"]:not([class*="bg-transparent"]),
.portal-root a[class*="bg-success"]:not([class*="bg-transparent"]) {
    background: var(--portal-accent) !important;
    color: #FFFFFF !important;
    border-color: var(--portal-accent) !important;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.18) inset,
        0 2px 4px rgba(37, 99, 235, 0.24) !important;
}
.portal-root button[class*="bg-success"]:not([class*="bg-transparent"]):hover {
    background: var(--portal-accent-deep) !important;
    border-color: var(--portal-accent-deep) !important;
}

/* Secondary / outline → ghost card */
.portal-root button[class*="bg-transparent"],
.portal-root button.btn-secondary,
.portal-root a[class*="bg-transparent"] {
    background: var(--portal-surface) !important;
    color: var(--portal-text) !important;
    border: 1px solid var(--portal-border) !important;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03) !important;
}
.portal-root button[class*="bg-transparent"]:hover {
    background: var(--portal-surface-2) !important;
    border-color: var(--portal-border-hard) !important;
    color: var(--portal-text) !important;
}

/* Danger → red destructive */
.portal-root button[class*="bg-danger"]:not([class*="bg-transparent"]),
.portal-root a[class*="bg-danger"]:not([class*="bg-transparent"]) {
    background: var(--portal-danger) !important;
    color: #FFFFFF !important;
    border-color: var(--portal-danger) !important;
}

/* Icon sizing inside rethemed Atlas buttons */
.portal-root button i,
.portal-root a[class*="bg-primary"] i,
.portal-root a[class*="bg-success"] i {
    font-size: 0.9em !important;
    line-height: 1 !important;
}

/* Banking-details card — shared component (lives here because inline page
   <style> blocks truncate around 36 rules; putting banking styles in a
   real stylesheet guarantees they render). */
.portal-root .banking-card-wrap {
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
}
.portal-root .banking-card-wrap > section.flex.flex-col.bg-card-bg,
.portal-root .banking-card-wrap > section > .flex-1 {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
}
.portal-root .banking-card {
    margin: 0 20px 12px;
    background: var(--portal-surface);
    border: 1px solid var(--portal-border);
    border-radius: 14px;
    overflow: hidden;
    box-shadow:
        0 1px 2px rgba(0, 0, 0, 0.04),
        0 4px 12px rgba(0, 0, 0, 0.04);
}
.portal-root .banking-header {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    background: linear-gradient(135deg, #F8FAFC 0%, #EFF6FF 100%);
    border-bottom: 1px solid var(--portal-border);
}
.portal-root .banking-header > i {
    width: 40px; height: 40px;
    flex-shrink: 0;
    border-radius: 10px;
    background: var(--portal-accent);
    color: #FFF;
    display: grid;
    place-items: center;
    font-size: 16px;
    box-shadow:
        0 2px 6px rgba(37, 99, 235, 0.28),
        0 1px 2px rgba(37, 99, 235, 0.16);
}
.portal-root .banking-title {
    font-weight: 600;
    font-size: 15px;
    color: var(--portal-text);
    line-height: 1.25;
}
.portal-root .banking-sub {
    font-size: 13px;
    color: var(--portal-text-soft);
    margin-top: 2px;
}
.portal-root .banking-rows { padding: 6px 0; }
.portal-root .banking-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 18px;
    border-bottom: 1px solid var(--portal-surface-2);
}
.portal-root .banking-row:last-child { border-bottom: none; }
.portal-root .banking-label {
    flex-shrink: 0;
    width: 110px;
    font-size: 12px;
    font-weight: 500;
    color: var(--portal-text-muted);
    letter-spacing: 0.01em;
}
.portal-root .banking-value {
    flex: 1;
    min-width: 0;
    font-family: "SF Mono", Menlo, Consolas, monospace;
    font-size: 14px;
    font-weight: 500;
    color: var(--portal-text);
    letter-spacing: 0.02em;
    word-break: break-all;
    user-select: all;
}
.portal-root .banking-row--reference { background: #FFFBEB; border-bottom-color: #FDE68A; }
.portal-root .banking-row--reference .banking-value { color: #92400E; font-weight: 600; }
.portal-root .banking-row--reference .banking-label { color: #92400E; font-weight: 600; }
.portal-root .banking-copy {
    flex-shrink: 0;
    width: 36px; height: 36px;
    border: 1px solid var(--portal-border) !important;
    background: var(--portal-surface) !important;
    border-radius: 8px !important;
    color: var(--portal-text-soft);
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.08s;
    position: relative;
    padding: 0 !important;
    min-height: 36px !important;
    height: 36px !important;
}
.portal-root .banking-copy:hover {
    background: var(--portal-surface-2) !important;
    border-color: var(--portal-border-hard) !important;
    color: var(--portal-text);
}
.portal-root .banking-copy:active { transform: scale(0.94); }
.portal-root .banking-copy i { font-size: 13px; position: absolute; inset: 0; display: grid; place-items: center; transition: opacity 0.15s, transform 0.15s; }
.portal-root .banking-copy .banking-copy-ok { opacity: 0; transform: scale(0.7); color: var(--portal-success); }
.portal-root .banking-copy.is-copied { border-color: var(--portal-success) !important; background: var(--portal-success-soft) !important; }
.portal-root .banking-copy.is-copied .banking-copy-ico { opacity: 0; transform: scale(0.7); }
.portal-root .banking-copy.is-copied .banking-copy-ok { opacity: 1; transform: scale(1); }
.portal-root .banking-note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 14px 18px;
    background: var(--portal-surface-2);
    border-top: 1px solid var(--portal-border);
    font-size: 13px;
    line-height: 1.5;
    color: var(--portal-text-soft);
}
.portal-root .banking-note i {
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--portal-accent);
}

/* Segmented tab control — usage: <Menu cssClass="portal-tab-segmented">
   Atlas's Menu part renders as <div class="flex flex-wrap ..."> + three
   independent button children. Force a tight horizontal 3-up pill. */
.portal-root .portal-tab-segmented {
    margin: 8px 20px 14px !important;
    padding: 4px !important;
    background: var(--portal-surface-2) !important;
    border: 1px solid var(--portal-border) !important;
    border-radius: 12px !important;
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    gap: 4px !important;
    overflow: hidden !important;
}
.portal-root .portal-tab-segmented > * {
    flex: 1 1 0 !important;
    min-width: 0 !important;
}
.portal-root .portal-tab-segmented button {
    flex: 1 1 0 !important;
    width: auto !important;
    min-width: 0 !important;
    min-height: 36px !important;
    height: 36px !important;
    padding: 6px 8px !important;
    border-radius: 8px !important;
    background: transparent !important;
    color: var(--portal-text-soft) !important;
    border: none !important;
    box-shadow: none !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    justify-content: center !important;
    gap: 6px !important;
}
.portal-root .portal-tab-segmented button.btn-primary,
.portal-root .portal-tab-segmented button[class*="bg-primary"],
.portal-root .portal-tab-segmented button.active {
    background: var(--portal-surface) !important;
    color: var(--portal-text) !important;
    box-shadow: 0 1px 2px rgba(0,0,0,0.06) !important;
}

/* Standalone Button parts in a column — align with the cards above them.
   Atlas ButtonPart wraps its button in <div class="{CssClass}">. When a
   button sits outside an invoice/tab context (e.g. "Edit Vehicle",
   "Grant marketing consent" on Profile), it hangs flush left with 0
   margin — looks misaligned next to 20px-margin cards. Force alignment. */
.portal-root .grid.grid-cols-12 > [class*="col-span-"] > div:has(> button),
.portal-root .grid.grid-cols-12 > [class*="col-span-"] > div:not(.invoice-card-actions):not([class*="banking-"]):not([class*="account-status"]):not([class*="tokens-mini"]):not([class*="portal-"]):has(> button) {
    margin: 0 20px 10px !important;
}
/* Each standalone button stretches to fill the card-aligned container */
.portal-root .grid.grid-cols-12 > [class*="col-span-"] > div:has(> button) > button {
    width: 100% !important;
    min-height: 44px;
    justify-content: flex-start !important;
    padding-left: 16px !important;
    padding-right: 16px !important;
}
/* Alert parts */
.portal-root [role="alert"] {
    border-radius: var(--portal-radius-md) !important;
    margin: 0 20px 12px !important;
    font-size: 14px !important;
}

/* ------------------------------------------------------------
   Cards / surfaces (explicit portal-card helper class)
   ------------------------------------------------------------ */
.portal-card {
    background: var(--portal-surface);
    border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius-lg);
    padding: 20px;
    box-shadow: var(--portal-shadow-sm);
}
.portal-card--flush { padding: 0; overflow: hidden; }
.portal-card--dark  { background: var(--portal-text); color: var(--portal-surface); border-color: var(--portal-text); }
.portal-card--accent {
    background: var(--portal-accent);
    color: #FFF;
    border-color: var(--portal-accent);
}
.portal-card--subtle { background: var(--portal-surface-2); border-color: var(--portal-border); box-shadow: none; }
.portal-card--interactive { cursor: pointer; transition: border-color 0.15s, transform 0.1s var(--portal-ease-out); }
.portal-card--interactive:active { transform: scale(0.995); border-color: var(--portal-border-hard); }

/* ------------------------------------------------------------
   Chips / pills
   ------------------------------------------------------------ */
.portal-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    background: var(--portal-surface-2);
    color: var(--portal-text-soft);
    border: 1px solid var(--portal-border);
    line-height: 1;
}
.portal-chip--success { background: var(--portal-success-soft); color: var(--portal-success); border-color: transparent; }
.portal-chip--warning { background: var(--portal-warning-soft); color: #854D0E; border-color: transparent; }
.portal-chip--danger  { background: var(--portal-danger-soft);  color: var(--portal-danger);  border-color: transparent; }
.portal-chip--accent  { background: var(--portal-accent-soft);  color: var(--portal-accent-deep); border-color: transparent; }
.portal-chip--live { position: relative; padding-left: 18px; }
.portal-chip--live::before {
    content: '';
    position: absolute;
    left: 8px; top: 50%;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
    transform: translateY(-50%);
    box-shadow: 0 0 0 0 currentColor;
    animation: portalPulse 2s ease-in-out infinite;
}
@keyframes portalPulse {
    0%, 100% { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
    50% { box-shadow: 0 0 0 4px currentColor; opacity: 0.25; }
}

/* ------------------------------------------------------------
   Forms
   ------------------------------------------------------------ */
.portal-field { margin-bottom: 16px; }
.portal-field-label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--portal-text);
    margin-bottom: 6px;
}
.portal-input,
.portal-textarea,
.portal-select {
    width: 100%;
    padding: 12px 14px;
    min-height: 48px;
    background: var(--portal-surface);
    border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius-md);
    font-family: var(--portal-font);
    font-size: 15px;
    color: var(--portal-text);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
    -webkit-appearance: none;
    appearance: none;
}
.portal-textarea { resize: none; line-height: 1.5; min-height: 96px; }
.portal-input:focus,
.portal-textarea:focus,
.portal-select:focus {
    border-color: var(--portal-accent);
    box-shadow: 0 0 0 3px var(--portal-accent-faint);
}
.portal-input::placeholder,
.portal-textarea::placeholder { color: var(--portal-text-muted); }

/* Selectable option (radio/checkbox replacement) */
.portal-option {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    background: var(--portal-surface);
    border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius-md);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, transform 0.08s;
    margin-bottom: 8px;
}
.portal-option:active { transform: scale(0.995); }
.portal-option.is-selected {
    border-color: var(--portal-text);
    background: var(--portal-surface);
    box-shadow: 0 0 0 1px var(--portal-text);
}
.portal-option-check {
    width: 22px; height: 22px;
    border: 1.5px solid var(--portal-border-hard);
    border-radius: 50%;
    display: grid; place-items: center;
    flex-shrink: 0;
    transition: background 0.15s, border-color 0.15s;
}
.portal-option.is-selected .portal-option-check {
    background: var(--portal-text);
    border-color: var(--portal-text);
}
.portal-option-check::after {
    content: '';
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #FFF;
    opacity: 0;
    transform: scale(0.3);
    transition: opacity 0.15s var(--portal-ease-spring), transform 0.15s var(--portal-ease-spring);
}
.portal-option.is-selected .portal-option-check::after { opacity: 1; transform: scale(1); }
.portal-option-body { flex: 1; min-width: 0; }
.portal-option-title { font-weight: 500; font-size: 15px; color: var(--portal-text); margin-bottom: 2px; }
.portal-option-sub { font-size: 13px; color: var(--portal-text-soft); }
.portal-option-price { font-weight: 600; font-size: 15px; color: var(--portal-text); }

/* ------------------------------------------------------------
   Bottom Tab Bar
   ------------------------------------------------------------ */
.portal-tabbar {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: calc(var(--portal-tabbar-height) + var(--portal-safe-bottom));
    padding-bottom: var(--portal-safe-bottom);
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(16px) saturate(1.4);
    -webkit-backdrop-filter: blur(16px) saturate(1.4);
    border-top: 1px solid var(--portal-border);
    display: flex;
    z-index: 1000;
}
.portal-tabbar-tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 8px 6px;
    font-family: var(--portal-font);
    font-size: 10.5px;
    font-weight: 500;
    color: var(--portal-text-muted);
    text-decoration: none;
    position: relative;
    transition: color 0.15s;
    min-height: 56px;
}
.portal-tabbar-tab.is-active { color: var(--portal-text); }
.portal-tabbar-icon-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.portal-tabbar-icon-wrap i { font-size: 20px; line-height: 1; }
.portal-tabbar-tab:active .portal-tabbar-icon-wrap i { transform: scale(0.92); transition: transform 0.1s; }
.portal-tabbar-badge {
    position: absolute;
    top: -5px; right: -9px;
    min-width: 16px; height: 16px;
    padding: 0 4px;
    background: var(--portal-accent);
    color: #FFF;
    border-radius: 8px;
    font-size: 10px;
    font-weight: 600;
    display: grid;
    place-items: center;
    border: 2px solid var(--portal-bg);
    line-height: 1;
}
.portal-tabbar-label { line-height: 1; font-weight: 500; }

/* ------------------------------------------------------------
   Stepper
   ------------------------------------------------------------ */
.portal-stepper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 6px 0 10px;
}
.portal-stepper-dots {
    display: flex;
    align-items: center;
    gap: 6px;
}
.portal-stepper-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--portal-border-hard);
    transition: background 0.3s var(--portal-ease-out), width 0.3s var(--portal-ease-out), border-radius 0.3s var(--portal-ease-out);
}
.portal-stepper-dot.is-done   { background: var(--portal-text); }
.portal-stepper-dot.is-active {
    background: var(--portal-text);
    width: 22px;
    border-radius: 3px;
}
.portal-stepper-label {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--portal-text-muted);
}

/* ------------------------------------------------------------
   Sticky bottom CTA block
   ------------------------------------------------------------ */
.portal-sticky-cta {
    position: sticky;
    bottom: calc(var(--portal-tabbar-height) + var(--portal-safe-bottom));
    margin-top: 20px;
    padding: 12px 16px 16px;
    background: linear-gradient(180deg, rgba(250, 250, 250, 0) 0%, var(--portal-bg) 30%);
    z-index: 10;
}

/* ------------------------------------------------------------
   Force all multi-col rows to stack on mobile — admin pages use
   6/12/4-col layouts that don't fit a 393px viewport. Single-col
   layout is a sensible default for every portal page.
   ------------------------------------------------------------ */
.portal-root .grid.grid-cols-12 {
    display: flex !important;
    flex-direction: column !important;
}
.portal-root .grid.grid-cols-12 > [class*="col-span-"] {
    grid-column: unset !important;
    width: 100% !important;
    min-width: 0 !important;
}
/* Pages like notifications render Label + many Checkboxes inside a single
   column that Atlas defaults to flex-row — stack vertically on mobile.
   Exception: when the JSON row explicitly sets cssClass="flex-row", respect
   the intentional horizontal layout (e.g. segmented Upcoming/Past toggle). */
.portal-root .grid.grid-cols-12 > [class*="col-span-"]:not(.flex-row) {
    flex-direction: column !important;
}
/* Label parts render as inline <span>; force them to block inside col-span so
   multi-label rows (page title + subtitle, section header + content) stack. */
.portal-root .grid.grid-cols-12 > [class*="col-span-"] > span,
.portal-root .grid.grid-cols-12 > [class*="col-span-"] > span.inline-flex {
    display: block !important;
    margin-bottom: 0;
}

/* ------------------------------------------------------------
   Initial-paint smoothness

   Atlas PageRouter renders a cream "Loading..." spinner while it
   resolves the URL asynchronously, then the portal-root mounts and
   flashes over it. Make the loading state visually match the portal
   (neutral background, no jarring pop).
   ------------------------------------------------------------ */
body > .flex.flex-col.min-h-screen > .flex.flex-1 > main > article > div.p-6.flex {
    background: var(--portal-bg);
    min-height: 70vh;
}
body > .flex.flex-col.min-h-screen > .flex.flex-1 > main > article > div.p-6.flex p {
    color: var(--portal-text-muted);
    font-family: var(--portal-font);
    font-weight: 500;
}

/* Gentle fade-in so portal content doesn't pop abruptly after SSR → interactive */
.portal-root {
    animation: portalFadeIn 0.15s ease-out;
}
@keyframes portalFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ------------------------------------------------------------
   Navigation splash override (portal-only)

   MainLayout.razor renders <div class="at-page-splash"><div
   class="at-page-splash-spinner"> between page navigations. The
   default admin styling is a translucent white wash with the
   --at-primary spinner — reads as a blunt flash against the
   portal's softer palette. Retint to the portal tokens so the
   splash feels like the same surface, not an admin intrusion.
   Scoped under body:has(.portal-root) — admin pages unaffected.
   ------------------------------------------------------------ */
body:has(.portal-root) .at-page-splash {
    background: var(--portal-bg) !important;
    animation: at-splash-fadein 0.12s var(--portal-ease-out) !important;
}
body:has(.portal-root) .at-page-splash-spinner {
    border-color: rgba(37, 99, 235, 0.15) !important;
    border-top-color: var(--portal-accent) !important;
}

/* ------------------------------------------------------------
   Motion respect
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
