/* =====================================================================
   assets/css/responsive.css
   Loaded after app.css.

   The device list this was built against contains ~39 phones, tablets,
   laptops and monitors, but they resolve to only 25 distinct CSS
   viewport widths, and those cluster into 8 bands. Writing a rule per
   device would be 39 copies of 8 rules that drift apart the moment a
   new phone ships. Each band below names the hardware it covers so the
   mapping is checkable.

   CSS widths, not physical pixels: an iPhone 15 Pro Max is 430pt wide
   whatever its screen does with them.
   ===================================================================== */

/* ---------------------------------------------------------------------
   BAND 1 — small phones,  ≤ 400px
   iPhone 12/13 mini (360), SE 2nd/3rd, 7, 8, X, XS, 11 Pro (375),
   iPhone 12/13/14/16e (390), 15/16 & Pixel (393)
   --------------------------------------------------------------------- */
@media (max-width: 400px) {
  html { font-size: 15px; }

  main.container-fluid { padding-left: 10px !important; padding-right: 10px !important; }

  .scoreboard { grid-template-columns: 1fr 1fr; }
  .score { padding: 9px 10px; }
  .score .k { font-size: 7.5px; letter-spacing: .1em; }
  .score .v { font-size: 14.5px !important; }
  .score.lead .v { font-size: 16px !important; }
  .score .s { font-size: 9.5px; min-height: calc(2 * 1.35 * 9.5px); }

  h1.h4 { font-size: 1rem; }
  .panel-head h2 { font-size: 12.5px; }
  .panel-head .sub { font-size: 10.5px; }

  .brand-logo-mark { height: 24px; }
  .brand-co { max-width: 104px; font-size: 9px; }
  .usermenu .who { display: none; }        /* avatar alone; the name wraps badly */
  .usermenu .btn { padding: 5px 7px; }

  .echart { height: 220px !important; }
  .chart-wrap { height: 200px; }

  .dt-buttons .btn { padding: 4px 7px; font-size: 11px; }
  .auth-card { padding: 20px 16px 16px; }
  .auth-logo { width: 170px; }
  .splash-logo { width: 80vw; }
}

/* ---------------------------------------------------------------------
   BAND 2 — large phones,  401–575px
   iPhone 16 Pro / 17 / 17 Pro (402), Galaxy S24U (412), 7/8 Plus, XR,
   11, XS Max, 11 Pro Max (414), 17 Air (420), 12/13 Pro Max, 14 Plus
   (428), 14 Pro Max, 15 Plus, 15 Pro Max (430), 16 Pro Max, 17 Pro Max (440)
   --------------------------------------------------------------------- */
@media (min-width: 401px) and (max-width: 575.98px) {
  .scoreboard { grid-template-columns: 1fr 1fr; }
  .score .v { font-size: 16px !important; }
  .echart { height: 240px !important; }
  .brand-co { max-width: 130px; }
}

/* ---------------------------------------------------------------------
   BAND 3 — landscape phones,  576–743px
   Any of the above rotated: 667–956 wide but only 320–440 tall.
   Vertical space is the scarce resource here, not horizontal.
   --------------------------------------------------------------------- */
@media (min-width: 576px) and (max-width: 743.98px) {
  .scoreboard { grid-template-columns: repeat(3, 1fr); }
  .chart-grid { grid-template-columns: 1fr; }
}

/* A short viewport in landscape: shrink the chrome, not the content. */
@media (max-height: 500px) and (orientation: landscape) {
  .tape { display: none; }                 /* the tape is the first thing to go */
  .navbar-collapse { max-height: 60vh; overflow-y: auto; }
  .deskbar { padding-top: 2px; padding-bottom: 2px; }
  .scoreboard { margin-bottom: 12px; }
  .score { padding: 7px 10px; }
  .score .v { font-size: 14px !important; }
  .echart, .chart-wrap { height: 190px !important; }
  .modal-dialog { min-height: auto; }
  .modal-content { min-height: auto; }
  .splash-logo { width: 240px; }
}

/* ---------------------------------------------------------------------
   BAND 4 — tablets portrait,  744–1023px
   iPad mini 6 / A17 (744), iPad 5th–9th & mini 5 (768), Android 10"
   (800), iPad 10th/A16, Air 4/5/11", Pro 11" all gens (820),
   iPad Air 3 & Pro 10.5 (834)
   --------------------------------------------------------------------- */
