/* ============================================================
   OtisEd IEP — unified design system (RFP mockups)
   Indigo / slate. Self-contained. No external assets.
   ============================================================ */

/* Token definitions removed: every rule below reads an Aspire token from
   aspire-tokens.css directly. */

*{box-sizing:border-box;margin:0;padding:0}
html,body{font-family:var(--font-body);color:var(--ink-strong);background:var(--surface-page);
  -webkit-font-smoothing:antialiased;font-size:16px;line-height:1.5}
/* default icon size for any bare inline svg; component rules below override */
svg{width:18px;height:18px;flex-shrink:0}
svg.chart{width:100%;height:auto;flex-shrink:1}

/* ---------- App shell ---------- */
.app{display:flex;min-height:100vh}
/* Pinned to the window, not to the page. As a plain flex child the rail grew to
   the height of whatever screen it sat beside, so on any page taller than the
   window the persona footer landed at the bottom of the PAGE — below the fold,
   looking cut off. Sticky at the top with the window's height keeps the brand at
   the top and the persona at the bottom of what you can actually see; the nav
   between them is the part that scrolls if it ever has to. */
.sidebar{width:248px;flex:0 0 248px;background:var(--chrome);color:var(--on-chrome-muted);
  display:flex;flex-direction:column;padding:0;
  position:sticky;top:0;align-self:flex-start;height:100vh;height:100dvh;overflow:hidden}
.sidebar .nav{overflow-y:auto;min-height:0}
/* The brand block is a link to the persona's home route. It keeps the flex layout
   it had as a div and adds the three things a link owes: no underline over a
   lockup, a hover cue on the whole box rather than on the words, and a focus ring
   that clears the mark. The red identity rule is this element's bottom border, so
   the hover fill stops cleanly above it. */
.brand{display:flex;align-items:center;gap:11px;padding:20px 20px;border-bottom:1px solid var(--chrome-hairline);
  text-decoration:none;color:inherit;transition:background-color 160ms ease}
.brand:hover{background:var(--chrome-hover)}
.brand:focus-visible{outline:2px solid var(--on-chrome);outline-offset:-3px}
/* Just a box that holds the mark at its natural size. No background, no radius,
   no shadow: the ASPIRE mark is already a contained circular form and the brand
   notes forbid nesting it inside another badge. */
.brand .mark{width:34px;height:34px;flex:0 0 34px;display:flex;align-items:center;justify-content:center}
.brand .name{color:var(--on-chrome);font-weight:700;font-size:18px;letter-spacing:-.2px;line-height:1.1}
.brand .name small{display:block;font-weight:500;font-size:14px;color:var(--on-chrome-subtle);letter-spacing:.3px;margin-top:1px}
.nav{padding:14px 12px;display:flex;flex-direction:column;gap:2px;flex:1}
.nav .group-label{font-size:14px;text-transform:uppercase;letter-spacing:.9px;color:var(--on-chrome-label);
  font-weight:600;padding:14px 12px 6px}
.nav-item{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;
  color:var(--on-chrome-muted);font-size:15px;font-weight:500;text-decoration:none;cursor:pointer}
.nav-item svg{width:18px;height:18px;flex:0 0 18px;opacity:.85}
.nav-item:hover{background:var(--chrome-hover);color:var(--on-chrome)}
.nav-item.active{background:var(--on-chrome);color:var(--chrome)}
.nav-item.active svg{opacity:1}
.sidebar .side-foot{padding:14px 16px;border-top:1px solid var(--chrome-hairline);
  display:flex;align-items:center;gap:10px}
.avatar{width:34px;height:34px;border-radius:50%;background:var(--brand-wash);color:var(--brand-hover);
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px;flex:0 0 34px}
.side-foot .who{font-size:14px;color:var(--on-chrome);font-weight:600;line-height:1.2}
.side-foot .who small{display:block;color:var(--on-chrome-subtle);font-weight:500;font-size:14px}
/* .avatar's default indigo ramp is a page colour and goes muddy on navy, so the
   one in the rail takes the chrome ramp. Avatars elsewhere are unaffected. */
.side-foot .avatar{background:var(--on-chrome-label);color:var(--chrome)}

