/* =============================================================================
   DEFAULT THEME
   =============================================================================

   The default theme's design-token values live in base.css :root — per CSS
   semantics :root IS the default theme, so this file needs no
   [data-theme] variable-override block.

   This file holds only the component-level rules that adapt Bootstrap to the
   Chippie look. Every colour is a var() reference to a base.css token; no hex
   literals live here.

   !important strategy: every [data-theme] .selector rule below
   carries an attribute selector plus a class, so it already out-ranks
   Bootstrap's single-class component rules by specificity alone — no flag
   needed. The only survivors are four navbar declarations, kept for parity
   with dark.css / rustic.css so the themed navbar colour reliably wins over
   Bootstrap's navbar styling and the base.css .navbar[data-nav-mode] rules.
*/

/* Self-hosted Trial fonts (editorial three-voice stack, all SIL OFL — permits
   self-hosting for web). Trial only: no brand font has been settled; this is
   a reversible swap, not a commitment. Three voices:
     Tinos (serif)           — headings; free metric-compatible Times.
     Source Serif 4 (serif)  — body/UI reading text; traditional transitional
                               serif designed to stay legible at small sizes.
     Fragment Mono (mono)    — data accents only (table column headers,
                               badges, code/.font-monospace); monospaced
                               Helvetica.
   Both the @font-face rules AND the token overrides live here rather than in
   base.css: base.css also loads on the public shell (public_base.html), and
   serif/mono tokens there would visibly change public pages via system
   fallbacks — the trial must stay app-only. skin.css loads on every
   app-shell theme (base.html includes it unconditionally, before the palette
   file) and after base.css, so this :root block wins the cascade over
   base.css's system-stack defaults while per-theme overrides (rustic's own
   type identity) still win over it. font-display: swap avoids invisible
   text (FOIT) while the woff2 loads. */
@font-face {
    font-family: 'Tinos';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/tinos/tinos-400.woff2') format('woff2');
}
@font-face {
    font-family: 'Tinos';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/static/fonts/tinos/tinos-700.woff2') format('woff2');
}
@font-face {
    font-family: 'Source Serif 4';
    font-style: normal;
    font-weight: 400 700; /* variable font — one file covers 400-700 */
    font-display: swap;
    src: url('/static/fonts/source-serif/source-serif-4-latin-var.woff2') format('woff2');
}
@font-face {
    font-family: 'Fragment Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/fragment-mono/fragment-mono-400.woff2') format('woff2');
}

:root {
    --font-family-base: 'Source Serif 4', Georgia, 'Times New Roman', serif;
    --font-family-heading: 'Tinos', 'Times New Roman', Times, Georgia, serif;
    --font-family-mono: 'Fragment Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    /* Route Bootstrap's monospace users (code, pre, kbd, .font-monospace)
       through the trial mono. */
    --bs-font-monospace: var(--font-family-mono);
}

/* Mono accents — the editorial "instrument data" voice, applied only where
   text is a label or datum rather than reading text: table column headers
   (already tracked caps) and badge pills (status/ID chips). Reading text,
   buttons, forms, and nav stay on the base font. */
.table thead th,
.badge {
    font-family: var(--font-family-mono);
}
/* The custom-status note inside the workflow badge is free-text prose
   (user-written sticky note), not a datum — keep it in the reading font. */
.badge .custom-status {
    font-family: var(--font-family-base);
}

/* Serif headings: Tinos has no Light cut (400/700 only), so headings sit at
   400 and slight tracking does the editorial work instead of weight. Scoped
   here (app shell only) so public headings keep Bootstrap's default. */
h1, h2, h3, .h1, .h2, .h3,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6 {
    font-weight: 400;
    letter-spacing: 0.02em;
}

/* Dashboard header — flat-blue edge-to-edge banner (Task .8).
   No gradient, no border-radius, no box-shadow, no side gutters: the
   banner is a full-bleed in-flow block (placed outside .container in
   base.html's page_header). Vertical padding only; the inner .container
   aligns the header content with the page body. */
