/* ============================================================================
   responsive.css - global adaptive layer for the TheiaLabs web app.

   Injected into every HTML response by app.py (add_app_shell) *after*
   each page's own inline <style>, so same-specificity rules here win without
   needing !important.

   Viewport classes, set on <html> by responsive.js:
     data-view="mobile"   <= 767px
     data-view="tablet"   768 - 1023px
     data-view="desktop"  >= 1024px   (desktop is left exactly as it was)
     data-orient="portrait|landscape", data-touch="1" on touch devices

   Layout rules live in plain @media blocks so the app still reflows correctly
   if JavaScript is blocked; only the JS-built components (nav drawer, sidebar
   drawer) key off the data-* attributes.
   ========================================================================= */

:root{
  --rwd-bar-h: 54px;          /* compact mobile app bar height               */
  --rwd-tap: 44px;            /* minimum comfortable tap target              */
  --rwd-gutter: 16px;         /* page side padding on phones                 */
  --rwd-safe-t: env(safe-area-inset-top, 0px);
  --rwd-safe-b: env(safe-area-inset-bottom, 0px);
  --rwd-safe-l: env(safe-area-inset-left, 0px);
  --rwd-safe-r: env(safe-area-inset-right, 0px);
  --rwd-vh: 1vh;              /* real 1% of viewport height, kept live by JS */
}