.main{flex:1;display:flex;flex-direction:column;min-width:0;background:var(--surface-page)}
.topbar{height:60px;flex:0 0 60px;background:var(--surface-raised);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:16px;padding:0 26px;position:relative;z-index:5}
.topbar .crumbs{font-size:15px;color:var(--ink-muted);font-weight:500}
.topbar .crumbs b{color:var(--ink-strong)}
.topbar .search{margin-inline-start:auto;display:flex;align-items:center;gap:8px;background:var(--surface-page);
  border:1px solid var(--line);border-radius:8px;padding:7px 12px;width:280px;color:var(--ink-muted);font-size:15px}
.topbar .search svg{width:16px;height:16px;flex:0 0 16px}
.topbar .ic{width:38px;height:38px;border-radius:9px;display:flex;align-items:center;justify-content:center;
  color:var(--ink-muted);background:var(--surface-subtle);border:1px solid var(--line)}
.topbar .ic svg{width:18px;height:18px}

.content{padding:26px 30px;flex:1}
.content.narrow{max-width:1180px;margin:0 auto;width:100%}

/* ---------- Page header ---------- */
.page-head{display:flex;align-items:flex-start;gap:16px;margin-bottom:22px}
.page-head .titles h1{font-size:23px;font-weight:700;letter-spacing:-.4px;color:var(--ink-strong)}
.page-head .titles p{color:var(--ink-muted);font-size:15px;margin-top:4px;max-width:680px}
.page-head .actions{margin-inline-start:auto;display:flex;gap:10px;align-items:center}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:8px;padding:9px 16px;border-radius:8px;font-size:15px;
  font-weight:600;border:1px solid transparent;cursor:pointer;text-decoration:none;white-space:nowrap}
.btn svg{width:16px;height:16px}
.btn-primary{background:var(--brand);color:var(--surface-raised);box-shadow:0 1px 2px rgba(79,70,229,.4)}
.btn-ghost{background:var(--surface-raised);color:var(--ink-strong);border-color:var(--line);box-shadow:var(--shadow-raised)}
.btn-soft{background:var(--brand-wash);color:var(--brand-hover);border-color:var(--brand-wash)}
.btn-sm{padding:6px 11px;font-size:14px}

/* ---------- Cards ---------- */
.card{background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--radius-md);box-shadow:var(--shadow-raised)}
.card-head{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line)}
.card-head h3{font-size:16px;font-weight:700;color:var(--ink-strong)}
.card-head .sub{font-size:14px;color:var(--ink-muted);margin-top:1px}
.card-head .actions{margin-inline-start:auto;display:flex;gap:8px;align-items:center}
.card-body{padding:20px}
.grid{display:grid;gap:18px}
.grid-2{grid-template-columns:repeat(2,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-4{grid-template-columns:repeat(4,1fr)}

/* ---------- Stat tiles ---------- */
.stat{background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--radius-md);padding:18px 20px;box-shadow:var(--shadow-raised)}
.stat .label{font-size:14px;color:var(--ink-muted);font-weight:600;text-transform:uppercase;letter-spacing:.5px}
.stat .value{font-size:28px;font-weight:800;color:var(--ink-strong);letter-spacing:-1px;margin-top:7px;line-height:1}
.stat .meta{font-size:14px;margin-top:8px;display:flex;align-items:center;gap:6px;color:var(--ink-muted)}
.stat .ic{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;float:right;float:inline-end}
.stat .ic svg{width:20px;height:20px}
.tone-indigo .ic{background:var(--brand-wash);color:var(--brand)}
.tone-green .ic{background:var(--wash-complete);color:var(--status-complete)}
.tone-amber .ic{background:var(--wash-due-soon);color:var(--status-due-soon)}
.tone-red .ic{background:var(--wash-past-due);color:var(--status-past-due)}
.delta-up{color:var(--status-complete);font-weight:700}
.delta-down{color:var(--status-past-due);font-weight:700}

/* ---------- Badges / pills ---------- */
.badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;
  font-size:14px;font-weight:600;line-height:1.6}
.badge .dot{width:7px;height:7px;border-radius:50%}
.badge.green{background:var(--wash-complete);color:var(--status-complete)} .badge.green .dot{background:var(--status-complete)}
.badge.amber{background:var(--wash-due-soon);color:var(--status-due-soon)} .badge.amber .dot{background:var(--status-due-soon)}
.badge.red{background:var(--wash-past-due);color:var(--status-past-due)} .badge.red .dot{background:var(--status-past-due)}
.badge.indigo{background:var(--brand-wash);color:var(--brand-hover)} .badge.indigo .dot{background:var(--brand)}
.badge.slate{background:var(--line);color:var(--ink-strong)} .badge.slate .dot{background:var(--ink-muted)}
.badge.sky{background:var(--wash-in-progress);color:var(--status-in-progress)} .badge.sky .dot{background:var(--status-in-progress)}