[data-theme] .dashboard-header {
    background: var(--primary-color);
    color: white;
    min-height: var(--banner-height);
    padding: var(--banner-pad-y) 0;
    margin-bottom: var(--banner-margin-bottom);
    display: flex;
    flex-direction: column;
    /* Centre content vertically within the fixed-height band
       (--banner-height) so the buffer above the heading equals the buffer
       below the last element. On mobile the action button stacks under the
       text, so centring keeps that button's bottom buffer symmetric with
       the top buffer. Buttonless pages (invoices) centre their shorter
       content within the same band height. */
    justify-content: center;
}

/* The banner's inner .container must not inherit the bottom-nav
   clearance that mobile.css adds to every .container on mobile
   (padding-bottom: 80px). The banner is not at page-end, so that
   padding renders as dead blue space below the heading. Strip it —
   this selector's (0,3,0) specificity outranks the bare .container. */
[data-theme] .dashboard-header .container {
    padding-bottom: 0;
}

[data-theme] .dashboard-header h1,
[data-theme] .dashboard-header .display-5 {
    color: white;
    text-shadow: none;
}

[data-theme] .dashboard-header .lead {
    color: white;
    opacity: 0.75;
}

/* Banner action buttons (Create New Quote, Recurring Jobs, Add New Client).
   The flat-blue banner (Task .8) replaced the old gradient that once gave a
   plain .btn-primary enough tonal contrast against the header. On the flat
   banner a default .btn-primary renders the same blue as its background —
   the outline disappears. Lift the in-banner button to a lighter blue so
   its edge reads, and lighten further on hover for visible feedback. */
[data-theme] .dashboard-header .btn-primary {
    background-color: var(--banner-btn-bg);
    border-color: var(--banner-btn-border);
}
[data-theme] .dashboard-header .btn-primary:hover,
[data-theme] .dashboard-header .btn-primary:focus {
    background-color: var(--banner-btn-hover-bg);
    border-color: var(--banner-btn-hover-border);
}

/* Mobile banner tweaks. The vertical padding + margin now come from the
   --banner-* tokens (redefined per-breakpoint in base.css :root), so no
   .dashboard-header sizing override is needed here. */
@media (max-width: 576px) {
    /* The banner stacks as: heading/subtitle, then the action-button
       column. That column carries a 1rem `mt-3` gap — too much on a
       compact mobile banner. Tighten it. The selector targets the
       second (and any later) column in the banner's row. */
    [data-theme] .dashboard-header .row > [class*="col-"] + [class*="col-"] {
        margin-top: 0.4rem;
    }
}

html[data-hotwire-native] .mobile-bottom-nav,
html[data-hotwire-native] .mobile-bottom-spacer {
    display: none !important;
}

/* Hide the web Chip AI launcher button in the native shell. The native shell
   draws its own launcher (a MaterialCardView sibling of the bottom nav) so the
   button stays static during the tab-switch slide instead of riding the webview
   it would otherwise live in. The chat *panel* stays web: the native button
   clicks this hidden launcher via JS to open it (see MainActivity.openChat). */
html[data-hotwire-native] .pchat-launcher {
    display: none !important;
}

@media (max-width: 992px) {
    html[data-hotwire-native] .container,
    html[data-hotwire-native] .container-fluid {
        padding-bottom: 0 !important;
    }
}

/* Navigation - preserve original Bootstrap navbar-dark styling.
   The four !important flags below mirror dark.css / rustic.css: they keep the
   themed navbar colour winning over Bootstrap's navbar component styles and
   the theme-independent base.css .navbar[data-nav-mode] rules. */
[data-theme] .navbar {
    background: var(--nav-bg) !important;
    box-shadow: var(--nav-shadow);
}

[data-theme] .navbar .nav-link {
    color: rgba(255, 255, 255, 0.75) !important;
    text-shadow: none;
}

[data-theme] .navbar .nav-link:hover {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(255, 255, 255, 0.1) !important;
    transform: translateY(-1px);
}

[data-theme] .navbar .nav-link.active {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(255, 255, 255, 0.2) !important;
    font-weight: 600;
}

[data-theme] .navbar-brand {
    color: rgba(255, 255, 255, 1);
    text-shadow: none;
}

