/* ============================================================================
   KIB portal — the ONE design system.
   Implements /opt/bsq/DESIGN_SYSTEM.md exactly. Served at /assets/kib.css and
   loaded by every module (the portal login, Branch Pulse, anything added
   later) so the whole product looks like one thing.

   Module-specific rules belong in that module's own stylesheet, never here.
   ========================================================================== */

/* Inter, self-hosted: the app's CSP is default-src 'self', so a Google Fonts
   link would be blocked outright and every screen would silently fall back. */
@font-face{
  font-family:'Inter var';
  src:url('/assets/fonts/InterVariable.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:swap;
}

:root{
  /* brand */
  --navy:#164080; --navy-deep:#0E2B57; --navy-mid:#2D5FA8;
  --mint:#32C1A4; --mint-deep:#1E9E85;
  --ink:#12233D; --porcelain:#F4F7FA; --grey:#6B7A90; --card-border:#E6ECF3;

  /* rating semantics — the same three everywhere, SQ and Branch Pulse alike */
  --good:#1E9E85;   /* Excellent / Pass / Green — On Track     */
  --warn:#D08A12;   /* Normal / Amber / Needs Attention        */
  --bad:#C8404A;    /* Bad / Fail / Red — Critical             */
  --na:#94A3B8;     /* N/A / neutral                           */

  --radius:16px;
  --shadow:0 8px 30px -12px rgba(18,35,61,.3);
  --phone:430px;    /* on desktop the app stays a phone-width column */
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:'Inter var',Inter,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  background:var(--porcelain); color:var(--ink);
  -webkit-font-smoothing:antialiased; font-size:15px; line-height:1.5;
  letter-spacing:-0.01em;
}
.hidden{display:none!important}

/* Arabic sits beneath its English label, smaller and grey. */
.ar{direction:rtl; font-size:.82em; color:var(--grey); display:block; margin-top:2px; letter-spacing:0}

/* Grey-on-white is the default, but Arabic also appears on the navy hero and
   inside filled buttons, where grey has no contrast. There it borrows the
   parent's own colour instead. Both rules are additive: no button or hero
   carried a .ar span before Branch Pulse's start flow, so nothing that
   already shipped in Service Quality or the portal changes. */
.btn .ar{color:currentColor; opacity:.72; font-size:12.5px; margin-top:1px}

/* ---------- question 15: the visit list ---------------------------------- */
/* One card per visit, so a phone shows customer, date and outcome stacked
   without the row ever scrolling sideways. All new class names — nothing
   here can reach a Service Quality or portal screen. */
.visits{display:flex; flex-direction:column; gap:10px; margin:10px 0}
.visit{background:var(--porcelain); border:1px solid var(--card-border);
  border-radius:12px; padding:10px; display:flex; flex-direction:column; gap:8px}
.visit-head{display:flex; align-items:center; justify-content:space-between}
.visit-n{display:inline-flex; align-items:center; justify-content:center;
  min-width:22px; height:22px; border-radius:999px; background:var(--navy);
  color:#fff; font-size:12px; font-weight:650; padding:0 6px; flex:none}
.visit-del{border:0; background:transparent; color:var(--grey); cursor:pointer;
  font-size:15px; line-height:1; padding:6px; border-radius:8px; min-height:32px}
.visit-del:active{background:rgba(0,0,0,.06)}
.visit-none{display:flex; align-items:center; gap:8px; margin-top:10px;
  font-size:13.5px; cursor:pointer}
.visit-none input{width:18px; height:18px; margin:0; flex:none; accent-color:var(--mint-deep)}
.visit-none .ar{display:inline-block; margin:0 0 0 6px}
.btn:has(.ar){flex-direction:column; gap:1px}
.hero .ar{color:#fff; opacity:.66}
.hero h1 .ar{font-size:15px; font-weight:600; margin-top:4px}
.hero .who .ar{font-size:11.5px; margin-top:1px}

/* ---------- shell: a centred phone-width column, on every screen size ----- */
.app{max-width:var(--phone); margin:0 auto; min-height:100vh; position:relative}
main{padding:0 16px 120px}          /* room for the floating tab bar */

/* ---------- the signature element: the navy hero band -------------------- */
.hero{
  position:relative; overflow:hidden;
  background:linear-gradient(135deg,var(--navy-deep),var(--navy),var(--navy-mid));
  border-radius:0 0 30px 30px;
  padding:26px 20px 46px;           /* deep bottom: content rises over it */
  color:#fff;
}
/* the soft mint glow that gives the band depth */
.hero::after{
  content:''; position:absolute; top:-70px; right:-50px;
  width:210px; height:210px; border-radius:50%;
  background:rgba(50,193,164,.30); filter:blur(46px); pointer-events:none;
}
.hero > *{position:relative; z-index:1}
.eyebrow{
  font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.12em;
  color:var(--mint); margin-bottom:6px;
}
.hero h1{font-size:26px; font-weight:700; letter-spacing:-0.02em; margin:0; line-height:1.15}
.hero .who{font-size:12.5px; color:rgba(255,255,255,.72); margin-top:5px}
.hero-row{display:flex; align-items:flex-start; gap:12px}
.hero-row .spacer{flex:1}

/* glass stat tiles, only inside the hero */
.glass-tiles{display:flex; gap:8px; margin-top:16px}
.glass{
  flex:1; background:rgba(255,255,255,.15); border:1px solid rgba(255,255,255,.22);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  border-radius:13px; padding:10px 11px;
}
.glass .v{font-size:20px; font-weight:700; letter-spacing:-0.02em; line-height:1.1}
.glass .l{font-size:9.5px; text-transform:uppercase; letter-spacing:.12em; color:rgba(255,255,255,.7); margin-top:3px}

/* THE defining layout move: the first card overlaps the band's lower edge. */
.rise{margin-top:-24px; position:relative; z-index:2}

.iconbtn{
  background:rgba(255,255,255,.16); border:1px solid rgba(255,255,255,.2); color:#fff;
  width:38px; height:38px; min-width:38px; border-radius:12px; font-size:15px;
  cursor:pointer; display:flex; align-items:center; justify-content:center;
  transition:transform .12s;
}
.iconbtn:active{transform:scale(.92)}

/* ---------- cards -------------------------------------------------------- */
.card{
  background:#fff; border:1px solid var(--card-border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:18px; margin-bottom:10px;
}
.card h2{font-size:19px; font-weight:650; letter-spacing:-0.02em; margin:0 0 4px}
.card p.hint{color:var(--grey); font-size:12.5px; margin:0 0 12px}
.card-tap{cursor:pointer; transition:transform .14s cubic-bezier(.2,.9,.3,1.2), box-shadow .14s}
.card-tap:active{transform:scale(.985); box-shadow:0 4px 16px -10px rgba(18,35,61,.34)}

/* the small uppercase label used above fields and beside values */
.label{font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.12em; color:var(--grey)}

/* ---------- buttons ------------------------------------------------------ */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  border:0; border-radius:14px; padding:14px 18px; font-size:15px; font-weight:650;
  font-family:inherit; cursor:pointer; width:100%; min-height:48px;
  letter-spacing:-0.01em; transition:transform .12s cubic-bezier(.2,.9,.3,1.3);
  text-decoration:none;
}
.btn:active{transform:scale(.96)}
.btn-primary{background:var(--navy); color:#fff}
.btn-mint{background:var(--mint); color:#06342C}
.btn-quiet{background:rgba(0,0,0,.05); color:var(--ink)}
.btn-danger{background:var(--bad); color:#fff}
.btn:disabled{opacity:.45; cursor:not-allowed; transform:none}
.btn-row{display:flex; gap:10px}
.btn-pill{border-radius:999px; width:auto; padding:10px 16px; font-size:13.5px; min-height:44px}

/* ---------- floating pill tab bar ---------------------------------------- */
.tabbar{
  position:fixed; left:50%; transform:translateX(-50%);
  bottom:calc(14px + env(safe-area-inset-bottom));
  width:calc(100% - 28px); max-width:calc(var(--phone) - 28px);
  background:#fff; border:1px solid var(--card-border); border-radius:999px;
  box-shadow:0 10px 34px -10px rgba(18,35,61,.34);
  display:flex; padding:7px; z-index:40;
}
.tab{
  flex:1; border:0; background:none; font-family:inherit; cursor:pointer;
  padding:7px 2px; border-radius:999px; color:var(--grey);
  display:flex; flex-direction:column; align-items:center; gap:3px;
  min-height:44px; justify-content:center; transition:color .15s, background .15s;
}
.tab .ti{font-size:16px; line-height:1}
.tab .tl{font-size:10px; font-weight:600; letter-spacing:.02em}
.tab.on{color:var(--navy); background:rgba(22,64,128,.07)}
.tab.on .ti{color:var(--mint-deep)}
.tab:active{transform:scale(.94)}

/* full-screen flows (an open form, a report view) hide the tab bar */
.fullscreen .tabbar{display:none}
.fullscreen main{padding-bottom:104px}

/* ---------- forms -------------------------------------------------------- */
.field{margin-bottom:20px}
.field > label.q{display:block; font-weight:650; font-size:14.5px; margin-bottom:8px; letter-spacing:-0.01em}
.field .num{
  display:inline-block; min-width:20px; color:var(--mint-deep); font-weight:700;
  margin-right:7px; font-variant-numeric:tabular-nums;
}
.req{color:var(--bad); margin-left:3px}
input[type=text],input[type=number],input[type=date],input[type=password],select,textarea{
  width:100%; padding:13px 14px; border:1px solid var(--card-border); border-radius:13px;
  font-size:16px; font-family:inherit; background:#fff; color:var(--ink); min-height:48px;
}
input:focus,select:focus,textarea:focus{outline:0; border-color:var(--mint); box-shadow:0 0 0 3px rgba(50,193,164,.16)}
input:disabled{background:#F7F9FC; color:var(--grey)}
textarea{min-height:88px; resize:vertical}
.counter{font-size:11px; color:var(--grey); text-align:right; margin-top:5px}

/* choice rows */
.choices{display:flex; flex-direction:column; gap:8px}
.choice{
  border:1px solid var(--card-border); border-radius:13px; padding:12px 14px; cursor:pointer;
  background:#fff; display:flex; align-items:center; gap:11px; min-height:48px;
  transition:border-color .13s, background .13s, transform .12s;
}
.choice:active{transform:scale(.985)}
.choice input{margin:0; accent-color:var(--navy); width:19px; height:19px; flex:none}
.choice .txt{flex:1}
.choice .en{font-size:14.5px}
.choice.on{border-color:var(--navy); background:rgba(22,64,128,.045)}
.choice.g.on{border-color:var(--good); background:rgba(30,158,133,.09)}
.choice.a.on{border-color:var(--warn); background:rgba(208,138,18,.09)}
.choice.r.on{border-color:var(--bad);  background:rgba(200,64,74,.09)}

/* the three-up rating row: Excellent / Normal / Bad */
.ratings{display:flex; gap:8px}
.rating{
  flex:1; border:1px solid var(--card-border); background:rgba(0,0,0,.03);
  border-radius:13px; padding:11px 6px; text-align:center; cursor:pointer;
  font-size:12.5px; font-weight:650; color:var(--grey); min-height:48px;
  font-family:inherit; transition:transform .13s cubic-bezier(.2,.9,.3,1.4), background .13s, color .13s;
}
.rating:active{transform:scale(.94)}
.rating.on{color:#fff; border-color:transparent}
.rating.on.g{background:var(--good)} .rating.on.a{background:var(--warn)}
.rating.on.r{background:var(--bad)}  .rating.on.n{background:var(--na)}
@keyframes checkspring{0%{transform:scale(0);opacity:0}60%{transform:scale(1.25)}100%{transform:scale(1);opacity:1}}
.rating .ck{display:inline-block; margin-left:4px; animation:checkspring .32s cubic-bezier(.2,.9,.3,1.5) both}

/* validation */
.err{color:var(--bad); font-size:12.5px; margin-top:6px}
.field.bad input,.field.bad select,.field.bad textarea,.field.bad .choice{border-color:var(--bad)}
.errbox{background:rgba(200,64,74,.07); border:1px solid rgba(200,64,74,.28); border-radius:13px; padding:14px; margin-bottom:12px}
.errbox h3{margin:0 0 6px; font-size:13.5px; color:var(--bad)}
.errbox ul{margin:0; padding-left:18px; font-size:12.5px; color:#8E2F37}

/* ---------- progress ----------------------------------------------------- */
.progress{padding:14px 16px 0}
.bar{height:5px; background:rgba(22,64,128,.12); border-radius:99px; overflow:hidden}
.bar > i{display:block; height:100%; background:var(--mint); border-radius:99px; transition:width .3s cubic-bezier(.3,.8,.4,1)}
.steplabel{font-size:11px; text-transform:uppercase; letter-spacing:.12em; color:var(--grey); margin-top:7px; display:flex; justify-content:space-between}

/* sticky action bar for staged flows (sits where the tab bar would be) */
.actionbar{
  position:fixed; bottom:0; left:50%; transform:translateX(-50%);
  width:100%; max-width:var(--phone); background:rgba(255,255,255,.94);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-top:1px solid var(--card-border);
  padding:12px 16px calc(12px + env(safe-area-inset-bottom));
  display:flex; gap:10px; z-index:41;
}

/* ---------- list rows ---------------------------------------------------- */
.row{display:flex; align-items:center; gap:12px; padding:13px 0; border-bottom:1px solid var(--card-border)}
.row:last-child{border-bottom:0}
.row.tap{cursor:pointer; transition:transform .12s}
.row.tap:active{transform:scale(.99)}
.row .grow{flex:1; min-width:0}
.row .t{font-weight:650; font-size:14.5px; letter-spacing:-0.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.row .s{font-size:12px; color:var(--grey); margin-top:2px}
.dot{width:9px; height:9px; border-radius:99px; flex:none}
.dot.g{background:var(--good)} .dot.a{background:var(--warn)}
.dot.r{background:var(--bad)}  .dot.n{background:var(--na)}
.score{font-weight:700; font-size:19px; color:var(--navy); letter-spacing:-0.02em; font-variant-numeric:tabular-nums}

.pill{display:inline-block; padding:4px 10px; border-radius:999px; font-size:11px; font-weight:650; letter-spacing:.01em}
.pill.g{background:rgba(30,158,133,.13); color:var(--mint-deep)}
.pill.a{background:rgba(208,138,18,.14); color:#9A660D}
.pill.r{background:rgba(200,64,74,.12); color:var(--bad)}
.pill.n{background:rgba(107,122,144,.13); color:var(--grey)}

/* ---------- stat tiles on porcelain -------------------------------------- */
.tiles{display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-bottom:10px}
.tile{background:#fff; border:1px solid var(--card-border); border-radius:var(--radius); padding:15px; box-shadow:var(--shadow)}
.tile .v{font-size:32px; font-weight:700; color:var(--navy); letter-spacing:-0.03em; line-height:1; font-variant-numeric:tabular-nums}
.tile .l{font-size:10.5px; text-transform:uppercase; letter-spacing:.12em; color:var(--grey); margin-top:6px}

/* ---------- the score reveal (the one dramatic moment) ------------------- */
.result{text-align:center; padding:12px 8px 20px}
.ring{width:172px; height:172px; margin:0 auto 18px; position:relative}
.ring svg{transform:rotate(-90deg)}
.ring circle.track{stroke:rgba(22,64,128,.10)}
/* the ring draws itself; the number counts up in script */
.ring circle.val{transition:stroke-dashoffset 1.15s cubic-bezier(.25,.8,.3,1)}
.ring .v{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  flex-direction:column; font-size:44px; font-weight:700; color:var(--navy);
  letter-spacing:-0.03em; font-variant-numeric:tabular-nums;
}
.ring .v small{font-size:10px; font-weight:650; color:var(--grey); letter-spacing:.12em; text-transform:uppercase; margin-top:2px}
@keyframes badgein{0%{transform:scale(0) translateY(8px);opacity:0}55%{transform:scale(1.18) translateY(0)}100%{transform:scale(1);opacity:1}}
.badge-in{animation:badgein .5s cubic-bezier(.2,.9,.3,1.5) both}

.bars .b{margin-bottom:11px}
.bars .b .lab{display:flex; justify-content:space-between; font-size:12.5px; margin-bottom:4px}
.bars .b .lab span:last-child{font-weight:650; font-variant-numeric:tabular-nums}
.bars .b .track{height:7px; background:rgba(22,64,128,.09); border-radius:99px; overflow:hidden}
.bars .b .track > i{display:block; height:100%; background:var(--navy); border-radius:99px; transition:width .7s cubic-bezier(.3,.8,.4,1)}

/* ---------- empty states: a small drawing and one line ------------------- */
.empty{text-align:center; color:var(--grey); padding:30px 16px; font-size:13.5px}
.empty svg{margin-bottom:10px; opacity:.85}

.spinner{
  width:24px; height:24px; border:2.5px solid rgba(22,64,128,.14); border-top-color:var(--navy);
  border-radius:99px; animation:spin .7s linear infinite; margin:34px auto;
}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- login -------------------------------------------------------- */
/* public-portal/portal.js is the ONLY thing that renders .login, so every rule
   scoped under it belongs to the sign-in screen alone. Nothing here can reach
   a Service Quality or Branch Pulse screen. */
.login{
  min-height:100vh; display:flex; align-items:center; justify-content:center; padding:22px;
  background:linear-gradient(135deg,var(--navy-deep),var(--navy),var(--navy-mid));
  position:relative; overflow:hidden;
}
/* Two glows, not one. The mint top-right is the brand note; the cooler blue
   bottom-left stops the lower half of the screen reading as flat navy. */
.login::before,.login::after{content:''; position:absolute; border-radius:50%; pointer-events:none}
.login::after{top:-120px; right:-90px; width:320px; height:320px;
  background:rgba(50,193,164,.28); filter:blur(70px)}
.login::before{bottom:-150px; left:-110px; width:360px; height:360px;
  background:rgba(45,95,168,.45); filter:blur(80px)}

.login .box{
  background:#fff; border-radius:22px; padding:30px 28px; width:100%; max-width:var(--phone);
  box-shadow:0 24px 60px -18px rgba(14,43,87,.55); position:relative; z-index:1;
  animation:loginIn .45s cubic-bezier(.2,.9,.3,1.05) both;
}
@keyframes loginIn{from{opacity:0; transform:translateY(14px) scale(.985)} to{opacity:1; transform:none}}

/* The same mint check as the installed app icon, so the screen someone signs
   in on and the icon they tapped are visibly one product. */
.login .mark{
  width:56px; height:56px; border-radius:17px; margin-bottom:16px;
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg,var(--navy-deep),var(--navy-mid));
  box-shadow:0 10px 22px -10px rgba(14,43,87,.65);
}
.login .mark svg{width:30px; height:30px}

.login .eyebrow{color:var(--mint-deep)}
.login h1{margin:0 0 4px; font-size:27px; font-weight:700; letter-spacing:-0.02em; color:var(--navy)}
.login .sub{color:var(--grey); font-size:13px; line-height:1.45; margin-bottom:24px}

/* A password field nobody can read is a support call, and these passwords are
   long and punctuated. */
.login .pw{position:relative}
.login .pw input{padding-right:54px}
.login .peek{
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  border:0; background:transparent; cursor:pointer; color:var(--grey);
  padding:10px; border-radius:10px; min-height:40px; display:flex; align-items:center;
}
.login .peek:active{background:rgba(0,0,0,.05)}
.login .peek svg{width:20px; height:20px}

/* Passwords here are case-sensitive and mixed-case; say so before the attempt
   fails rather than after. */
.login .caps{
  display:none; margin-top:9px; font-size:12px; color:#8A6100; line-height:1.4;
  background:rgba(208,138,18,.10); border:1px solid rgba(208,138,18,.30);
  border-radius:10px; padding:7px 10px;
}
.login .caps.on{display:block}

/* Compact alert: the old .errbox heading weighed more than its own message. */
.login .alert{
  display:flex; gap:9px; align-items:flex-start; font-size:13px; color:#8E2F37;
  background:rgba(200,64,74,.07); border:1px solid rgba(200,64,74,.28);
  border-radius:13px; padding:11px 13px; margin-bottom:16px;
  animation:alertShake .3s ease both;
}
.login .alert svg{width:17px; height:17px; flex:none; margin-top:1px; color:var(--bad)}
@keyframes alertShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}

.login .foot{
  margin-top:22px; padding-top:16px; border-top:1px solid var(--card-border);
  font-size:11.5px; color:var(--grey); text-align:center; line-height:1.6;
}

/* Section 4 of DESIGN_SYSTEM.md: motion is quiet and functional. Honour the
   system setting and drop it entirely. */
@media (prefers-reduced-motion: reduce){
  .login .box,.login .alert{animation:none}
}

.filters{display:flex; gap:8px; overflow-x:auto; padding:2px 0 10px}
.filters select{width:auto; flex:none; font-size:13px; padding:9px 12px; min-height:44px}

/* ---------- pickers: a designed replacement for <select> ----------------- *
   A native <select> renders its list with the OS, which ignores this design
   system entirely and truncates or overflows long branch names. The trigger
   below looks exactly like a .field input; tapping it opens a bottom sheet we
   control, so the list follows the system and always fits.                   */
.picker{
  width:100%; display:flex; align-items:center; gap:10px; text-align:left;
  padding:13px 14px; border:1px solid var(--card-border); border-radius:13px;
  background:#fff; color:var(--ink); font-family:inherit; font-size:15px;
  min-height:48px; cursor:pointer; transition:border-color .13s, transform .12s;
}
.picker:active{transform:scale(.99)}
.picker:focus-visible{outline:0; border-color:var(--mint); box-shadow:0 0 0 3px rgba(50,193,164,.16)}
.picker .pv{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.picker .pv.ph{color:var(--grey)}
.picker .pc{flex:none; color:var(--na); font-size:11px; transition:transform .18s}
.picker[aria-expanded="true"] .pc{transform:rotate(180deg)}
.picker.on{border-color:var(--navy)}

/* filter row: compact pill triggers that scroll rather than squash */
.filters{display:flex; gap:8px; overflow-x:auto; padding:2px 2px 12px; scrollbar-width:none}
.filters::-webkit-scrollbar{display:none}
.filters .picker{
  width:auto; flex:none; max-width:60vw; border-radius:999px;
  padding:9px 14px; min-height:44px; font-size:13px; font-weight:600;
  box-shadow:0 2px 10px -6px rgba(18,35,61,.4);
}
.filters .picker.set{background:var(--navy); border-color:var(--navy); color:#fff}
.filters .picker.set .pc{color:rgba(255,255,255,.7)}

/* the sheet itself */
.sheet-back{
  position:fixed; inset:0; background:rgba(14,43,87,.44); z-index:60;
  animation:fadein .18s ease both; -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
}
@keyframes fadein{from{opacity:0}to{opacity:1}}
@keyframes sheetup{from{transform:translateY(100%)}to{transform:translateY(0)}}
.sheet{
  position:fixed; left:50%; bottom:0; transform:translateX(-50%);
  width:100%; max-width:var(--phone); background:#fff; z-index:61;
  border-radius:22px 22px 0 0; box-shadow:0 -12px 40px -12px rgba(14,43,87,.45);
  animation:sheetup .26s cubic-bezier(.25,.9,.3,1) both;
  display:flex; flex-direction:column; max-height:78vh;
  padding-bottom:env(safe-area-inset-bottom);
}
.sheet .grab{width:38px; height:4px; border-radius:99px; background:var(--card-border); margin:10px auto 4px}
.sheet header{padding:8px 18px 12px; border-bottom:1px solid var(--card-border)}
.sheet header h3{margin:0; font-size:17px; font-weight:650; letter-spacing:-0.02em}
.sheet .search{margin:12px 18px 0}
.sheet .search input{min-height:46px; font-size:15px}
.sheet-list{overflow-y:auto; -webkit-overflow-scrolling:touch; padding:8px 10px 14px}
.sheet-item{
  display:flex; align-items:center; gap:12px; width:100%; text-align:left;
  padding:13px 14px; border:0; background:none; border-radius:13px; cursor:pointer;
  font-family:inherit; color:var(--ink); min-height:48px; font-size:15px;
}
.sheet-item:active{background:rgba(22,64,128,.06)}
.sheet-item .si{flex:1; min-width:0}
.sheet-item .si .en{display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sheet-item .si .sub{font-size:12px; color:var(--grey); margin-top:1px}
.sheet-item .tick{flex:none; color:var(--mint-deep); font-size:15px; opacity:0}
.sheet-item.on{background:rgba(22,64,128,.055); font-weight:650}
.sheet-item.on .tick{opacity:1}
.sheet .none{padding:26px 18px; text-align:center; color:var(--grey); font-size:13.5px}

/* ---------- module chooser (portal) -------------------------------------- */
.modules{display:flex; flex-direction:column; gap:10px}
.module{
  display:flex; align-items:center; gap:14px; text-decoration:none; color:inherit;
  background:#fff; border:1px solid var(--card-border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:18px; border-left:4px solid var(--navy);
  transition:transform .14s cubic-bezier(.2,.9,.3,1.2);
}
.module:active{transform:scale(.985)}
.module.is-pulse{border-left-color:var(--mint)}
.module .ic{
  width:46px; height:46px; border-radius:14px; background:rgba(22,64,128,.07); flex:none;
  display:flex; align-items:center; justify-content:center; font-size:20px; color:var(--navy);
}
.module.is-pulse .ic{background:rgba(50,193,164,.14); color:var(--mint-deep)}
.module .n{font-weight:700; font-size:15.5px; color:var(--navy); letter-spacing:-0.01em}
.module .d{font-size:12.5px; color:var(--grey); margin-top:2px}
.module .go{margin-left:auto; color:var(--na); font-size:22px}
.notice{background:rgba(208,138,18,.09); border:1px solid rgba(208,138,18,.3); border-radius:13px; padding:14px; font-size:13px}
.notice b{color:#9A660D}

/* respect a user who does not want motion */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important}
}

/* ============================================================================
   RESPONSIVE LAYER — phone, iPad, desktop
   ----------------------------------------------------------------------------
   The original system pinned every shell to --phone (430px) at every screen
   size, on purpose: "a field tool used on phones, and the desktop view mirrors
   it." That was reviewed and changed — the product is opened on iPads at
   branches and on desktops in the office, and a 430px ribbon in the middle of
   a 1024 or 1920 screen wasted almost all of it.

   The rule now: ONE layout that adapts, not three designs. Everything below
   only changes measurements — widths, columns, spacing, pointer affordances.
   No colour, no radius, no shadow, no component structure is touched, so the
   hero band, the cards, the pill tab bar and the rating semantics stay exactly
   as DESIGN_SYSTEM.md specifies them.

   --phone stays the phone baseline. --shell is what the shell actually uses.
   ========================================================================== */

:root{ --shell:var(--phone); }

.app,
.actionbar          { max-width:var(--shell); }
.tabbar             { max-width:calc(var(--shell) - 28px); }

/* Dynamic viewport height: on iOS the browser chrome makes 100vh taller than
   the visible area, which pushed the tab bar under the Safari toolbar. */
.app  { min-height:100vh; min-height:100dvh; }
.login{ min-height:100vh; min-height:100dvh; }

/* ---------------------------------------------------------------- iPad ----
   Width AND height, deliberately. Width alone at 768px missed the iPad mini
   in portrait (744pt), and caught a big phone in landscape (an iPhone 15 Pro
   Max is 932pt wide) — which would hand a 430pt-tall viewport the roomy
   tablet hero and leave no space for content. 700x600 covers every iPad in
   both orientations and no phone in either. Touch targets are unchanged:
   a finger on a tablet is the same size as a finger on a phone.            */
@media (min-width:700px) and (min-height:600px){
  :root{ --shell:720px; }

  main{ padding:0 24px 132px; }

  .hero{ padding:34px 28px 54px; border-radius:0 0 36px 36px; }
  .hero h1{ font-size:31px; }
  .hero .who{ font-size:13.5px; }
  .glass-tiles{ gap:12px; margin-top:20px; }
  .glass{ padding:13px 15px; }
  .glass .v{ font-size:23px; }

  .card{ padding:22px; margin-bottom:12px; border-radius:18px; }
  .card h2{ font-size:20px; }

  /* auto-fit, not a fixed count: these blocks hold 4 tiles (Insights, Pulse)
     or 2 (a branch view). A fixed 3- or 4-track grid would strand an orphan on
     a second row, or leave empty columns and squeeze the tiles that are there. */
  .tiles{ grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:12px; }

  /* A filter pill capped at 60vw is 614px on an iPad; that is a whole row. */
  .filters .picker{ max-width:280px; }

  .login .box{ max-width:460px; padding:32px; }

  /* Long-form controls stop growing before they become unusable to scan. */
  .field textarea{ max-width:none; }
}

/* ------------------------------------------------------------- desktop ----
   The shell widens again but stays a readable measure. A form field stretched
   across 1920px is worse than one at 880px, not better — the limit here is
   legibility, not available pixels.                                         */
@media (min-width:1180px){
  :root{ --shell:880px; }

  main{ padding:0 32px 140px; }

  .hero{ padding:40px 34px 60px; }
  .hero h1{ font-size:34px; }

  .card{ padding:26px; }

  .tiles{ grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); }

  .btn-row{ gap:12px; }
}

/* ------------------------------------------------- pointer, not finger ----
   Everything in the base system reacts to :active only, which is correct for
   touch and leaves a mouse with no feedback at all. These apply only where a
   real hover-capable pointer exists, so nothing changes on a tablet or phone
   (and no sticky-hover on touch devices that report coarse pointers).       */
@media (hover:hover) and (pointer:fine){
  .card-tap:hover      { transform:translateY(-2px);
                         box-shadow:0 14px 36px -14px rgba(18,35,61,.42); }
  .row.tap:hover       { background:rgba(22,64,128,.035); }
  .btn:hover:not(:disabled){ filter:brightness(1.06); }
  .btn-quiet:hover     { background:rgba(0,0,0,.08); }
  .choice:hover        { border-color:var(--navy-mid); }
  .rating:hover:not(.on){ background:rgba(0,0,0,.06); }
  .picker:hover        { border-color:var(--navy-mid); }
  .sheet-item:hover    { background:rgba(22,64,128,.06); }
  .module:hover        { transform:translateY(-2px);
                         box-shadow:0 14px 36px -14px rgba(18,35,61,.42); }
  .tab:hover           { color:var(--navy); }
  .iconbtn:hover       { background:rgba(255,255,255,.26); }

  /* A mouse needs a visible scrollbar; the filter row hides its own. */
  .filters{ scrollbar-width:thin; }
  .filters::-webkit-scrollbar{ display:block; height:6px; }
  .filters::-webkit-scrollbar-thumb{ background:rgba(107,122,144,.34); border-radius:99px; }
}

/* Keyboard focus must stay visible everywhere; a mouse-first screen is also
   the one most likely to be driven by Tab. */
:focus-visible{ outline:2px solid var(--mint); outline-offset:2px; }

/* ---------------------------------------------------- the picker sheet ----
   A sheet that slides up from the bottom edge is a phone gesture. On a large
   pointer-driven screen the same list reads as a centred dialog; it is the
   same markup and the same behaviour, only anchored differently.            */
@media (min-width:700px) and (min-height:600px){
  @keyframes sheetin{ from{ opacity:0; transform:translate(-50%,-46%) scale(.97); }
                      to  { opacity:1; transform:translate(-50%,-50%) scale(1); } }
  .sheet{
    top:50%; bottom:auto; left:50%;
    transform:translate(-50%,-50%);
    max-width:520px; max-height:72vh;
    border-radius:22px;
    animation:sheetin .2s cubic-bezier(.25,.9,.3,1) both;
    box-shadow:0 30px 80px -24px rgba(14,43,87,.55);
    padding-bottom:8px;
  }
  /* The drag handle means "swipe me down", which is not true any more. */
  .sheet .grab{ display:none; }
  .sheet header{ padding-top:16px; }
}

/* ------------------------------------------------------------- printing ---
   Reports are printed from the desktop view, where the shell is now wide.
   Print must ignore the shell entirely and use the sheet of paper.          */
@media print{
  :root{ --shell:100%; }
  .app{ max-width:none; min-height:0; }
  .tabbar,.actionbar,.sheet,.sheet-back{ display:none !important; }
  main{ padding:0; }
  .card{ box-shadow:none; break-inside:avoid; }
}

/* ---------- install on the home screen ------------------------------------ *
   The portal is installable: one app at "/", which signs the user in and then
   routes them to their own module. This is the prompt that offers it — a card
   in the same language as everything else, never the browser's own banner.    */
.pwa-bar{
  position:fixed; left:50%; transform:translateX(-50%) translateY(120%);
  bottom:calc(14px + env(safe-area-inset-bottom));
  width:calc(100% - 28px); max-width:calc(var(--phone) - 28px);
  background:#fff; border:1px solid var(--card-border); border-radius:18px;
  box-shadow:0 14px 40px -12px rgba(14,43,87,.42);
  display:flex; align-items:center; gap:12px; padding:12px 12px 12px 14px;
  z-index:45;                      /* over the page, under a sheet (60/61) */
  transition:transform .3s cubic-bezier(.25,.9,.3,1);
}
.pwa-bar.in{transform:translateX(-50%) translateY(0)}
/* On the screens that have a floating tab bar, sit above it rather than on it. */
.pwa-bar.above-tabs{bottom:calc(84px + env(safe-area-inset-bottom))}
.pwa-ico{width:40px; height:40px; border-radius:11px; flex:none; display:block}
.pwa-txt{flex:1; min-width:0}
.pwa-txt b{display:block; font-size:14px; font-weight:650; letter-spacing:-0.01em}
.pwa-txt .ar{font-size:11.5px}
.pwa-go{
  border:0; border-radius:999px; background:var(--navy); color:#fff;
  font-family:inherit; font-size:13.5px; font-weight:650; letter-spacing:-0.01em;
  padding:10px 16px; min-height:44px; cursor:pointer; flex:none;
  transition:transform .12s cubic-bezier(.2,.9,.3,1.3);
}
.pwa-go:active{transform:scale(.95)}
.pwa-x{
  border:0; background:transparent; color:var(--grey); font-size:22px; line-height:1;
  padding:0 4px; min-width:36px; min-height:44px; cursor:pointer; flex:none;
}
.pwa-steps{margin:0; padding:16px 18px 4px 34px; color:var(--ink); font-size:14.5px}
.pwa-steps li{margin-bottom:14px}
.pwa-steps li::marker{color:var(--mint-deep); font-weight:700}
.pwa-sheet .btn{margin:6px 18px 18px; width:calc(100% - 36px)}