/* ---------- Tables ---------- */
table.tbl{width:100%;border-collapse:collapse;font-size:15px}
table.tbl thead th{text-align:start;font-size:14px;text-transform:uppercase;letter-spacing:.6px;
  color:var(--ink-muted);font-weight:700;padding:11px 16px;border-bottom:1px solid var(--line);background:var(--surface-subtle)}
table.tbl tbody td{padding:13px 16px;border-bottom:1px solid var(--surface-page);color:var(--ink-strong)}
table.tbl tbody tr:last-child td{border-bottom:none}
table.tbl tbody tr:hover{background:var(--surface-subtle)}
table.tbl td .name{font-weight:600;color:var(--ink-strong)}
table.tbl td .sub{color:var(--ink-muted);font-size:14px}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.right{text-align:end}

/* ---------- Accordion (indicator sections) ---------- */
.accordion{display:flex;flex-direction:column;gap:12px}
.acc{background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--radius-md);box-shadow:var(--shadow-raised);overflow:hidden}
.acc-head{display:flex;align-items:center;gap:12px;padding:15px 20px;cursor:pointer}
.acc-head .chev{margin-inline-start:auto;color:var(--ink-muted)}
.acc-head h3{font-size:16px;font-weight:700;color:var(--brand-hover)}
.acc-head .q{width:18px;height:18px;border-radius:50%;border:1.5px solid var(--line);color:var(--ink-muted);
  display:inline-flex;align-items:center;justify-content:center;font-size:14px;font-weight:700}
.acc.open .acc-head{border-bottom:1px solid var(--line)}
.acc-body{padding:6px 0 0}

/* ---------- Forms ---------- */
.field{margin-bottom:18px}
.field label{display:block;font-size:14px;font-weight:600;color:var(--ink-strong);margin-bottom:6px}
.field .req{color:var(--status-past-due)}
.input,.select{width:100%;padding:10px 13px;border:1px solid var(--line);border-radius:8px;font-size:15px;
  color:var(--ink-strong);background:var(--surface-raised);font-family:var(--font-body)}
.input::placeholder{color:var(--ink-muted)}
.input.filled{background:var(--brand-wash);border-color:var(--line-strong);color:var(--brand-hover);font-weight:600}
/* The chevron image is a token, defined once per theme in aspire-tokens.css.
   A data URI cannot read a custom property, so the old version baked in a slate
   hex that stayed cool grey against a warm interface and would have been
   invisible in dark and high contrast. */
.select{appearance:none;background-image:var(--chevron);
  background-repeat:no-repeat;background-position:right 12px center;padding-inline-end:36px}
.hint{font-size:14px;color:var(--ink-muted);margin-top:5px}
.prefill-tag{display:inline-flex;align-items:center;gap:5px;font-size:14px;font-weight:700;color:var(--brand-hover);
  background:var(--brand-wash);border:1px solid var(--brand-wash);border-radius:6px;padding:2px 7px;margin-inline-start:8px}

/* inline compliance prompt */
.alert{display:flex;gap:11px;padding:13px 15px;border-radius:9px;font-size:15px;align-items:flex-start}
.alert .ai{flex:0 0 20px;width:20px;height:20px}
.alert-warn{background:var(--wash-due-soon);border:1px solid var(--wash-due-soon);color:var(--status-due-soon)}
.alert-red{background:var(--wash-past-due);border:1px solid var(--wash-past-due);color:var(--status-past-due)}
.alert-info{background:var(--wash-in-progress);border:1px solid var(--wash-in-progress);color:var(--status-in-progress)}
.alert-ok{background:var(--wash-complete);border:1px solid var(--wash-complete);color:var(--status-complete)}
.alert b{font-weight:700}

/* ---------- Misc ---------- */
.divider{height:1px;background:var(--line);margin:18px 0}
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:20px}
/* .tab is applied to <button>, so it has to clear the user-agent button face
   itself: without the reset the grey fill and bevel border survive and bury
   the underline this rule is trying to draw. */
.tab{appearance:none;background:none;border:0;border-bottom:2px solid transparent;
  font:inherit;font-size:15px;font-weight:600;padding:10px 16px;color:var(--ink-muted);cursor:pointer}
.tab:hover{color:var(--ink-strong)}
.tab.active{color:var(--brand-hover);border-bottom-color:var(--brand)}