[data-theme] .navbar-brand:hover {
    color: rgba(255, 255, 255, 1);
    transform: scale(1.05);
}

/* Quick actions section — hairline border + soft shadow, same elevation
   language as .section-card so the page reads as one family of surfaces. */
[data-theme] .action-section {
    background-color: var(--card-bg);
    border-radius: var(--border-radius-lg);
    padding: 1.5rem;
    margin-bottom: 2rem;
    border: 1px solid var(--border-light);
    box-shadow: var(--shadow-sm);
}

/* Dashboard stats - preserve original styling */
[data-theme] .dashboard-stats {
    margin-bottom: 2rem;
}

/* Cards — Bootstrap's .card wears the same skin as .section-card below.

   Bootstrap 5.3 routes every visual property of .card / .card-header /
   .card-body / .card-footer through --bs-card-* custom properties, so the
   whole component retints from this one declaration block. Setting the
   properties (rather than restyling the parts) means Bootstrap keeps
   deriving what it derives — notably --bs-card-inner-border-radius, which
   keeps a flush .list-group or .card-img square with the outer corners.

   The one property Bootstrap declares but never applies is --bs-card-box-shadow,
   hence the literal box-shadow.

   Utilities still win: .bg-info and friends carry !important, so a
   `card-header bg-info text-white` keeps its tint over --bs-card-cap-bg.

   The edge uses --border-color / --shadow-base (the darker, heavier pair)
   rather than --border-light / --shadow-sm. Every theme defines both pairs,
   so the card stays theme-aware. .section-card below must use the same two
   or the primitives drift apart again. The header keeps --border-light for
   its rule: a separator inside the card should read lighter than its edge. */
[data-theme] .card {
    --bs-card-bg: var(--card-bg);
    --bs-card-border-color: var(--border-color);
    --bs-card-border-radius: var(--border-radius-lg);
    --bs-card-cap-bg: var(--surface-header);
    --bs-card-cap-color: var(--secondary-dark);
    --bs-card-cap-padding-y: 1rem;
    --bs-card-cap-padding-x: 1.5rem;
    --bs-card-spacer-y: 1.5rem;
    --bs-card-spacer-x: 1.5rem;
    box-shadow: var(--shadow-base);
}

[data-theme] .card > .card-header {
    font-weight: 600;
}

/* Section cards — defined border with a layered ambient shadow instead of
   the old borderless 15px blur blob; reads crisper on the sandstone canvas.

   Visually identical to .card above; it adds only the stack gap and the
   corner clipping. Both are the Chippie card, so the edge tokens must match. */
[data-theme] .section-card {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-lg);
    box-shadow: var(--shadow-base);
    margin-bottom: var(--section-card-gap, 2rem);
    overflow: var(--section-card-overflow, hidden); /* clip sticky table headers to the rounded corners */
}

/* The 2rem gap is vertical-stack rhythm. A card stretched to fill its grid
   row has no stack below it, and the gap would break the row's baseline. */
[data-theme] .section-card.h-100 {
    --section-card-gap: 0;
}

/* Opt out of clipping. A dropdown or popover anchored inside the card is
   positioned within it, so `overflow: hidden` silently truncates the open
   menu at the card edge. Cards holding an escaping menu declare this. */
[data-theme] .section-card-menu {
    --section-card-overflow: visible;
}

[data-theme] .section-header {
    background-color: var(--surface-header);
    border-bottom: 1px solid var(--border-light);
    padding: 1rem 1.5rem;
    font-weight: 600;
    color: var(--secondary-dark);
    border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
}

[data-theme] .section-body {
    padding: 1.5rem;
}

/* Stat cards — same hairline + soft shadow family as section cards; hover
   lifts gently with the layered base shadow rather than a blue glow. */
[data-theme] .stat-card,
[data-theme] .enhanced-stat-card {
    background-color: var(--card-bg);
    border: 1px solid var(--border-light);
    border-radius: var(--border-radius-lg);
    box-shadow: var(--shadow-sm);
    transition: all 0.3s ease;
    margin-bottom: 1rem;
}

