  /* Sign-in / set-password pages. align-items:flex-start + margin:auto on the card, rather than
     align-items:center, so that when the card is taller than the viewport (a landscape tablet or any
     short window) it starts at the top and the page scrolls to the rest of it - centring an
     overflowing flex item puts its top and bottom edges outside the scrollable area, which used to
     leave the Sign In button unreachable. */
  /* flex:1 rather than a 100dvh height: these pages sit under the header inside body's flex column,
     so a full viewport height overflowed the document by exactly the header's height and left the
     whole page scrollable by that much even when the card fit. */
  .auth-page{flex:1 1 auto; min-height:0; align-items:flex-start; justify-content:center; width:100%;
    overflow-y:auto; padding:16px; background:var(--paper)}
  .auth-card{width:100%; max-width:400px; margin:auto; padding:40px; background:var(--card);
    border-radius:12px; box-shadow:0 2px 8px rgba(0,0,0,0.1)}
  .auth-brand{text-align:center; margin-bottom:28px}
  /* The markup carries a width attribute (a presentational hint) alongside its inline height, so any
     rule that changes only the height - the short-screen and landscape ones below - would stretch the
     logo to that fixed width. width:auto beats the hint and keeps its 132:151 proportions. */
  .auth-brand img{width:auto}
  @media(max-width:480px){.auth-card{padding:24px}}
  /* Short windows: trim the card enough that it fits without scrolling. */
  @media(max-height:620px){
    .auth-card{padding:22px 24px}
    .auth-brand{margin-bottom:14px}
    .auth-brand img{height:42px !important; margin-bottom:8px !important}
    .auth-card .field{margin:12px 0 !important}
  }
  /* Landscape (any wide-enough landscape display - desktop, tablet or a rotated phone): the brand sits
     beside the form rather than above it, which suits the shape of the screen and, on a phone in
     landscape, is the difference between fitting and not - stacked it wants ~460px of height where
     there is ~350px, while half the width goes unused. A portrait display (including a rotated
     monitor) keeps the stacked card, which is the right shape there. */
  @media(orientation:landscape) and (min-width:620px){
    .auth-card{display:flex; align-items:center; gap:32px; max-width:720px; padding:32px 34px}
    .auth-brand{flex:0 0 38%; margin:0; padding-right:32px; border-right:1px solid var(--line)}
    .auth-form{flex:1; min-width:0}
  }
  /* Short landscape (phones, and any squat window): same two columns, tightened to fit the height. */
  @media(orientation:landscape) and (min-width:620px) and (max-height:560px){
    .auth-page{padding:10px}
    .auth-card{gap:26px; max-width:660px; padding:18px 24px}
    .auth-brand{padding-right:26px}
    .auth-brand img{height:52px !important; margin-bottom:10px !important}
    .auth-card .field{margin:10px 0 !important}
    /* The "keep me signed in" row - the only non-.field block in the form. */
    .auth-form>div:not(.field){margin:8px 0 !important}
    .auth-form>p{margin-top:10px !important; font-size:11px !important}
  }

  /* Full-screen scroll-to-accept Terms/Privacy gate (#termsGatePage, index.html) - deliberately
     NOT .auth-card's narrow centred box: the whole point is a reading pane big enough that
     scrolling it feels like reading the actual document, not squinting at a modal. Two classes
     (.auth-page.terms-gate-page) beats plain .auth-page on specificity, so this doesn't need
     !important to override align-items:flex-start with the stretch this variant needs instead. */
  .auth-page.terms-gate-page{align-items:stretch; padding:20px;}
  .terms-gate-card{width:100%; max-width:820px; margin:0 auto; display:flex; flex-direction:column; min-height:0;}
  .terms-gate-head{flex-shrink:0; margin-bottom:14px;}
  /* flex:1 fills whatever height .terms-gate-card ends up with (stretched to match .auth-page's
     own, itself the viewport minus the header - see base.css's --hdr-h comment); min-height is
     just a floor for very short windows, where the outer .auth-page's own overflow-y:auto is the
     fallback that keeps the Accept button reachable rather than clipped. */
  .terms-gate-box{flex:1 1 auto; min-height:160px; overflow-y:auto; overscroll-behavior:contain;
    background:var(--card); border:1px solid var(--line); border-radius:12px; padding:22px 26px;}
  @media(max-width:600px){ .terms-gate-box{padding:16px;} }
  /* Minimal typography for the legal content injected here (loadTermsGateContent, auth.js) - a
     smaller, self-contained echo of legal.css's .legal-wrap rules, not a shared stylesheet,
     because this box's own padding/scroll/border already do what .legal-wrap's max-width/margin
     would otherwise fight with. */
  .terms-gate-box h2{font-family:'Space Grotesk',sans-serif; font-size:15px; margin:20px 0 8px;}
  .terms-gate-box h2:first-child{margin-top:0;}
  .terms-gate-box p{line-height:1.6; margin:0 0 12px; color:var(--ink); font-size:13px;}
  .terms-gate-box ul{margin:0 0 12px; padding-left:20px; line-height:1.6; font-size:13px;}
  .terms-gate-box li{margin-bottom:6px;}
  .terms-gate-box table{width:100%; border-collapse:collapse; margin:0 0 14px; font-size:12px;}
  .terms-gate-box th, .terms-gate-box td{text-align:left; padding:8px 9px; border:1px solid var(--line); vertical-align:top;}
  .terms-gate-box th{background:var(--paper); font-weight:700;}
  /* No app-wide "a{color:...}" rule exists (every other link in the app sets its own color
     inline), so the Contact section's mailto:/https:// links here would otherwise fall back to
     the browser's native link colors - blue unvisited, a jarring magenta once visited - clashing
     with the theme instead of reading as this app's own accent blue. */
  .terms-gate-box a{color:var(--accent);}

  /* Account menu - an ordinary centred dialog by default; only phones dock it to the bottom edge
     (see the phone section), where a full-bleed sheet is both easier to reach and easier to hit. */
  .modal-bg.sheet .modal{max-width:420px}
  .sheet-header-actions{display:flex; align-items:center; gap:8px; margin-left:auto; flex-shrink:0}
  .sheet-icon-btn{width:30px; height:30px; padding:0; flex-shrink:0; display:inline-flex;
    align-items:center; justify-content:center; background:transparent; border-radius:7px; cursor:pointer}
  .sheet-icon-btn svg{width:17px; height:17px}
  .install-app-btn{border-color:var(--accent); color:var(--accent)}
  .install-app-btn:hover{background:var(--accent); color:#fff}
  .sheet-close-btn{border-color:#C0392B; color:#C0392B; font-size:16px; line-height:1}
  .sheet-close-btn:hover{background:#C0392B; border-color:#C0392B; color:#fff}
  .profile-modal{position:relative}
  /* Give the signed-in user's photo a clear accent ring in the account sheet without changing
     the same .acct-avatar component where it is reused by the avatar picker. */
  .sheet-profile-header .acct-avatar{box-sizing:border-box; border:2px solid var(--accent)}
  /* Covers the entire modal layer, including Edit profile's outer blue border; only the source
     menu itself sits above this, so every other element is blurred consistently. */
  .avatar-menu-scrim{position:absolute; inset:0; z-index:65;
    background:rgba(16,24,37,.16); backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px)}
  .avatar-source-menu{z-index:70; min-width:220px; border:1px solid var(--accent); border-radius:9px}
  .avatar-source-menu .avatar-source-option{display:grid; grid-template-columns:18px 1fr 18px;
    align-items:center; gap:7px; padding:11px 12px; text-align:center; border-bottom:1px solid var(--accent);
    color:var(--ink); font-size:13px; font-weight:600}
  .avatar-source-menu .avatar-source-option:last-child{border-bottom:0}
  .avatar-source-menu .avatar-source-option:hover{background:color-mix(in srgb, var(--accent) 12%, var(--card))}
  .avatar-source-menu .avatar-source-option.current{background:var(--accent); color:#fff}
  .avatar-source-menu .avatar-source-option.current:hover{background:var(--accent)}
  .avatar-source-check{display:inline-flex; align-items:center; justify-content:center; font-size:15px}
  .device-loading{padding:22px; text-align:center; color:var(--muted)}
  .device-card{padding:14px; margin-top:10px; border:1px solid var(--line); border-radius:11px; background:var(--paper)}
  .device-card.current{border:2px solid var(--accent)}
  .device-card-heading{display:flex; align-items:center; gap:10px; padding-bottom:12px; margin-bottom:10px; border-bottom:1px solid var(--line)}
  .device-icon{font-size:22px; flex-shrink:0}
  .device-card-heading strong,.device-card-heading span{display:block}
  .device-card-heading div>span{margin-top:2px; color:var(--muted); font-size:12px}
  .device-current-badge{margin-left:auto; padding:4px 7px; border-radius:999px; background:var(--accent); color:#fff; font-size:10px; font-weight:700; white-space:nowrap}
  .device-detail{display:flex; justify-content:space-between; gap:14px; padding:4px 0; font-size:12px}
  .device-detail span{color:var(--muted)}
  .device-detail strong{text-align:right; overflow-wrap:anywhere}
  .device-zone{margin-top:7px; color:var(--muted); font-size:10px; text-align:right}
  .device-logout-btn{display:block; width:100%; margin-top:11px; padding:8px 10px; border:1px solid #C0392B;
    border-radius:8px; background:transparent; color:#C0392B; font-size:12px; font-weight:700; cursor:pointer}
  .device-logout-btn:hover{background:#C0392B; color:#fff}
  .device-logout-btn:disabled{opacity:.6; cursor:wait}
  .device-logout-all-btn{margin-top:16px; background:#C0392B; color:#fff}
  .device-logout-all-btn:hover{background:#A93226; border-color:#A93226}
  .sheet-row{display:flex; align-items:center; gap:10px; width:100%; margin-top:8px; padding:13px 12px;
    border:1px solid var(--line); border-radius:10px; background:var(--card); color:var(--ink);
    font-size:14px; font-weight:600; text-align:left; cursor:pointer}
  .sheet-row.danger{border-color:#C0392B; color:#C0392B}
  /* The timezone control IS the row - the whole cell is the button, and it states what it is plus the
     current zone ("Timezone - Halifax (ADT)"). Its menu is the app's own dropdown rather than a native
     select, which is what lets the list show just the regions while the closed row keeps the label. */
  .sheet-row .sheet-caret{margin-left:auto; font-size:10px; color:var(--muted)}
  /* Matches the same blue/white "selected" look used elsewhere (e.g. the active tab, .tz-current)
     while its own menu is expanded, so an open row reads as "selected" rather than looking identical
     to every closed one - see toggleDropdown, which adds/removes this class on the trigger button. */
  .sheet-row.open{background:var(--accent); border-color:var(--accent); color:#fff}
  .sheet-row.open .sheet-caret{color:#fff}
  /* The zone list opens in the flow under its row, not as an absolute overlay: the list itself is what
     scrolls (the sheet around it stays put), and an overlay that long would in any case be clipped by
     the dialog's own scroll box instead of scrolling. */
  .tz-list{max-height:min(48dvh, 300px); overflow-y:auto; overscroll-behavior:contain; margin-top:6px;
    border:1px solid var(--line); border-radius:10px; background:var(--card)}
  .tz-list>div{display:flex; align-items:center; gap:8px; padding:11px 12px; font-size:14px;
    font-weight:600; color:var(--ink); cursor:pointer}
  .tz-list>div:hover{background:var(--paper)}
  /* Compact account-sheet submenus share the timezone list's container styling, but their items
     are discrete actions and need a visible separator. Keep this off the timezone list, whose
     region headings and inset current-zone card use a different visual structure. */
  .sheet-submenu{border-color:var(--accent)}
  .sheet-submenu>div:not(:last-child){border-bottom:1px solid var(--accent)}
  .tz-list .tz-default{font-weight:400; color:var(--muted)}
  .tz-list .tz-region{position:sticky; top:0; z-index:1; padding:6px 12px; background:var(--paper);
    font-size:11px; font-weight:700; letter-spacing:.4px; text-transform:uppercase; color:var(--muted); cursor:default}
  .tz-list .tz-region:hover{background:var(--paper)}
  /* The zone in use, marked in place: a frosted accent panel with white text, so once the list has
     scrolled to it (toggleTimezoneList) it reads as the current setting rather than as one more option.
     The solid accent is declared first as the fallback for browsers without color-mix(). */
  .tz-list .tz-current{margin:6px; padding:11px 12px; border-radius:8px; color:#fff; font-weight:700;
    background:var(--accent);
    background:color-mix(in srgb, var(--accent) 34%, transparent);
    border:1px solid color-mix(in srgb, var(--accent) 60%, transparent);
    backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px)}
  .tz-list .tz-current:hover{background:color-mix(in srgb, var(--accent) 48%, transparent)}
  .tz-list .tz-current .tz-default{color:rgba(255,255,255,.75)}