/* Segmented filter. Deliberately not .tab: a filter that narrows the content of
   one panel must not look like the tabs that switch between panels, and the two
   appear on the same screen in the tier boundaries view. */
.segbar{display:inline-flex;gap:2px;padding:3px;border-radius:9px;background:var(--surface-page);border:1px solid var(--line)}
.segbtn{appearance:none;background:none;border:0;border-radius:7px;
  font:inherit;font-size:14px;font-weight:600;padding:6px 14px;color:var(--ink-muted);cursor:pointer}
.segbtn:hover{color:var(--ink-strong)}
.segbtn[aria-pressed="true"]{background:var(--surface-raised);color:var(--brand-hover);box-shadow:var(--shadow-raised)}

/* Directory lookup results. Capped in the engine, so this list is short by
   construction and scrolls only when a narrow viewport makes it. */
.picklist{margin-top:6px;border:1px solid var(--line);border-radius:9px;overflow:hidden;max-height:260px;overflow-y:auto}
.pickrow{display:block;width:100%;text-align:start;appearance:none;background:none;border:0;
  border-bottom:1px solid var(--line);font:inherit;padding:9px 12px;cursor:pointer}
.pickrow:last-child{border-bottom:0}
.pickrow:hover{background:var(--surface-subtle)}
.pickrow .name{display:block;font-size:15px;font-weight:600;color:var(--ink-strong)}
.pickrow .sub{display:block}
.picked{display:flex;gap:12px;align-items:flex-start;border:1px solid var(--line);
  border-radius:9px;padding:10px 12px;background:var(--surface-subtle)}
.picked>div:first-child{flex:1 1 auto;min-width:0}
.picked .name{font-size:15px;font-weight:600;color:var(--ink-strong);margin-inline-end:6px}
.legend{display:flex;gap:18px;align-items:center;font-size:14px;color:var(--ink-strong);font-weight:500}
.legend .li{display:flex;align-items:center;gap:6px}
.legend .sw{width:14px;height:3px;border-radius:2px}
.legend .sw.dot{width:10px;height:10px;border-radius:50%}
.mono{font-family:"SF Mono",Consolas,"Roboto Mono",monospace;font-size:14px}

/* ============ Family portal shell ============ */
.portal{min-height:100vh;background:var(--surface-page)}
.portal-bar{height:66px;background:var(--surface-raised);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:28px;padding:0 30px}
.portal-bar .brand-row{display:flex;align-items:center;gap:11px}
.portal-bar .mark{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,var(--brand),var(--brand-hover));display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px rgba(79,70,229,.35)}
.portal-bar .mark svg{width:20px;height:20px;color:var(--surface-raised)}
.portal-bar .pname{font-weight:800;font-size:18px;color:var(--ink-strong);letter-spacing:-.3px}
.portal-bar .pname span{font-weight:600;color:var(--ink-muted)}
.portal-nav{display:flex;gap:6px;margin-inline-start:8px}
.portal-nav a{padding:8px 14px;border-radius:8px;font-size:16px;font-weight:600;color:var(--ink-muted);cursor:pointer}
.portal-nav a.active{background:var(--brand-wash);color:var(--brand-hover)}
.portal-right{margin-inline-start:auto;display:flex;align-items:center;gap:16px}
.lang{display:flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;font-size:14px;font-weight:700}
.lang span{padding:6px 11px;color:var(--ink-muted)}
.lang span.on{background:var(--brand);color:var(--surface-raised)}
.portal-body{max-width:1040px;margin:0 auto;padding:30px}

/* ============ Phone shell ============ */
.phone-stage{min-height:100vh;background:radial-gradient(circle at 50% 0%,var(--brand-wash),var(--surface-subtle) 60%);display:flex;align-items:center;justify-content:center;padding:48px 0}
.phone{width:412px;background:var(--ink-strong);border-radius:46px;padding:13px;box-shadow:0 30px 70px rgba(15,23,42,.35);position:relative}
.phone-notch{position:absolute;top:13px;left:50%;transform:translateX(-50%);width:150px;height:26px;background:var(--ink-strong);border-radius:0 0 18px 18px;z-index:3}
.phone-status{position:absolute;top:20px;left:0;right:0;display:flex;justify-content:space-between;padding:0 34px;color:var(--surface-raised);font-size:15px;font-weight:700;z-index:2}
.phone-status .dots{letter-spacing:1px;font-size:14px}
.phone-screen{background:var(--surface-page);border-radius:34px;overflow:hidden;margin-top:0;min-height:760px}