@media (min-width: 744px) and (max-width: 1023.98px) {
  main.container-fluid { padding-left: 18px !important; padding-right: 18px !important; }

  .scoreboard { grid-template-columns: repeat(3, 1fr); }
  .score .v { font-size: 17px !important; }

  .chart-grid { grid-template-columns: repeat(2, 1fr); }
  .span-wide { grid-column: span 2; }
  .span-half, .span-third { grid-column: span 1; }
  .echart { height: 280px; }
  .span-wide .echart { height: 320px; }

  /* Tablets are wide enough for a real modal, unlike a phone. */
  .modal-dialog { margin: 1.75rem auto; min-height: auto; max-width: 92vw; }
  .modal-content { min-height: auto; border-radius: 12px;
                   border: 1px solid var(--line); }
  .modal-body { padding-bottom: 1rem; }
  .modal-footer { position: static; }

  .brand-logo { display: block; height: 26px; }
  .brand-logo-mark { display: none; }
}

/* ---------------------------------------------------------------------
   BAND 5 — tablet landscape and small laptops,  1024–1365px
   iPad Pro 12.9 all gens & Air 13" (1024), MacBook Air/Pro 13 (1280)
   --------------------------------------------------------------------- */
@media (min-width: 1024px) and (max-width: 1365.98px) {
  .scoreboard { grid-template-columns: repeat(4, 1fr); }
  .chart-grid { grid-template-columns: repeat(4, 1fr); }
  .span-wide { grid-column: span 4; }
  .span-half { grid-column: span 2; }
  .span-third { grid-column: span 2; }
  .echart { height: 290px; }
}

/* ---------------------------------------------------------------------
   BAND 6 — laptops,  1366–1919px
   Windows 1366, MacBook Air 15 (1440), MBP 14 (1512), MBP 16 (1728)
   This is the design's home ground; app.css already fits it.
   --------------------------------------------------------------------- */
@media (min-width: 1366px) and (max-width: 1919.98px) {
  .chart-grid { grid-template-columns: repeat(6, 1fr); }
  .span-wide { grid-column: span 6; }
  .span-half { grid-column: span 3; }
  .span-third { grid-column: span 2; }
}

/* ---------------------------------------------------------------------
   BAND 7 — desktop,  1920–2559px
   iMac 21.5/24, 1080p monitors
   Stop the content becoming a thin ribbon: widen, then cap.
   --------------------------------------------------------------------- */
