/* Instrument-light theme.
 *
 * Scoped twice over, on purpose. The page-level rules only apply under
 * `body.theme-light`, which dashboard.html sets for sleep and eldercare
 * panels; every component class is prefixed `sl-`. Nothing here can reach the
 * motion, temperature, plug or camera panels, the admin console or the public
 * site, all of which still carry the older look.
 *
 * The tokens are declared on :root rather than on the body so the chart code
 * can read them with getComputedStyle -- Chart.js paints a canvas and cannot
 * resolve var(--data) itself.
 */

:root {
    --ground: #EEF1F4;
    --card: #FFFFFF;
    --ink: #18212C;
    --ink-2: #2E3A48;
    --muted: #5A6573;
    --date-sub: #444C56;     /* --muted 25% darker: the motion charts' date lines */
    --faint: #A6AEB8;
    --rule: #DFE4EA;
    --rule-strong: #C6CED7;
    --btn-rule: #A7ABB0;     /* --rule 25% darker: sleep/motion arrow and Details outlines */
    --axis: #B9C1CB;
    --grid: #EDF0F3;
    --data: #2E6C8C;
    --line: #2E6C8C;
    --highlight: #B8660F;
    --highlight-text: #8F4E0A;
    --ok: #2F8F5B;
    --danger: #B42318;
    --danger-bg: #FBEDEC;
    --nav: #16213A;
    --nav-border: #16213A;
    --nav-ink: #FFFFFF;
    --nav-muted: #B8C1D6;
    --nav-active: #24304D;
    --nav-button-border: #3A4766;
    --primary: #16213A;
    --primary-ink: #FFFFFF;
    --radius: 10px;
    /* The six-hour blocks on the motion panel, and the fill under the sleep
       line. Tokens because the dark theme moves all five. */
    --block-1: #3F4F86;
    --block-2: #3C8C7B;
    --block-3: #D0992F;
    --block-4: #B45F4C;
    --area-opacity: 0.08;
    /* The wash under the temperature trend. Its own token rather than the line
       colour at --area-opacity: that came out as a washed-out mauve on white
       (Paul, 2026-09-25). This is the cyan the chart carried before. */
    --temp-fill: rgba(0, 201, 255, 0.133);
    /* The dashed running averages. Deliberately NOT --axis: these are read, not
       merely sensed, so they have to be darker than the grid here and lighter
       than the plot in dark. A grid colour is the opposite of that in both. */
    --trend: #2E3A48;
    --hover: #F7F9FB;
    --hover-danger: #F7DEDC;
    /* The alerts-on pill: the only green background on the page. */
    --ok-bg: #E8F5EE;
    --ok-ink: #1E6F47;
    --shadow: 0 1px 2px rgba(22, 33, 58, 0.06);
    --theme-font: 'IBM Plex Sans', 'Helvetica Neue', sans-serif;
}

/* ---- dark ---------------------------------------------------------------
 * Values from the implementation notes, exactly. Only colours change: font,
 * size, spacing, radius and layout are shared, which is what makes the switch
 * a swap of variables rather than a second stylesheet.
 */
:root[data-theme="dark"] {
    --ground: #10162A;
    --card: #171F36;
    --ink: #E7EAF3;
    --ink-2: #CBD1E1;
    --muted: #98A1B9;
    --date-sub: #B7BDCE;     /* --muted 30% lighter */
    --faint: #56607A;
    --rule: #262F4A;
    --rule-strong: #364060;
    --btn-rule: #676D80;     /* --rule 30% lighter */
    --axis: #3A4462;
    --grid: #212A44;
    --data: #8190F0;
    --line: #A9B4FF;
    --highlight: #F0B35B;
    --highlight-text: #F0B35B;
    --ok: #5CC98D;
    --danger: #FF9C9C;
    --danger-bg: #3A1F2A;
    --nav: #0C1122;
    --nav-border: #222A43;
    --nav-ink: #F1F3F9;
    --nav-muted: #98A1B9;
    --nav-active: #1D2640;
    --nav-button-border: #35405F;
    --primary: #8190F0;
    --primary-ink: #0C1122;
    --block-1: #7C87E2;
    --block-2: #5CBFA5;
    --block-3: #E9B45C;
    --block-4: #E0866E;
    --area-opacity: 0.14;
    --temp-fill: rgba(169, 180, 255, 0.14);
    --trend: #CBD1E1;
    /* A shadow that reads as depth on white reads as dirt on near-black. */
    --shadow: none;
    /* Hovers, which were light tints before they were tokens. */
    --hover: #1E2740;
    --hover-danger: #4A2833;
    --ok-bg: #1B3A2C;
    --ok-ink: #5CC98D;
}

