/* =================================================================
   CASTLE CAPITAL — CHART THEME CSS
   The DOM half of the plot layer. The canvas half lives in
   static/js/castle-chart-theme.js (tokens, axes, datasets) and
   static/js/castle-chart-glass.js (HUD, crosshair, area, draw-in).
   Version: 20260726002

   -----------------------------------------------------------------
   This file is injected by castle-chart-glass.js rather than linked
   from a template: base.html, performance.html, admin_base.html and
   portfolio_demo.html all load the readout layer and none of them is
   in this pass's ownership lane. It therefore lands in <head> at the
   position of that script — BEFORE style.css, mobile-charts.css and
   castle-glass.css. Anything here that has to beat those files says so
   with specificity, not with source order.

   Register: a plot is an instrument panel, not a card. Hairline rules
   instead of borders and gaps, near-square corners, figures in the
   tabular column, and gold reserved for the one series that matters.
   ================================================================= */

:root {
  /* Local aliases so this file works on a page that has not loaded
     theme-unification.css (portfolio_demo.html is one). Same values as
     the brief's token block — do not fork them. */
  --cc-chart-rule:        var(--cc-rule, rgba(255, 255, 255, 0.09));
  --cc-chart-rule-strong: var(--cc-rule-strong, rgba(255, 255, 255, 0.16));
  --cc-chart-label:       var(--cc-label-color, rgba(255, 255, 255, 0.58));
  --cc-chart-radius:      var(--cc-radius-card, 4px);
  --cc-chart-gold:        var(--castle-gold, #C9A74E);
  --cc-chart-bg:          var(--cc-register-bg, rgba(255, 255, 255, 0.022));
}

/* -----------------------------------------------------------------
   1. CANVAS + CONTAINER SIZING
   ----------------------------------------------------------------- */

/* Chart.js sizes the backing store itself; the CSS box has to follow the
   container or every plot renders at its intrinsic 300px. `data-cc-raw`
   opts a canvas out — a WebGL/ambient canvas is not a plot and must keep
   whatever geometry its own script gave it. */
canvas {
    width: 100% !important;
    display: block;
    background: transparent !important;
}

canvas[data-cc-raw] {
    width: auto !important;
}

/* A canvas Chart.js has NOT taken over — a plot whose fetch failed, or
   one that has not been constructed yet — carries only its intrinsic
   300x150 attribute ratio. Stretched to the container width by the rule
   above, that becomes a several-hundred-pixel void: measured on
   /portfolio, whose positions API currently 500s, the untouched
   `performance-sparkline` canvas laid out at 1108x554 inside a 320px
   panel and pushed the whole page down.

   Chart.js writes an inline `height` on every canvas it manages, so the
   attribute selector is an exact test for "nobody owns this yet" — a
   real plot is never matched, and the cap lifts the moment the chart is
   built. When the parent has no definite height, `100%` resolves to
   `auto` and nothing changes. */
canvas:not([data-cc-raw]):not([style*="height"]) {
    max-height: 100%;
}

.chart-container,
.performance-chart,
.dashboard-chart-wrapper {
    position: relative;
    width: 100% !important;
    min-height: 280px;
    box-sizing: border-box;
}

/* No grey plates behind a plot. Depth comes from the navy ramp. */
.chart-container,
.performance-chart,
.chart-card,
.chart-body {
    background: transparent !important;
}

/* The panel a plot sits in: a register, not a rounded card. */
.chart-body {
    background: var(--cc-chart-bg) !important;
    padding: 1.25rem;
    border-radius: 0 0 var(--cc-chart-radius) var(--cc-chart-radius);
    border-top: 1px solid var(--cc-chart-rule);
}

/* -----------------------------------------------------------------
   2. RESPONSIVE CHART HEIGHTS
   ----------------------------------------------------------------- */

@media (min-width: 1280px) {
    .chart-container,
    .performance-chart,
    .dashboard-chart-wrapper {
        min-height: 400px;
    }
}

@media (min-width: 768px) and (max-width: 1279px) {
    .chart-container,
    .performance-chart,
    .dashboard-chart-wrapper {
        min-height: 320px;
    }
}

@media (min-width: 480px) and (max-width: 767px) {
    .chart-container,
    .performance-chart,
    .dashboard-chart-wrapper {
        min-height: 280px;
    }

    .chart-body {
        padding: 1rem;
    }
}

@media (max-width: 479px) {
    .chart-container,
    .performance-chart,
    .dashboard-chart-wrapper {
        min-height: 260px;
    }

    .chart-body {
        padding: 0.75rem;
    }
}

.dashboard-chart-wrapper {
    position: relative;
    width: 100%;
    height: 320px;
}

@media (min-width: 1280px) {
    .dashboard-chart-wrapper {
        height: 400px;
    }
}

@media (max-width: 480px) {
    .dashboard-chart-wrapper {
        height: 260px;
    }
}

/* -----------------------------------------------------------------
   3. THE PLOT FRAME — .cc-plot
   -----------------------------------------------------------------
   The container primitive for a new chart: a hairline-ruled register
   with a header line (title left, controls right) and the plot below
   it. No radius on the body, no shadow, no gap between the header and
   the plot — the rule IS the separation.

       <section class="cc-plot">
         <header class="cc-plot__head">
           <h2 class="cc-plot__title">Portfolio value</h2>
           <div class="cc-plot__tools">…toggles…</div>
         </header>
         <div class="cc-plot__body"><canvas id="…"></canvas></div>
       </section>
   ----------------------------------------------------------------- */

.cc-plot {
    background: var(--cc-chart-bg);
    border: 1px solid var(--cc-chart-rule);
    border-radius: var(--cc-chart-radius);
    overflow: hidden;
}

.cc-plot__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--cc-chart-rule);
    min-height: 48px;
}