[data-theme] .stat-card:hover,
[data-theme] .enhanced-stat-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-base);
}

[data-theme] .stat-card-link:hover {
    text-decoration: none;
    transform: translateY(-2px);
}

[data-theme] .stat-card-link:hover .stat-card {
    box-shadow: var(--shadow-base);
}

[data-theme] .stat-card-link:active {
    transform: translateY(0);
}

/* Tables — headers as uppercase micro-labels on the card surface (no grey
   band), hairline row separators, and a faint primary-tinted row hover. */
[data-theme] .table {
    color: var(--text-primary);
    background-color: var(--card-bg);
    --bs-table-hover-bg: rgba(var(--primary-rgb), 0.04);
    --bs-table-hover-color: var(--text-primary);
}

[data-theme] .table th {
    background-color: var(--surface);
    border-color: var(--border-light);
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

[data-theme] .table td {
    border-color: var(--border-light);
    color: var(--text-primary);
}

/* Forms - preserve original styling */
[data-theme] .form-control {
    background-color: var(--input-bg);
    border-color: var(--input-border);
    color: var(--input-text);
}

[data-theme] .form-control:focus {
    border-color: var(--input-focus);
    box-shadow: 0 0 0 0.25rem rgba(var(--primary-rgb), 0.25);
}

/* Buttons - preserve original styling */
[data-theme] .btn-primary {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--text-light);
}

[data-theme] .btn-primary:hover {
    background-color: var(--btn-primary-hover-bg);
    border-color: var(--btn-primary-hover-border);
}

/* Enhanced form containers — same surface family as .section-card */
[data-theme] .enhanced-form-container {
    background-color: var(--card-bg);
    border: 1px solid var(--border-light);
    border-radius: var(--border-radius-lg);
    box-shadow: var(--shadow-sm);
    margin-bottom: 2rem;
}

[data-theme] .form-header {
    background-color: var(--surface-header);
    border-bottom: 1px solid var(--border-light);
    padding: 1rem 1.5rem;
    border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
    font-weight: 600;
    color: var(--secondary-dark);
}

[data-theme] .form-body {
    padding: 1.5rem;
}

/* Mobile navigation - preserve original styling */
[data-theme] .mobile-bottom-nav {
    background: var(--nav-bg);
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

[data-theme] .mobile-nav-item {
    color: rgba(255, 255, 255, 0.75);
}

[data-theme] .mobile-nav-item:hover {
    color: rgba(255, 255, 255, 1);
}

[data-theme] .mobile-nav-item.active {
    background-color: rgba(255, 255, 255, 0.2);
    border-radius: 0.25rem;
    color: rgba(255, 255, 255, 1);
}

/* Mobile menu overlay */
[data-theme] .mobile-menu {
    background-color: var(--bg-primary);
    border: 1px solid var(--border-color);
    box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}

[data-theme] .mobile-menu-header {
    background-color: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
    color: var(--secondary-dark);
}

[data-theme] .mobile-menu-item {
    color: var(--secondary-dark);
    border-bottom: 1px solid var(--border-light);
}

[data-theme] .mobile-menu-item:hover {
    background-color: var(--bg-secondary);
    color: var(--primary-color);
}

/* Breadcrumbs - preserve original styling */
[data-theme] .breadcrumb {
    background-color: transparent;
}

[data-theme] .breadcrumb-item a {
    color: var(--text-secondary);
}

[data-theme] .breadcrumb-item a:hover {
    color: var(--primary-color);
}

[data-theme] .breadcrumb-item.active {
    color: var(--text-secondary);
}

/* Table scroll containers - preserve original styling */
[data-theme] .table-scroll-container {
    max-height: 400px;
    overflow-y: auto;
    overflow-x: auto;
}

/* Mobile view - increase table height */
@media (max-width: 767px) {
    [data-theme] .table-scroll-container {
        max-height: 600px;
    }
}

[data-theme] .table-header-sticky th {
    position: sticky;
    top: 0;
    /* Must stay opaque: these headers float over scrolling rows. var(--surface)
       matches the card so the band disappears visually but still masks rows. */
    background-color: var(--surface);
    z-index: 10;
    border-bottom: 1px solid var(--border-color);
}

/* Custom scrollbar styling - preserve original */
[data-theme] .table-scroll-container::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

[data-theme] .table-scroll-container::-webkit-scrollbar-track {
    background: var(--scrollbar-track);
    border-radius: 4px;
}

[data-theme] .table-scroll-container::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb);
    border-radius: 4px;
}