/* ---- the nav, on converted pages only -----------------------------------
 * base.html's own nav rules are hard-coded and shared with every page that has
 * not been converted. These override them under body.theme-light, so the bar
 * follows the theme on a sleep or motion panel and is left alone everywhere
 * else -- which is why those pages still show the old navy bar.
 */
/* The bar's own surface follows the theme. Its TEXT and its dropdown panels
   deliberately do not: they keep the colours and the font the light theme
   renders, in both themes (Paul, 2026-09-24).

   Two of those overrides were also wrong rather than merely unwanted.
   `body.theme-light nav .menu-btn` (0,2,2) outranks base.html's
   `.menu.open .menu-btn` (0,2,1), so an open menu kept the dim inactive
   colour instead of turning white; and base's
   `nav .menu-panel a:hover { color: #16213e }` still won on hover, which put
   dark navy text on the dark panel. Styling half a component from two files
   is how that happens. */
body.theme-light nav { background: var(--nav); border-bottom: 1px solid var(--nav-border); }

/* ---- the View menu ------------------------------------------------------- */
.view-choice { display: flex; align-items: center; gap: 0.6ch; }
.view-choice .view-tick { width: 1ch; display: inline-block; }

body.theme-light {
    background: var(--ground);
    font-family: var(--theme-font);
    color: var(--ink);
}

/* The shared container adds its own padding and max width; the restyled page
   manages its own spacing, and a second layer of it fights the 32px. */
body.theme-light .container { max-width: none; padding: 0; }

.sl-page { padding: 32px; display: flex; flex-direction: column; gap: 24px; }

/* ---- title row ---------------------------------------------------------- */
.sl-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.sl-head-text { display: flex; flex-direction: column; gap: 6px; }
.sl-head h1 {
    margin: 0; font-size: 30px; font-weight: 700;
    color: var(--ink); letter-spacing: -0.02em;
}
.sl-status { margin: 0; font-size: 14px; color: var(--muted); display: flex; align-items: center; }
.sl-dot {
    display: inline-block; width: 8px; height: 8px; border-radius: 4px;
    background: var(--ok); margin-right: 8px; flex: none;
}
.sl-status-off .sl-dot { background: var(--danger); }
.sl-refresh {
    height: 40px; padding: 0 16px; display: inline-flex; align-items: center; gap: 8px;
    border-radius: 8px; border: none; background: var(--primary); color: var(--primary-ink);
    font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; flex: none;
}
/* Darkened in light, lightened in dark: a hover has to move away from the
   button's own colour, and which way depends on the theme. */
.sl-refresh:hover { filter: brightness(1.15); }

/* ---- the four-stat strip ------------------------------------------------ */
.sl-stats {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
    background: var(--card); border: 1px solid var(--rule);
    border-radius: var(--radius); box-shadow: var(--shadow);
}
.sl-stat { display: flex; flex-direction: column; gap: 4px; padding: 16px 20px; min-width: 0; }
.sl-stat + .sl-stat { border-left: 1px solid var(--rule); }
/* Five, for a panel that shows a reading and its range for two measurements
   and then the history. Declared before the breakpoints below, so a narrow
   window still collapses it to two columns like every other strip. */
.sl-stats-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.sl-stat-label { font-size: 13px; color: var(--muted); }
.sl-stat-value {
    font-size: 28px; font-weight: 600; color: var(--ink);
    letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.sl-stat-sub { font-size: 12px; color: var(--muted); }

/* ---- the cards ---------------------------------------------------------- */
.sl-grid { display: flex; gap: 24px; align-items: stretch; }
.sl-card {
    background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
    padding: 20px; box-shadow: var(--shadow);
    display: flex; flex-direction: column; gap: 16px; min-width: 0;
}
/* 300px, not 360: the table inside is a timestamp and a Delete button, and
   the slack between them was pushing the chart column narrower than it needed
   to be (Paul, 2026-09-23). */
.sl-list { width: 300px; flex: none; }
.sl-charts { display: flex; flex-direction: column; gap: 24px; flex: 1 1 auto; min-width: 0; }
.sl-row2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }

.sl-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.sl-card-head h2 {
    margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); letter-spacing: -0.005em;
}
.sl-sub { margin: 0; font-size: 13px; color: var(--muted); }
.sl-head-text-2 { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sl-controls { display: flex; gap: 8px; align-items: center; flex: none; }

/* ---- the chart plot area ------------------------------------------------ */
/* A fixed height, with Chart.js told not to keep its own aspect ratio: left to
   itself it resizes away from these proportions. */
.sl-plot { position: relative; height: 250px; }
.sl-plot-wide { height: 250px; }

/* ---- buttons ------------------------------------------------------------ */
/* These override the older .day-btn and .detail-btn rules, which position
   themselves absolutely over the canvas. Here they sit in the card header. */
body.theme-light .sl-controls .day-btn,
body.theme-light .sl-controls .detail-btn {
    position: static; display: inline-flex; align-items: center; justify-content: center;
    font: inherit;
    /* The old layout floated these over the canvas and pulled them into place
       with transforms -- translateX(-100%) on Details, -50% on the arrow pair.
       Static position does not cancel a transform, so both stayed shifted left
       and landed on top of each other. */
    transform: none;
}
body.theme-light .sl-controls .day-nav {
    display: flex; gap: 6px; position: static; transform: none;
    /* Closed up over three passes on 2026-09-23: 3ch each side, then 1ch,
       then none. What separates them now is the 8px column gap on
       .sl-controls; take that to zero and they touch. */
    margin-right: 0;
}
body.theme-light .sl-controls .detail-btn { margin-left: 0; }
/* The wide chart at the bottom carries its controls 4ch further in than the
   two above it. Its own class rather than :has() or nth-child, so moving the
   card later cannot silently move the rule with it. */
body.theme-light .sl-panel-sleep .sl-controls { margin-right: 4ch; }
/* The same nudge on the temperature pager (Paul, 2026-09-25): 4ch of right
   margin is what moves a control group left without disturbing the header it
   sits in. */
body.theme-light .sl-panel-temp .sl-controls { margin-right: 4ch; }
body.theme-light .sl-controls .day-btn {
    height: 36px; min-width: 36px; padding: 0 10px; border-radius: 8px;
    border: 1px solid var(--rule); background: var(--card); color: var(--ink);
    font-size: 13px; cursor: pointer;
}
body.theme-light .sl-controls .day-btn:hover:not(:disabled) { background: var(--hover); }
body.theme-light .sl-controls .day-btn:disabled { color: var(--faint); cursor: default; }
body.theme-light .sl-controls .detail-btn {
    height: 32px; padding: 0 12px; border-radius: 8px; border: 1px solid var(--rule);
    background: transparent; color: var(--ink-2); font-size: 13px; font-weight: 500; cursor: pointer;
}
body.theme-light .sl-controls .detail-btn:hover { background: var(--hover); }
/* Sleep and motion: outlines easier to find (Paul, 2026-10-02). The
   temperature pager is the same button and keeps the quieter --rule. */
body.theme-light .sl-controls .day-btn,
body.theme-light .sl-controls .detail-btn { border-color: var(--btn-rule); }
body.theme-light .sl-panel-temp .sl-controls .day-btn { border-color: var(--rule); }

/* ---- motion panel: the status line, the legend, the footer --------------- */
/* Title, then a row carrying the email-alert pill and the reporting dot. */
.sl-title-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
/* The email-alert state, which used to be 1.425rem of bare coloured text
   positioned by script against the chart heading below it. As a pill it needs
   no measuring, and it stays beside the name it belongs to. */
body.theme-light .email-alert-status.sl-pill {
    display: inline-flex; align-items: center; gap: 6px;
    height: 26px; padding: 0 10px; border-radius: 13px;
    font-size: 13px; font-weight: 600; white-space: nowrap;
    /* The script that used to place this is gone; make sure no leftover
       inline offsets from a cached page keep pushing it about. */
    position: static; left: auto; top: auto; margin-left: 0;
}
/* Deactivated and offline are both red: in either case nothing is watching. */
body.theme-light .email-alert-status[data-state="off"],
body.theme-light .email-alert-status[data-state="offline"] {
    background: var(--danger-bg); color: var(--danger);
}
body.theme-light .email-alert-status[data-state="on"] {
    background: var(--ok-bg); color: var(--ok-ink);
}

.sl-foot { text-align: center; font-size: 12px; color: var(--muted); padding-top: 8px; }

/* The two motion charts are full width and differ in height. */
.sl-plot-grid { height: 270px; }
/* The temperature pair. The humidity plot is about two thirds of the one above
   it, which is the proportion the old stacked layout used and the reason the
   two read as a pair rather than as two unrelated cards. */
.sl-plot-temp { height: 320px; }
/* The controller panel is sized by its seven-day grid rather than by the page:
   about 52rem for the grid and 17rem for the cycle column beside it. Wider than
   that is empty space, so it stops here instead of stretching. */
.sl-page-plug { max-width: 73rem; }
.sl-plot-hum { height: 215px; }
.sl-plot-hourly { height: 230px; }

/* ---- the detections table ----------------------------------------------- */
.sl-list-scroll { overflow-y: auto; max-height: 600px; margin-top: -8px; }
/* The motion list sits beside two stacked charts rather than three, so it is
   shorter: a taller box would leave the column hanging below them. */
/* Exactly ten rows: a 26.5px header plus 10 x 38px (Paul, 2026-10-03).
   At 420px a sliver of an eleventh row showed. Change it in 38px steps. */
.sl-list-short { max-height: 406.5px; }
.sl-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.sl-table thead th {
    position: sticky; top: 0; background: var(--card); z-index: 1;
    text-align: left; font-size: 12px; font-weight: 600; color: var(--muted);
    padding: 0 4px 8px; border-bottom: 1px solid var(--rule-strong);
}
.sl-table thead th.sl-th-edit { text-align: right; }
.sl-table td {
    height: 38px; padding: 0 4px; border-top: 1px solid var(--rule);
    font-variant-numeric: tabular-nums;
}
.sl-table tbody tr:first-child td { border-top: none; }
/* A stronger rule where one night ends and the next begins. */
.sl-table tr.sl-night-break td { border-top: 1px solid var(--rule-strong); }
.sl-when { white-space: nowrap; }
.sl-date { color: var(--muted); display: inline-block; min-width: 60px; }
.sl-time { color: var(--ink); font-weight: 500; margin-left: 8px; }
/* The When cell takes the slack, so Delete sits against the right edge rather
   than a column width away from the time. */
.sl-table td.sl-when { width: 100%; }
.sl-td-edit { text-align: right; white-space: nowrap; }
body.theme-light .sl-table .sl-delete {
    height: 28px; padding: 0 10px; border-radius: 6px; border: 1px solid transparent;
    background: var(--danger-bg); color: var(--danger);
    font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
body.theme-light .sl-table .sl-delete:hover { background: var(--hover-danger); }

.sl-hint { text-align: center; color: var(--muted); font-size: 13px; }

/* ---- narrow screens ------------------------------------------------------ */
/* The list drops under the charts rather than squeezing them: below this width
   two columns of chart are unreadable anyway. */
@media (max-width: 1100px) {
    .sl-grid { flex-direction: column-reverse; }
    .sl-list { width: auto; }
    .sl-row2 { grid-template-columns: minmax(0, 1fr); }
    .sl-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* Whatever starts a row in a two-column layout, which is every odd
       card -- nth-child(3) happened to be right for four and is wrong for five. */
    .sl-stat:nth-child(odd) { border-left: none; }
    .sl-stat:nth-child(n+3) { border-top: 1px solid var(--rule); }
}
@media (max-width: 640px) {
    .sl-page { padding: 16px; gap: 16px; }
    .sl-head { flex-direction: column; align-items: flex-start; }
    .sl-stats { grid-template-columns: minmax(0, 1fr); }
    .sl-stat + .sl-stat { border-left: none; border-top: 1px solid var(--rule); }
    .sl-head h1 { font-size: 24px; }
}


/* ---- motion panel chart headings (Paul, 2026-10-02) ----------------------
 * Both titles 20% larger than the 16px card heading, and the date line under
 * each brighter than the usual subtitle: 30% lighter in dark, 25% darker in
 * light, so it gains contrast either way.
 */
.sl-panel-grid .sl-card-head h2,
.sl-panel-hourly .sl-card-head h2 { font-size: 19.2px; }
.sl-panel-grid .grid-title,
.sl-panel-hourly .hourly-title { color: var(--date-sub); }


/* ---- "Shared with you by ..." (Paul, 2026-10-02) ------------------------
 * Plain text on the page, no box: --ink is white-ish in dark and near-black in
 * light. Inset to line up with the panel's 32px padding.
 *
 * The panel below moves up 3ch of 12pt text (Paul), not 3ch of this line's
 * smaller text. A ch is measured in its element's own font size, so the lift
 * is an empty 12pt ::after with a -3ch bottom margin. With no bottom padding
 * or border on the note, that margin collapses with the note's own 1rem, and
 * the gap below becomes 1rem - 3ch(12pt).
 */
.shared-note {
    padding: 0 32px; font-size: 0.9rem; color: var(--ink);
    margin: 0 0 1rem;
}
/* One 12pt ch lower than that (Paul, 2026-10-02), the same trick at the
   top; the lift below grows by the same 1ch so the panel stays put. */
.shared-note::before {
    content: ""; display: block; font-size: 12pt; margin-top: 1ch;
}
.shared-note::after {
    content: ""; display: block; font-size: 12pt; margin-bottom: -4ch;
}
.shared-note a { color: inherit; text-decoration: underline; }
@media (max-width: 640px) { .shared-note { padding: 0 16px; } }


/* ---- sensor panels on phones (Paul, 2026-10-19) ---------------------------
 * The figures two by two rather than one long column, their labels free to
 * wrap; the panel nearly as wide as the phone, to cut scrolling. Last in the
 * file, so it follows the 640px rules above. "body" outranks the frame's
 * padding set in base.html. The charts' own changes (7 days, 12 hours) are in
 * dashboard.html's script.
 */
@media (max-width: 760px) {
    body .container-wide { padding-left: 4px; padding-right: 4px; }
    .sl-page { padding: 12px 4px; gap: 12px; }
    .sl-head { padding: 0 8px; }
    .sl-card { padding: 14px 10px; }
    .sl-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sl-stat { padding: 12px; }
    .sl-stat + .sl-stat { border-left: 1px solid var(--rule); border-top: none; }
    .sl-stat:nth-child(odd) { border-left: none; }
    .sl-stat:nth-child(n+3) { border-top: 1px solid var(--rule); }
    .sl-stat-label { font-size: 12px; line-height: 1.3; }
    .sl-stat-value { font-size: 24px; }
    /* The Activity Sensor's Detections list, signed in too (Paul, 2026-10-19):
       the charts above say it, and the list was the longest scroll. */
    .sensor-panel[data-sensor-type="motion"] .sl-list { display: none; }
    /* Motion by hour (Paul, 2026-10-19): the arrows at the right with
       Details under them, the night on three lines, the chart 25% shorter. */
    .sl-panel-motion .sl-controls { flex-direction: column; align-items: flex-end; gap: 6px; }
    .sl-panel-motion .sl-sub[data-sub="motion"] { white-space: pre-line; }
    .sl-panel-motion .sl-plot { height: 188px; }
    /* Longest nightly motion-free interval, the same way (Paul, 2026-10-19),
       and without its "Nights with no detections are excluded" line. */
    .sl-panel-sleep .sl-controls { flex-direction: column; align-items: flex-end; gap: 6px; }
    body.theme-light .sl-panel-sleep .sl-controls { margin-right: 0; }   /* the computer's 4ch nudge, off */
    .sl-panel-sleep .sl-head-text-2 .sl-sub { display: none; }
    /* The Detections list shows the newest four (Paul, 2026-10-19): its
       26.5px header plus 4 x 38px rows; older ones are a scroll away, so
       they can still be deleted. */
    .sl-list-scroll, .sl-list-short { max-height: 178.5px; }
    /* The Sleep Sensor's boxes 12px apart, as the figures are from Motion by
       hour (Paul, 2026-10-24); they were 24px. */
    .sensor-panel[data-sensor-type="sleep"] .sl-grid,
    .sensor-panel[data-sensor-type="sleep"] .sl-charts,
    .sensor-panel[data-sensor-type="sleep"] .sl-row2 { gap: 12px; }
    /* The email-alert label wraps rather than running off the screen. */
    body.theme-light .email-alert-status.sl-pill {
        white-space: normal; height: auto; min-height: 26px;
        padding: 4px 10px; line-height: 1.3;
    }
}