.cc-plot__title {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.3;
    color: #fff;
    letter-spacing: 0;
}

/* A one-line caption for the plot: what is measured, over what window.
   Sits with the title, not above it — no stacked eyebrow. */
.cc-plot__meta {
    font-size: var(--cc-label-size, 0.6875rem);
    font-weight: 500;
    color: var(--cc-chart-label);
    letter-spacing: var(--cc-label-tracking, 0.04em);
}

.cc-plot__tools {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.cc-plot__body {
    position: relative;
    padding: 0.75rem 0.5rem 0.5rem;
}

/* A second panel stacked under the first (drawdown beneath value):
   one rule between them, no gap, no second border. */
.cc-plot__body + .cc-plot__head {
    border-top: 1px solid var(--cc-chart-rule);
}

/* -----------------------------------------------------------------
   4. LOADING STATE
   -----------------------------------------------------------------
   Left-aligned and quiet. The old version centred a 40px gold ring
   that span forever with no reduced-motion guard — a spinner is the
   loudest thing on a page that is, by definition, showing nothing.
   ----------------------------------------------------------------- */

.chart-loading {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.625rem;
    min-height: 280px;
    padding: 0 0.25rem;
    font-size: 0.8125rem;
    color: rgba(255, 255, 255, 0.62);
}

.chart-loading::after {
    content: '';
    width: 14px;
    height: 14px;
    border: 2px solid var(--cc-chart-rule-strong);
    border-top-color: var(--cc-chart-gold);
    border-radius: 50%;
    animation: chart-spin 0.9s linear infinite;
}

@keyframes chart-spin {
    to { transform: rotate(360deg); }
}

/* -----------------------------------------------------------------
   5. EMPTY AND ERROR STATES
   -----------------------------------------------------------------
   An institutional empty state is left-aligned, says what is missing
   and what to do about it, and leaves the surrounding structure
   standing. Centred italic grey with a giant icon is the consumer
   tell; the icon is now a 16px hairline mark, not a 40px ornament.

       <div class="chart-empty">
         <p class="chart-empty__title">No portfolio history yet</p>
         <p class="chart-empty__hint">Values appear after the first
            daily snapshot, at 4:00 PM ET.</p>
       </div>
   ----------------------------------------------------------------- */

.chart-empty {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.375rem;
    min-height: 280px;
    padding: 0 0.25rem;
    text-align: left;
    color: rgba(255, 255, 255, 0.62);
}

.chart-empty i {
    font-size: 1rem;
    color: rgba(255, 255, 255, 0.34);
    margin-bottom: 0.25rem;
}

.chart-empty p {
    font-size: 0.8125rem;
    max-width: 46ch;
    margin: 0;
}

.chart-empty__title {
    font-size: 0.9375rem !important;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.88);
}