html{ -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ---------------------------------------------------------------- utilities */
.rwd-scroll{ max-width: 100%; }
@media (max-width: 1023px){
  .rwd-scroll{
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .rwd-scroll::-webkit-scrollbar{ height: 6px; }
  .rwd-scroll > table{ min-width: max-content; }
}

/* Shown only on phones and tablets. */
.rwd-mobile-only{ display: none; }
html[data-view="mobile"] .rwd-mobile-only,
html[data-view="tablet"] .rwd-mobile-only{ display: block; }

/* ================================================================= MOBILE UI
   Chrome built at runtime by responsive.js: the hamburger button, the slide-in
   navigation drawer and the shared backdrop. Hidden outright on desktop.
   ========================================================================= */
.rwd-navbtn,
.rwd-sidebtn{
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--rwd-tap);
  height: 38px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 8px;
  background: rgba(255,255,255,.06);
  color: currentColor;
  font: inherit;
  line-height: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.rwd-navbtn:active,
.rwd-sidebtn:active{ background: rgba(255,255,255,.14); }
.rwd-navbtn .rwd-bars,
.rwd-sidebtn .rwd-bars{
  display: block;
  position: relative;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}
.rwd-navbtn .rwd-bars::before,
.rwd-navbtn .rwd-bars::after,
.rwd-sidebtn .rwd-bars::before,
.rwd-sidebtn .rwd-bars::after{
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}
.rwd-navbtn .rwd-bars::before,
.rwd-sidebtn .rwd-bars::before{ top: -6px; }
.rwd-navbtn .rwd-bars::after,
.rwd-sidebtn .rwd-bars::after{ top: 6px; }

html[data-view="mobile"] .rwd-navbtn,
html[data-view="tablet"] .rwd-navbtn,
html[data-view="mobile"] .rwd-sidebtn,
html[data-view="tablet"] .rwd-sidebtn{ display: inline-flex; }

/* The 3D viewers show both buttons at once. Two identical hamburgers side by
   side would be a coin toss, so the sidebar one is drawn as a panel. */
.rwd-sidebtn .rwd-bars{
  width: 18px;
  height: 14px;
  background: transparent;
  border: 2px solid currentColor;
  border-radius: 3px;
}
.rwd-sidebtn .rwd-bars::before{
  top: 0;
  left: 3px;
  width: 2px;
  height: 100%;
  border-radius: 0;
}
.rwd-sidebtn .rwd-bars::after{ display: none; }

/* Collapse control added to the telemetry HUD by responsive.js. */
.rwd-collapse{
  margin-left: auto;
  width: 30px;
  height: 26px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid rgba(255,255,255,.22);
  border-radius: 6px;
  background: rgba(255,255,255,.06);
  color: currentColor;
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.rwd-collapse:active{ background: rgba(255,255,255,.16); }

/* Backdrop shared by the nav drawer and the sidebar drawer. */
.rwd-backdrop{
  position: fixed;
  inset: 0;
  z-index: 100000;
  background: rgba(0,0,0,.6);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
body.rwd-drawer-open .rwd-backdrop{ opacity: 1; pointer-events: auto; }

/* Slide-in navigation drawer, populated from each page's own top-bar links. */
.rwd-drawer{
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  z-index: 100001;
  width: min(82vw, 330px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: calc(14px + var(--rwd-safe-t)) 14px calc(20px + var(--rwd-safe-b));
  background: #0c0e12;
  border-left: 1px solid rgba(255,255,255,.12);
  box-shadow: -18px 0 48px rgba(0,0,0,.6);
  transform: translateX(100%);
  /* visibility, not just the transform: an off-screen drawer is still in the
     tab order, so a keyboard user on desktop would otherwise tab into a menu
     they cannot see. It flips back instantly on open and only after the
     slide-out finishes on close. */
  visibility: hidden;
  transition: transform .24s cubic-bezier(.22,.61,.36,1),
              visibility 0s linear .24s;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}
body.rwd-nav-open .rwd-drawer{
  transform: translateX(0);
  visibility: visible;
  transition: transform .24s cubic-bezier(.22,.61,.36,1), visibility 0s;
}
.rwd-drawer-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,.10);
  color: #a3a9b4;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.rwd-drawer-id{
  display: flex;
  align-items: center;
  min-width: 0;
}
.rwd-drawer-who{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rwd-drawer-close{
  width: 36px;
  height: 36px;
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 8px;
  background: transparent;
  color: #f4f6fa;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.rwd-drawer a,
.rwd-drawer .rwd-drawer-item{
  display: flex;
  align-items: center;
  min-height: var(--rwd-tap);
  padding: 10px 12px;
  border-radius: 8px;
  color: #e9edf4;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  background: transparent;
}
.rwd-drawer a:active,
.rwd-drawer .rwd-drawer-item:active{ background: rgba(255,255,255,.08); }
/* Install-to-home-screen button. The [hidden] rule is load-bearing: the
   .rwd-drawer-item display:flex above would otherwise beat the browser's
   default styling for the hidden attribute and show the button regardless. */
.rwd-drawer .rwd-install{
  width: 100%;
  margin-top: 16px;
  justify-content: center;
  border: 1px solid rgba(74,216,255,.45);
  background: rgba(74,216,255,.10);
  color: #bfefff;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.rwd-drawer .rwd-install:active{ background: rgba(74,216,255,.2); }
.rwd-drawer .rwd-install[hidden]{ display: none; }

.rwd-drawer .rwd-drawer-label{
  margin: 14px 0 4px;
  padding: 0 12px;
  color: #6a6f7a;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* Off-canvas drawer for the tool sidebars (3D viewer, breadboard, pointing). */
html[data-view="mobile"] .rwd-side-drawer,
html[data-view="tablet"] .rwd-side-drawer{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 100001;
  width: min(88vw, 360px);
  max-height: none;
  padding-top: calc(10px + var(--rwd-safe-t));
  padding-bottom: calc(16px + var(--rwd-safe-b));
  transform: translateX(-100%);
  visibility: hidden;
  transition: transform .24s cubic-bezier(.22,.61,.36,1),
              visibility 0s linear .24s;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  box-shadow: 18px 0 48px rgba(0,0,0,.6);
}
html[data-view="mobile"] body.rwd-side-open .rwd-side-drawer,
html[data-view="tablet"] body.rwd-side-open .rwd-side-drawer{
  transform: translateX(0);
  visibility: visible;
  transition: transform .24s cubic-bezier(.22,.61,.36,1), visibility 0s;
}

/* ======================================================= TABLET AND NARROWER
   Shared page chrome used by every model page: .topbar/.topbar-inner, .brand,
   .back-btn, .wrap, .header, .panel.
   ========================================================================= */
@media (max-width: 1023px){
  body{ overflow-x: hidden; }

  .wrap,
  .shell,
  .container,
  .fc-main{
    padding-left: max(20px, var(--rwd-safe-l));
    padding-right: max(20px, var(--rwd-safe-r));
  }

  .topbar-inner{ flex-wrap: wrap; gap: 10px; }
  .brand .sub{ display: none; }

  /* The drawer button appears from here down, so the bars that already run
     edge to edge on a tablet need room to wrap rather than overflow. */
  .appbar,
  .fc-header{ flex-wrap: wrap; row-gap: 8px; }
  .appbar .actions,
  .fc-actions{ flex-wrap: wrap; }

  /* Two columns before dropping all the way to one. */
  .phases,
  .models-grid,
  .arch-track,
  .perms-grid,
  .rep-grid,
  .grant-grid,
  .fc-kpis{ grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .grid,
  .hero,
  .about-grid,
  .bridge-grid{ grid-template-columns: 1fr; }
  .bridge-arrow{ transform: rotate(90deg); padding: 10px 0; }
}

/* ================================================================== PHONES */
@media (max-width: 767px){

  /* ---------------------------------------------------------- base & text */
  body{
    overflow-x: hidden;
    padding-bottom: var(--rwd-safe-b);
  }
  img, svg, video{ max-width: 100%; }

  /* The landing-page hero illustration deliberately paints outside its frame;
     on a phone that spill is what widens the document, so it is clipped. */
  .hero-visual{ overflow: hidden; }

  /* The hero status rail is position:absolute, which works while it is one
     line in the gap above the headline. On a phone it wraps to three lines
     and, being out of flow, prints straight over the headline. Putting it
     back in the flow lets it push the text down instead. */
  .hero-readout{
    position: static;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 20px;
    font-size: 10px;
  }

  h1{ font-size: clamp(1.5rem, 6.4vw, 2rem); line-height: 1.2; }
  h2{ font-size: clamp(1.2rem, 5.2vw, 1.5rem); line-height: 1.25; }
  h3{ font-size: clamp(1.02rem, 4.4vw, 1.2rem); }
  .page-title{ font-size: 1.6em; }
  .title h1{ font-size: 1.45em; }
  .title p{ font-size: .9em; }

  /* ------------------------------------------------------- shared top bar */
  .topbar,
  .fc-header,
  .appbar{
    padding-top: var(--rwd-safe-t);
  }
  .topbar-inner,
  .fc-header,
  .appbar{
    flex-wrap: nowrap;
    gap: 8px;
    padding-left: max(12px, var(--rwd-safe-l));
    padding-right: max(12px, var(--rwd-safe-r));
    min-height: var(--rwd-bar-h);
  }
  .nav-links{ display: none; }
  .brand{ min-width: 0; overflow: hidden; }
  .brand .name,
  .brand-name{
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 13px;
  }
  .brand .sep,
  .brand .muted,
  .brand .ver,
  .fc-brand .sep,
  .fc-brand .muted,
  .fc-brand .ver{ display: none; }
  .back-btn,
  .fc-back,
  .home-btn{
    min-height: 36px;
    padding: 0 10px;
    font-size: 11px;
    white-space: nowrap;
  }

  /* ------------------------------------------------------- page scaffolds */
  .wrap,
  .shell,
  .container,
  .fc-main{
    width: 100%;
    max-width: 100%;
    padding-left: max(var(--rwd-gutter), var(--rwd-safe-l));
    padding-right: max(var(--rwd-gutter), var(--rwd-safe-r));
  }
  .container{ padding-top: 24px; padding-bottom: 32px; }
  .header,
  .dash-header,
  .fc-meta{
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    padding: 22px 0 18px;
  }
  .fc-meta .meta-r{ width: 100%; }

  /* ----------------------------------------------- every grid goes single */
  .grid,
  .grid2,
  .hero,
  .hero-spec,
  .about-grid,
  .footer-top,
  .phases,
  .models-grid,
  .arch-track,
  .perms-grid,
  .rep-grid,
  .kpi-grid,
  .fc-kpis,
  .fields,
  .fields-2,
  .bridge-grid,
  .board,
  .cards,
  .stats,
  .stat-grid,
  .metrics{
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .view-btns{ grid-template-columns: 1fr 1fr; }
  .mode-grid{ grid-template-columns: repeat(3, 1fr); }
  .cal-grid{ grid-template-columns: repeat(7, 1fr); gap: 4px; font-size: 11px; }
  .tl-wrap{ grid-template-columns: 120px 1fr; }

  /* auto-fit tracks with a 360-440px minimum are wider than a phone, so the
     track itself overflows the page unless it is pinned to one column. */
  .buttons-grid,
  .tool-buttons,
  .charts{ grid-template-columns: 1fr; }

  /* Portal top bar: identity stays visible, the duplicated links are in the
     drawer rather than squeezed into a 360px bar. */
  .nav-back{ display: none; }
  .nav-auth .btn{ display: none; }
  .nav-auth .who{
    max-width: 42vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .brand-mark{ font-size: 12px; white-space: nowrap; }

  /* Plotly figures are written at a fixed size by pio.write_html; make them
     track the card width and let responsive.js re-draw them on rotate. */
  .js-plotly-plot,
  .plotly-graph-div{ width: 100% !important; }

  /* --------------------------------------------------------------- panels */
  .panel,
  .card,
  .section,
  .kpi,
  .col{
    border-radius: 10px;
  }
  .panel-head{
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 14px;
  }
  .panel-head h2{ font-size: 12px; }
  .panel-body,
  .panel > .body{ padding: 14px; }

  /* ---------------------------------------------------------------- forms */
  input, select, textarea{
    font-size: 16px;            /* keeps iOS Safari from zooming on focus */
    max-width: 100%;
  }
  input[type="text"], input[type="number"], input[type="email"],
  input[type="password"], input[type="date"], select, textarea{
    width: 100%;
    min-height: var(--rwd-tap);
  }
  .field,
  .form-row,
  .meta-line{
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    width: 100%;
  }
  .meta-line .lbl{ width: auto; }
  button,
  .btn,
  .btn-link,
  .btn-warm,
  a.btn,
  .tabbtn,
  .seg-btn{
    min-height: 38px;
    padding: 8px 14px;
    -webkit-tap-highlight-color: transparent;
  }
  /* Action rows inside the page body wrap freely onto several lines... */
  .btn-row,
  .panel .actions,
  .wrap .actions{
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  /* ...but a navigation bar must not wrap into a ragged stack. It scrolls
     sideways as one line, with the drawer button pinned so it never scrolls
     out of reach. */
  .topbar-inner{
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }
  .topbar-inner::-webkit-scrollbar{ height: 0; }

  .rwd-navbtn{
    position: sticky;
    right: 0;
    z-index: 2;
    background: rgba(12,14,18,.94);
    box-shadow: -10px 0 10px rgba(12,14,18,.94);
  }
  .rwd-sidebtn{
    position: sticky;
    left: 0;
    z-index: 2;
    background: rgba(12,14,18,.94);
    box-shadow: 10px 0 10px rgba(12,14,18,.94);
  }

  /* The kanban and forecast bars carry a tool group *and* a row of page
     actions. Rather than hiding the action labels — which leaves a row of
     identical blank pills — the actions move to a second, full-width row. */
  .appbar,
  .fc-header{ flex-wrap: wrap; row-gap: 8px; }
  .fc-brand{ flex: 1 1 auto; min-width: 0; flex-wrap: nowrap; overflow: hidden; }
  /* Keep only the mark and the company name; the breadcrumb trail repeats the
     page heading that is a few pixels further down the screen anyway. */
  .fc-brand > span:not(.dot):not(.brand-name){ display: none; }
  .fc-header .rwd-navbtn{ order: 2; position: static; box-shadow: none; }
  .fc-actions{
    order: 3;
    width: 100%;
    flex-wrap: wrap;
    gap: 8px;
  }
  .appbar .title{
    flex: 0 0 auto;
    max-width: 44vw;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .appbar .kb-left{
    flex: 1 1 auto;
    min-width: 0;
    margin-right: 0;
    overflow-x: auto;
  }
  .appbar .kb-left::-webkit-scrollbar{ height: 0; }
  .appbar .rwd-navbtn{ order: 2; position: static; box-shadow: none; }
  .appbar .actions{
    order: 3;
    width: 100%;
    margin-left: 0;
    flex-wrap: wrap;
  }
  .appbar .btn span{ display: inline; }
  .tabs,
  .tabbar{
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
  }
  .tabbar{ padding-bottom: 4px; }
  .tabbtn{ white-space: nowrap; flex: 0 0 auto; }

  /* --------------------------------------------------------------- tables */
  table{ width: 100%; font-size: 12px; }
  table.specs,
  table.parts,
  table.rep-table,
  table.log-table,
  table.sens-table,
  table.spec-table,
  table.quarterly-table{ min-width: max-content; }
  th, td{ padding: 7px 8px; white-space: nowrap; }

  /* --------------------------------------------------------------- modals */
  .modal-overlay,
  .modal-backdrop,
  .drawer-backdrop{ padding: 0; }
  .modal,
  .modal.bom-modal-fs,
  .reports-modal,
  .detail-drawer{
    width: 100vw;
    max-width: 100vw;
    height: 100%;
    max-height: 100%;
    margin: 0;
    border-radius: 0;
    padding-top: var(--rwd-safe-t);
    padding-bottom: var(--rwd-safe-b);
  }
  .modal-header{
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 14px;
  }
  .modal-search{ width: 100%; }

  /* ------------------------------------------------- hover-only affordance
     Touch devices never fire :hover, so anything revealed on hover is made
     permanently visible instead of being unreachable. */
  .img-thumb-wrap .img-remove,
  .item-actions{ opacity: 1; }
}

/* ========================================================= MODULE: ROADMAP
   Phase and item rows pack an editable title, a status pill and an icon
   cluster onto one line. On a phone the title keeps the first row and the
   controls wrap underneath, instead of the title being squeezed to a stub.
   ========================================================================= */
@media (max-width: 767px){
  .phase-head{ flex-wrap: wrap; row-gap: 8px; padding: 12px 14px; }
  .phase-title{ flex: 1 1 auto; min-width: 60%; }
  .phase-count{ order: 3; }
  .phase-actions{ order: 4; margin-left: auto; }

  .item{ flex-wrap: wrap; row-gap: 6px; }
  .item-body{ flex: 1 1 68%; min-width: 0; }
  .tier-wrap{ order: 3; }
  .item-actions{ order: 4; margin-left: auto; }
  .item-detail{ margin-left: 12px; }
  .phase-body{ padding: 6px 10px 12px; }
}

/* ====================================================== MODULE: BREADBOARD
   theme.css lays <body> out as a three-row / two-column grid with a fixed
   280px sidebar. On phones the sidebar leaves the flow and becomes the
   off-canvas drawer so the 3D canvas gets the whole screen.
   ========================================================================= */
@media (max-width: 767px){
  body.rwd-shell-breadboard{
    grid-template-columns: 1fr;
    grid-template-rows: var(--rwd-bar-h) 1fr 24px;
    grid-template-areas: "hdr" "main" "ftr";
    height: calc(var(--rwd-vh) * 100);
  }
  body.rwd-shell-breadboard > header{
    gap: 8px;
    padding: 0 10px;
    padding-top: var(--rwd-safe-t);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* The breadcrumb would eat the whole bar, but the Portal link inside it is
     the way back out of a full-screen 3D view - so only the trailing text is
     dropped and the back button stays put. */
  body.rwd-shell-breadboard > header .brand{
    flex: 0 0 auto;
    min-width: 0;
    gap: 0;
  }
  body.rwd-shell-breadboard > header .brand > span{ display: none; }
  body.rwd-shell-breadboard > header .brand .home-btn{
    display: inline-flex;
    margin-right: 4px;
  }
  body.rwd-shell-breadboard > header .actions{
    flex-wrap: nowrap;
    gap: 6px;
  }
  body.rwd-shell-breadboard > header .actions > .grp button{
    min-width: 42px;
    min-height: 32px;
  }
  body.rwd-shell-breadboard > footer{
    font-size: 10px;
    overflow: hidden;
    white-space: nowrap;
  }
  /* BOM / specs grids keep their column structure but scroll horizontally. */
  .bom-section{ overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .bom-grid{ min-width: 980px; }
}

/* ==================================================== MODULE: 3D POINTING
   .layout is position:fixed with a 340px sidebar; the sidebar becomes the
   off-canvas drawer and the canvas takes the full remaining viewport.
   ========================================================================= */
@media (max-width: 767px){
  body.rwd-shell-pointing3d .layout{
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
    top: var(--rwd-bar-h);
  }
  body.rwd-shell-pointing3d .sidebar{
    max-height: none;
    border-right: none;
    border-bottom: none;
  }
  body.rwd-shell-pointing3d .canvas-wrap{ width: 100%; }

  /* HUD overlays are absolutely positioned at desktop sizes; on a phone they
     are pulled inside the viewport and allowed to scroll rather than being
     clipped by the canvas edge. */
  .timeline{
    top: 8px;
    left: 8px;
    right: 8px;
    transform: none;
    max-width: calc(100% - 16px);
    justify-content: flex-start;
    gap: 10px;
    padding: 6px 10px;
    font-size: 9px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .timeline::-webkit-scrollbar{ height: 0; }
  .timeline .tl-step{ flex: 0 0 auto; }

  /* The phase strip now spans the top, so the corner read-outs move below it.
     The right-hand one is a static build/units caption — dropped on a phone
     where screen space is the scarcer resource. */
  .hud-tl{ top: 40px; left: 10px; }
  .hud-tr{ display: none; }

  /* min-width:420px is wider than the screen; the banner is re-anchored to
     the viewport edges instead of being centred on a width it cannot have. */
  .phase-narrator{
    top: 72px;
    left: 8px;
    right: 8px;
    transform: none;
    min-width: 0;
    max-width: none;
    padding: 10px 14px;
  }

  .telem-panel{
    width: min(78vw, 272px);
    right: 8px;
    top: 72px;
  }
  .telem-panel .telem-body{
    max-height: 44vh;
    overflow-y: auto;
  }
  .telem-panel.rwd-collapsed .telem-body{ display: none; }
  .telem-panel .telem-drag-hint{ display: none; }

  .scan-mini{ width: 108px; height: 108px; }
  .readout{ font-size: 10px; max-width: 58vw; }
  .help{ display: none; }
}

/* ========================================================== MODULE: KANBAN
   The board is a horizontal row of columns on desktop. On phones each column
   becomes a full-width stacked section so cards stay readable.
   ========================================================================= */
@media (max-width: 767px){
  .board{
    grid-template-columns: 1fr;
    gap: 12px;
    overflow: visible;
  }
  .col{ max-height: none; }
  .charts{ grid-template-columns: 1fr; }
  /* The board no longer scrolls horizontally, so its columns size to content. */
  .page{ width: 100%; padding: 12px; }
}

/* ======================================================== MODULE: FORECAST
   The quarterly table is intentionally wide - it scrolls inside its own box
   instead of stretching the page.
   ========================================================================= */
@media (max-width: 767px){
  .period-toggle{ width: 100%; display: flex; }
  .period-toggle button{ flex: 1 1 0; min-height: 38px; font-size: 11px; }
  .kpi-value{ font-size: 1.4rem; }

  /* Org-context strip: the right-hand field column drops below the title. */
  .meta-r{ min-width: 0; width: 100%; }
  .meta-line{ grid-template-columns: 1fr; gap: 4px; }
  .meta-line .lbl{ text-align: left; }

  /* Label/value pairs read better stacked than squeezed into a 100px gutter. */
  .grant-grid{ grid-template-columns: 1fr; }
  .pw-row,
  .tr-row{ grid-template-columns: 1fr; gap: 2px; }

  /* The personnel / material / other tables keep their column structure and
     scroll inside their own box rather than stretching the page. */
  .fc-table{ overflow-x: auto; -webkit-overflow-scrolling: touch; }
  #tbl-personnel .thead, #tbl-personnel .trow,
  #tbl-material .thead,  #tbl-material .trow,
  #tbl-other .thead,     #tbl-other .trow{ min-width: 900px; }
  .quarterly-table{ min-width: 760px; }
}

/* ================================================ MODULE: ENGINEERING PORTAL
   The dashboard is the first thing seen after signing in. On a desktop its
   title block is a pleasant 600px of breathing room; on a phone that is a
   screen and a half of branding before a single tool is reachable, and the
   whole page ran past 3000px.

   So on phones it becomes a launcher: a compact identity line, then the
   modules. Nothing is removed that carries information - the eyebrow and
   tagline both restate the title, and each section's description repeats
   what its buttons already say.
   ========================================================================= */
@media (max-width: 767px){
  .dash-header{
    padding: 18px 0 14px;
    gap: 6px;
  }
  .dash-header .eyebrow,
  .dash-header .tagline{ display: none; }
  .dash-header .logo{
    font-size: 1.7rem;
    letter-spacing: .12em;
    margin-bottom: 4px;
  }
  .dash-header .subtitle{
    font-size: 12px;
    letter-spacing: .04em;
    margin-top: 0;
  }

  .buttons-grid{ gap: 14px; padding-bottom: 28px; }

  .section-card{
    padding: 16px 14px;
    border-radius: 10px;
  }
  .section-header{
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
    padding-bottom: 10px;
  }
  /* Icon beside the title rather than stacked above it. */
  .section-icon{
    display: block;
    font-size: 1.3em;
    margin-bottom: 0;
  }
  .section-title-card{ font-size: 16px; margin-bottom: 0; }
  .section-desc{ display: none; }

  .tool-buttons{ gap: 8px; }
  .tool-btn{
    padding: 13px 14px;
    font-size: 14px;
    border-radius: 8px;
  }

  .site-footer{ padding: 18px 0 24px; }
  .footer-bot{
    display: grid;
    gap: 6px;
    font-size: 10px;
    text-align: center;
  }
}

/* ============================================= MODULE: AUTH / ADMIN PAGES */
@media (max-width: 767px){
  .moon{ width: 320px; height: 320px; top: -8%; right: -16%; }
  .logo{ font-size: 1.7em; }
  .tagline{ font-size: .82em; margin-bottom: 26px; }
  .user-head{ flex-direction: column; align-items: stretch; gap: 10px; }
  .user-head .actions{ justify-content: flex-start; }
  .auth-card{ padding: 22px 18px; }
}

/* ================================================= LANDSCAPE PHONES (short)
   Trim vertical chrome when there are only a few hundred pixels of height.
   ========================================================================= */
@media (max-height: 460px) and (orientation: landscape){
  .topbar,
  .appbar,
  .fc-header{ min-height: 44px; }
  .header,
  .dash-header{ padding: 12px 0 10px; }
  .rwd-drawer{ padding-top: 10px; }
}

/* Users who prefer reduced motion get no drawer slide. */
@media (prefers-reduced-motion: reduce){
  .rwd-drawer,
  .rwd-side-drawer,
  .rwd-backdrop{ transition: none; }
}