[data-theme] .table-scroll-container::-webkit-scrollbar-thumb:hover {
    background: var(--scrollbar-thumb-hover);
}

/* Status badges - preserve original styling */
[data-theme] .status-badge {
    transition: all 0.3s ease;
}

[data-theme] .badge:hover {
    transform: scale(1.05);
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

/* Alerts and notifications - preserve original styling */
[data-theme] .alert {
    border-radius: 0.5rem;
}

[data-theme] .alert-success {
    background-color: var(--alert-success-bg);
    border-color: var(--alert-success-border);
    color: var(--alert-success-text);
}

[data-theme] .alert-info {
    background-color: var(--alert-info-bg);
    border-color: var(--alert-info-border);
    color: var(--alert-info-text);
}

[data-theme] .alert-warning {
    background-color: var(--alert-warning-bg);
    border-color: var(--alert-warning-border);
    color: var(--alert-warning-text);
}

[data-theme] .alert-danger {
    background-color: var(--alert-danger-bg);
    border-color: var(--alert-danger-border);
    color: var(--alert-danger-text);
}

/* =============================================================================
   COMPONENT STATE THEMING
   =============================================================================

   Bootstrap scopes each component's state colours (hover/active/disabled/
   focus/show) to its own --bs-* custom properties, set on the component's
   base class. Overriding those properties here re-themes every state at
   once, since Bootstrap's state selectors already read var(--bs-btn-active-bg)
   etc. — no separate rule per pseudo-class needed.
*/

[data-theme] .btn-primary {
    --bs-btn-active-bg: var(--btn-primary-hover-bg);
    --bs-btn-active-border-color: var(--btn-primary-hover-border);
    --bs-btn-disabled-bg: var(--primary-color);
    --bs-btn-disabled-border-color: var(--primary-color);
}

[data-theme] .btn-outline-primary {
    --bs-btn-color: var(--primary-color);
    --bs-btn-border-color: var(--primary-color);
    --bs-btn-hover-color: var(--text-light);
    --bs-btn-hover-bg: var(--primary-color);
    --bs-btn-hover-border-color: var(--primary-color);
    --bs-btn-focus-shadow-rgb: var(--primary-rgb);
    --bs-btn-active-color: var(--text-light);
    --bs-btn-active-bg: var(--primary-color);
    --bs-btn-active-border-color: var(--primary-color);
    --bs-btn-disabled-color: var(--primary-color);
    --bs-btn-disabled-border-color: var(--primary-color);
}

/* form-check and form-range set their state colours as plain properties
   rather than component vars, so these override the property directly. */
[data-theme] .form-check-input:checked,
[data-theme] .form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
}

[data-theme] .form-range::-webkit-slider-thumb {
    background-color: var(--primary-color);
}
[data-theme] .form-range::-moz-range-thumb {
    background-color: var(--primary-color);
}

/* .text-bg-primary carries !important on the vendor rule itself, so the
   override needs it too — specificity alone can't beat !important. */
[data-theme] .text-bg-primary {
    background-color: var(--primary-color) !important;
}

[data-theme] .pagination {
    --bs-pagination-active-bg: var(--primary-color);
    --bs-pagination-active-border-color: var(--primary-color);
}

[data-theme] .progress {
    --bs-progress-bar-bg: var(--primary-color);
}

[data-theme] .dropdown-menu {
    --bs-dropdown-link-active-bg: var(--primary-color);
}

[data-theme] .list-group {
    --bs-list-group-active-bg: var(--primary-color);
    --bs-list-group-active-border-color: var(--primary-color);
}

[data-theme] .nav-pills {
    --bs-nav-pills-link-active-bg: var(--primary-color);
}