.chart-empty__hint {
    color: rgba(255, 255, 255, 0.62);
}

/* An error is an empty state that names the failure. Amber marks it as
   a state, not a loss — red is reserved for money going down. */
.chart-empty--error .chart-empty__title {
    color: #fff;
}

.chart-empty--error {
    border-left: none;                       /* never a side stripe */
    padding-left: 0.25rem;
}

.chart-empty--error i {
    color: var(--castle-warning, #F59E0B);
}

/* -----------------------------------------------------------------
   6. CHART CONTROLS
   -----------------------------------------------------------------
   Period toggles and series switches. R4: the active state is a gold
   hairline marker, never a filled gold pill — a 700px gold gradient
   slab on a toggle group was the single loudest use of the accent in
   the app.
   ----------------------------------------------------------------- */

.chart-controls-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    align-items: center;
}

.chart-controls,
.chart-type-toggle {
    display: inline-flex;
    gap: 0;
    background: transparent;
    padding: 0;
    border: 1px solid var(--cc-chart-rule);
    border-radius: var(--cc-chart-radius);
    overflow: hidden;
}

/* Rule-divided segments, not floating chips. */
.chart-controls > * + *,
.chart-type-toggle > * + * {
    border-left: 1px solid var(--cc-chart-rule);
}

.chart-type-btn,
.chart-toggle-btn {
    font-family: 'Montserrat', sans-serif;
    font-size: 0.8125rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums lining-nums;
    padding: 0.4375rem 0.875rem;
    border: none;
    border-radius: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.68);
    cursor: pointer;
    position: relative;
    transition: color 0.15s ease-out, background-color 0.15s ease-out;
}

.chart-type-btn:hover,
.chart-toggle-btn:hover {
    background: rgba(255, 255, 255, 0.05);
    color: rgba(255, 255, 255, 0.95);
}

.chart-type-btn:focus-visible,
.chart-toggle-btn:focus-visible {
    outline: 2px solid var(--cc-chart-gold);
    outline-offset: -2px;
}

.chart-type-btn.active,
.chart-toggle-btn.active {
    background: rgba(201, 167, 78, 0.08);
    color: var(--cc-chart-gold);
    box-shadow: none;
}

/* The marker: a 2px gold underline on the active segment. */
.chart-type-btn.active::after,
.chart-toggle-btn.active::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--cc-chart-gold);
}

@media (max-width: 480px) {
    .chart-controls-row {
        flex-direction: column;
        align-items: stretch;
        gap: 0.5rem;
    }

    .chart-controls,
    .chart-type-toggle {
        width: 100%;
        justify-content: stretch;
        flex-wrap: nowrap;
    }

    .chart-type-btn,
    .chart-toggle-btn {
        padding: 0.5rem 0.5rem;
        font-size: 0.6875rem;
        flex: 1 1 0;
        min-width: 0;
        min-height: 40px;
    }
}

/* -----------------------------------------------------------------
   7. LEGEND
   -----------------------------------------------------------------
   Left-aligned under the plot, separated by a hairline. Direction and
   series identity are never carried by colour alone: a benchmark key
   also carries its dash pattern, and a gain/loss key carries its sign.
   ----------------------------------------------------------------- */

.chart-legend,
.cc-chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
    justify-content: flex-start;
    margin-top: 0.75rem;
    padding-top: 0.625rem;
    border-top: 1px solid var(--cc-chart-rule);
}