@media (min-width: 1920px) {
  html { font-size: 17px; }
  body { font-size: 15px; }

  main.container-fluid,
  .deskfoot > .container-fluid,
  .deskbar > .container-fluid { max-width: 1860px; margin-inline: auto; }

  .scoreboard { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
  .score { padding: 16px 18px; }
  .score .v { font-size: 21px !important; }
  .score.lead .v { font-size: 26px !important; }

  .echart { height: 340px; }
  .span-wide .echart { height: 420px; }
  .chart-wrap { height: 340px; }
  .brand-logo { height: 34px; }
}

/* ---------------------------------------------------------------------
   BAND 8 — large monitors and television,  ≥ 2560px
   iMac 27" 5K, 1440p panels, 4K TV at 3840
   A TV is watched from three metres, so everything scales up and the
   line length is capped. This is a ten-foot interface, not a big desktop.
   --------------------------------------------------------------------- */
@media (min-width: 2560px) {
  html { font-size: 20px; }
  body { font-size: 17px; }

  main.container-fluid,
  .deskfoot > .container-fluid,
  .deskbar > .container-fluid { max-width: 2400px; }

  .scoreboard { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
  .score { padding: 20px 22px; }
  .score .k { font-size: 11px; }
  .score .v { font-size: 27px !important; }
  .score.lead .v { font-size: 34px !important; }
  .score .s { font-size: 13px; }

  .brand-logo { height: 44px; }
  .nav-link { font-size: 15px; padding: 10px 16px !important; }
  .echart { height: 420px; }
  .span-wide .echart { height: 520px; }
  .chart-wrap { height: 420px; }

  table.dataTable td, table.dataTable th { font-size: 15px; padding: 10px 12px; }
  .btn { font-size: 15px; }
  .panel-head h2 { font-size: 17px; }
  .panel-head .sub { font-size: 13.5px; }
}

/* 4K and up: from across a room, thin text disappears. */
@media (min-width: 3400px) {
  html { font-size: 24px; }
  body { font-size: 19px; }
  main.container-fluid { max-width: 3200px; }
  .score .v { font-size: 32px !important; }
  .score.lead .v { font-size: 42px !important; }
  .brand-logo { height: 56px; }
  .echart { height: 520px; }
  .span-wide .echart { height: 640px; }
  /* Hairlines vanish at this distance. */
  .panel, .scoreboard, table.dataTable td { border-width: 2px; }
}

/* =====================================================================
   INPUT TYPE, not screen size
   A tablet and a laptop can share a width but not a pointer.
   ===================================================================== */
@media (hover: none) and (pointer: coarse) {
  .btn, .nav-link, .dropdown-item, .chip, .page-link,
  .form-control, .form-select { min-height: var(--tap); }

  td .btn-sm, th .btn-sm { min-width: 36px; min-height: 36px; }
  .table-responsive { -webkit-overflow-scrolling: touch; }

  /* Hover-only affordances never appear on touch, so make them permanent. */
  .rowlink:active td { background: var(--panel-2); }
  .act-status { text-decoration: underline dotted; }
}

@media (hover: hover) and (pointer: fine) {
  .rowlink:hover td { background: var(--panel-2); }
}

/* =====================================================================
   BROWSER QUIRKS
   ===================================================================== */

/* Safari — iOS and macOS.
   -webkit-fill-available fixes the old 100vh-under-the-toolbar problem
   on iOS versions that predate dvh. Date inputs need explicit alignment
   or they render centred and clipped. */
@supports (-webkit-touch-callout: none) {
  .auth-wrap, .auth-body { min-height: -webkit-fill-available; }
  input[type="date"], input[type="time"] {
    -webkit-appearance: none; appearance: none;
    text-align: left; min-height: var(--tap);
  }
  /* iOS Safari ignores overflow scrolling inside a flex child without this. */
  .table-responsive { transform: translateZ(0); }
}

/* Safari also needs the prefix for backdrop blur. */
.deskbar, .modal-footer {
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  backdrop-filter: saturate(140%) blur(8px);
}

/* Firefox — no ::-webkit-scrollbar, uses its own two properties. */
@supports (scrollbar-width: thin) {
  * { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
}

/* Chromium family: Chrome, Edge, Opera, Brave, Vivaldi. */
@supports selector(::-webkit-scrollbar) {
  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-track { background: transparent; }
  ::-webkit-scrollbar-thumb {
    background: var(--line); border-radius: 6px;
    border: 2px solid var(--bg);
  }
  ::-webkit-scrollbar-thumb:hover { background: #37414f; }
}

/* Edge puts its own reveal button next to ours on password fields. */
input::-ms-reveal, input::-ms-clear { display: none; }

/* Firefox draws a red glow on :invalid before the user has typed. */
input:invalid, select:invalid, textarea:invalid { box-shadow: none; }

/* Chrome's yellow autofill is unreadable on a dark panel. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--txt);
  -webkit-box-shadow: 0 0 0 1000px var(--panel-2) inset;
  caret-color: var(--txt);
  transition: background-color 9999s ease-out;
}

/* =====================================================================
   NOTCHES, CUT-OUTS AND HOME INDICATORS
   iPhone X onward, and most modern Android. Needs viewport-fit=cover,
   which is set in the page head.
   ===================================================================== */
@supports (padding: max(0px)) {
  .deskbar > .container-fluid,
  main.container-fluid,
  .deskfoot > .container-fluid {
    padding-left:  max(12px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
  }
  body { padding-bottom: env(safe-area-inset-bottom); }
  .tape { padding-left: env(safe-area-inset-left); }
  .modal-footer { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
  .toast-host { bottom: max(16px, calc(16px + env(safe-area-inset-bottom))); }
}

/* =====================================================================
   PIXEL DENSITY
   ===================================================================== */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  /* Retina renders a 1px border at 0.5 device pixels and it disappears. */
  .panel, .scoreboard, .reset-card { border-width: 0.5px; }
  body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
}

/* =====================================================================
   PRINT — statements go to clients on paper
   ===================================================================== */
@media print {
  @page { margin: 14mm; size: A4; }

  html, body { background: #fff !important; color: #000 !important; font-size: 11pt; }
  .tape, .deskbar, .chipbar, .toolbar, .deskfoot,
  .btn, .dt-buttons, .dataTables_filter, .dataTables_paginate,
  .dataTables_length, .chart-expand, .skip, .danger-panel { display: none !important; }

  .panel { border: 1px solid #bbb !important; background: #fff !important;
           break-inside: avoid; page-break-inside: avoid; margin-bottom: 10pt; }
  .panel-head { background: #f4f4f4 !important; }
  .panel-head h2, .score .v, h1, h2, td, th { color: #000 !important; }
  .score { background: #fff !important; border: 1px solid #ddd; }
  .scoreboard { background: #fff !important; }

  .up   { color: #0a6b3d !important; }
  .down { color: #a3161a !important; }
  .amber{ color: #7a5a10 !important; }

  a[href]::after { content: ""; }        /* URLs after every link are noise */
  table { font-size: 9pt; }
  thead { display: table-header-group; } /* repeat headers across pages */
  tr { page-break-inside: avoid; }
}

/* =====================================================================
   HIGH CONTRAST AND FORCED COLOURS (Windows)
   ===================================================================== */
@media (forced-colors: active) {
  .panel, .score, .reset-card { border: 1px solid CanvasText; }
  .pill { border: 1px solid CanvasText; }
  .btn { border: 1px solid ButtonText; }
}