/* mobile portal internal pieces */
.m-head{background:linear-gradient(135deg,var(--brand),var(--brand-hover));color:var(--surface-raised);padding:50px 20px 22px}
.m-head .hi{font-size:15px;opacity:.85}
.m-head .stu{font-size:20px;font-weight:800;margin-top:3px}
.m-head .meta{font-size:14px;opacity:.85;margin-top:2px}
.m-tabbar{display:flex;background:var(--surface-raised);border-top:1px solid var(--line);position:relative}
.m-tabbar .t{flex:1;text-align:center;padding:11px 0 13px;font-size:14px;font-weight:600;color:var(--ink-muted);display:flex;flex-direction:column;align-items:center;gap:4px}
.m-tabbar .t svg{width:20px;height:20px}
.m-tabbar .t.on{color:var(--brand)}
.m-sec{padding:16px 18px}
.m-card{background:var(--surface-raised);border:1px solid var(--line);border-radius:14px;padding:16px;box-shadow:var(--shadow-raised);margin-bottom:14px}

/* progress bars */
.pbar{height:8px;background:var(--line);border-radius:999px;overflow:hidden}
.pbar>span{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,var(--brand),var(--brand))}
.pbar.green>span{background:linear-gradient(90deg,var(--status-complete),var(--status-complete))}
.pbar.amber>span{background:linear-gradient(90deg,var(--status-due-soon),var(--status-due-soon))}

/* role panel header */
.role-strip{display:flex;align-items:center;gap:12px;padding:13px 18px;border-radius:10px 10px 0 0;color:var(--surface-raised)}
.role-strip svg{width:20px;height:20px}
.role-strip .rt{font-weight:700;font-size:16px}
.role-strip .rd{font-size:14px;opacity:.9;margin-inline-start:auto}
.role-educator{background:linear-gradient(90deg,var(--chart-1),var(--link))}
.role-lea{background:linear-gradient(90deg,var(--brand),var(--brand-hover))}
.role-state{background:linear-gradient(90deg,var(--chart-3),var(--chart-3))}

/* stepper */
.stepper{display:flex;gap:0;margin:6px 0}
.step{flex:1;position:relative;text-align:center}
.step .dot{width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:16px;position:relative;z-index:2;border:2px solid var(--line);background:var(--surface-raised);color:var(--ink-muted)}
.step .dot svg{width:16px;height:16px}
.step.done .dot{background:var(--status-complete);border-color:var(--status-complete);color:var(--surface-raised)}
.step.active .dot{background:var(--brand);border-color:var(--brand);color:var(--surface-raised);box-shadow:0 0 0 4px var(--brand-wash)}
.step:not(:first-child):before{content:"";position:absolute;top:17px;left:-50%;width:100%;height:2px;background:var(--line);z-index:1}
.step.done:before,.step.active:before{background:var(--status-complete)}
.step .lab{font-size:14px;font-weight:600;color:var(--ink-strong);margin-top:8px}
.step .sub2{font-size:14px;color:var(--ink-muted);margin-top:2px}

/* radio cards */
.radio-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.rc{border:1.5px solid var(--line);border-radius:10px;padding:16px;cursor:pointer;position:relative}
.rc.sel{border-color:var(--brand);background:var(--brand-wash)}
.rc .fmt{font-weight:800;font-size:16px;color:var(--ink-strong)}
.rc .d{font-size:14px;color:var(--ink-muted);margin-top:4px}
.rc .tick{position:absolute;top:12px;right:12px;width:20px;height:20px;border-radius:50%;border:2px solid var(--line)}
.rc.sel .tick{background:var(--brand);border-color:var(--brand)}
.rc.sel .tick:after{content:"";position:absolute;top:4px;left:4px;width:8px;height:8px;border-radius:50%;background:var(--surface-raised)}

/* toggle */
.tog{width:38px;height:22px;border-radius:999px;background:var(--line);position:relative;flex:0 0 38px}
.tog:after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:var(--surface-raised)}
.tog.on{background:var(--brand)}
.tog.on:after{left:18px}
.tog.locked{background:var(--line)}
.tog.locked:after{background:var(--line)}

/* Arrows that mean "back" and "forward" point the other way in a right-to-left
   language: Next day is to the left in Arabic. Only these two icons carry the
   class; a chevron that opens a menu, or a check, is not directional. */
[dir="rtl"] .ic-dir{transform:scaleX(-1)}