.chart-legend-item,
.cc-chart-legend__key {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.72);
    letter-spacing: 0;
}

.chart-legend-color,
.cc-chart-legend__swatch {
    width: 10px;
    height: 2px;
    border-radius: 0;
    flex: 0 0 auto;
    background: var(--cc-chart-gold);
}

/* A benchmark is drawn dashed on the plot; its key says so too, so the
   two series are still separable in greyscale. */
.cc-chart-legend__swatch--dashed {
    height: 0;
    border-top: 2px dashed currentColor;
    background: none;
    width: 12px;
}

.chart-legend-color.gold   { background: var(--cc-chart-gold); }
/* The benchmark blue is not in DESIGN.md's palette; it is the existing
   comparison-series colour (CastleCharts.BLUE in castle-chart-theme.js)
   and a legend key MUST match the line it labels, so it is quoted here
   rather than re-picked. Flagged upward for the palette, not forked. */
.chart-legend-color.blue   { background: var(--cc-chart-blue, #4FC3F7); }
.chart-legend-color.red    { background: var(--castle-loss, #EF4444); }
.chart-legend-color.green  { background: var(--castle-gain, #10B981); }

/* A note under a plot — sample window, data source, caveat. */
.cc-chart-note {
    margin-top: 0.5rem;
    font-size: var(--cc-label-size, 0.6875rem);
    color: var(--cc-chart-label);
    letter-spacing: var(--cc-label-tracking, 0.04em);
}

/* -----------------------------------------------------------------
   8. THE HUD READOUT
   -----------------------------------------------------------------
   Structure, material, radius and padding all live in castle-glass.css
   (the --hud role) and stay there — one owner per property, or the two
   files drift. What belongs HERE is only what is specific to reading a
   PLOT.
   ----------------------------------------------------------------- */

/* Dates, tickers and figures all sit on one advance so the panel does
   not change width as you scrub across the series. */
.cc-chart-hud .cc-chart-hud__title,
.cc-chart-hud .cc-chart-hud__value {
    font-variant-numeric: tabular-nums lining-nums;
}

/* -----------------------------------------------------------------
   9. ANNOTATION MARKERS
   ----------------------------------------------------------------- */

.chart-marker-peak,
.chart-marker-trough {
    position: absolute;
    font-size: 0.6875rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums lining-nums;
    padding: 0.1875rem 0.375rem;
    border-radius: var(--cc-radius-chip, 2px);
    white-space: nowrap;
}

.chart-marker-peak {
    background: rgba(201, 167, 78, 0.14);
    border: 1px solid rgba(201, 167, 78, 0.45);
    color: var(--cc-chart-gold);
}

.chart-marker-trough {
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.45);
    color: #fff;
}

/* -----------------------------------------------------------------
   10. PIE / DOUGHNUT
   ----------------------------------------------------------------- */

.pie-chart-container {
    position: relative;
    max-width: 300px;
    margin: 0;                                /* left-anchored, not centred */
}

@media (max-width: 480px) {
    .pie-chart-container {
        max-width: 240px;
    }
}

/* -----------------------------------------------------------------
   11. REDUCED MOTION
   -----------------------------------------------------------------
   A chart must still be COMPLETE and CORRECT with motion off — never
   blank, never half-drawn. The canvas-side guards are in
   castle-chart-theme.js (Chart.defaults.animation = false) and
   castle-chart-glass.js (the wipe resolves to 1 immediately); this is
   the DOM half.
   ----------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .chart-loading::after {
        animation: none;
        border-top-color: var(--cc-chart-gold);
        opacity: 0.9;
    }

    .chart-type-btn,
    .chart-toggle-btn {
        transition: none;
    }

    /* Belt and braces: if any page still applies the entrance clip to a
       canvas, motion-off must leave the FULL plot visible. */
    canvas {
        clip-path: none !important;
        -webkit-clip-path: none !important;
    }
}
