/* Employee Portal — utilitarian layer on top of the site tokens. */
body.portal{background:var(--paper)}

.p-login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}
.p-login-card{background:var(--panel);border:2px solid var(--ink);border-radius:20px;
  box-shadow:var(--pop);padding:32px;width:100%;max-width:400px}
.p-brand{display:flex;align-items:center;gap:14px;margin-bottom:20px;color:var(--ink)}
.p-brand b{font-size:17px}
.p-brand span{color:var(--ink-soft);font-size:14px}
/* style.css makes every <form> a 2-column grid (for the booking form).
   The login card wants a plain stacked layout: label over full-width
   field, widget and button on their own rows. Without this the Turnstile
   widget landed in the narrow left grid column and overflowed the card. */
.p-login-card form{display:block;margin-top:0}
.p-login-card label{display:block;font-size:14px;font-weight:700;color:var(--ink-soft);margin:14px 0 6px}
.p-login-card input{width:100%;background:var(--paper);border:2px solid var(--ink);border-radius:12px;
  padding:12px 14px;font:inherit;color:var(--ink)}
.p-login-card .btn{margin-top:20px;width:100%}
/* Cloudflare Turnstile: its iframe is a FIXED 300px wide and refuses to
   shrink. min-width:0 stops it inflating the form (which pushed the inputs
   and button outside the card); flex centers the iframe in the leftover
   space instead. */
.p-login-card .cf-turnstile{min-width:0;display:flex;justify-content:center;margin-top:16px}
@media (max-width:430px){
  /* Slim the card down so the 300px widget genuinely fits on phones. */
  .p-login-wrap{padding:12px}
  .p-login-card{padding:24px 16px}
}
@media (max-width:352px){
  /* Tiny screens: even edge-to-edge 300px doesn't fit — scale the widget.
     No fixed height: with appearance=interaction-only the widget is usually
     invisible, and a reserved height would leave a phantom gap. */
  .p-login-card .cf-turnstile{transform:scale(.86);transform-origin:center top}
}
.p-error{background:var(--red);color:#fff;border-radius:10px;padding:10px 14px;font-size:14px;font-weight:600}
.p-langs{margin-top:18px;text-align:center;font-size:14px}

.p-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:12px 20px;background:var(--panel);border-bottom:2px solid var(--ink);flex-wrap:wrap}
.p-user{display:flex;align-items:center;gap:12px;font-size:14px;color:var(--ink)}
.p-level{background:var(--amber);color:#26333B;border:1.5px solid #26333B;border-radius:999px;
  padding:3px 12px;font-size:12.5px;font-weight:800}
.p-lang{color:var(--ink-soft);text-decoration:none;font-weight:700;padding:2px 4px}
.p-lang:hover{color:var(--fern)}
.p-logout{border:2px solid var(--ink);background:transparent;color:var(--ink);border-radius:999px;
  padding:6px 14px;font:inherit;font-size:13.5px;font-weight:700;cursor:pointer}
.p-logout:hover{background:var(--ink);color:var(--paper)}

.p-main{max-width:1200px;margin:0 auto;padding:28px 20px}
.p-main h1{font-size:24px;margin-bottom:18px}
.p-empty{color:var(--ink-soft)}
.p-tablewrap{overflow-x:auto;background:var(--panel);border:2px solid var(--ink);border-radius:14px;box-shadow:var(--pop)}
.p-table{width:100%;border-collapse:collapse;font-size:14.5px}
.p-table th{text-align:left;padding:12px 14px;border-bottom:2px solid var(--ink);
  font-size:12.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft)}
.p-table td{padding:11px 14px;border-bottom:1px solid var(--line);vertical-align:top;color:var(--ink)}
.p-table tbody tr:last-child td{border-bottom:0}
.p-table a{color:var(--fern);font-weight:600;text-decoration:none}
.p-nowrap{white-space:nowrap}
.p-note{max-width:340px}
.p-tag{background:var(--sky-soft);border:1px solid var(--line);border-radius:999px;
  padding:2px 10px;font-size:12px;font-weight:700;text-transform:uppercase;white-space:nowrap}

/* claim-system workflow */
.p-notice{background:var(--amber);color:#26333B;border:1.5px solid #26333B;border-radius:12px;
  padding:10px 16px;font-size:14px;font-weight:600;margin-bottom:14px}
.p-st{display:inline-block;border-radius:999px;padding:3px 12px;font-size:12.5px;font-weight:800;
  border:1.5px solid #26333B;color:#26333B;white-space:nowrap}
.p-st-new{background:#BBD8F2}
.p-st-claimed{background:#F8DE9C}
.p-st-addressed{background:#C4E3C0}
.p-row-addressed td{opacity:.65}
.p-actions{white-space:nowrap}
.p-actions form{display:inline-block;margin:0 4px 4px 0}
.p-act{border:1.5px solid var(--ink);background:var(--panel);color:var(--ink);border-radius:999px;
  padding:5px 12px;font:inherit;font-size:12.5px;font-weight:700;cursor:pointer;white-space:nowrap}
.p-act:hover{background:var(--ink);color:var(--paper)}
.p-act-claim{background:var(--blue);border-color:#26333B;color:#fff}
.p-act-claim:hover{background:#2F6AAB;color:#fff}
.p-act-address{background:var(--green);border-color:#26333B;color:#fff}
.p-act-address:hover{background:#3D7447;color:#fff}
.p-act-danger{border-color:var(--red);color:var(--red)}
.p-act-danger:hover{background:var(--red);color:#fff}

/* staff account management */
.p-card{background:var(--panel);border:2px solid var(--ink);border-radius:14px;
  box-shadow:var(--pop);padding:20px;margin-bottom:26px}
.p-card h2{font-size:18px;margin-bottom:14px}
.p-create{display:flex;gap:14px;flex-wrap:wrap;align-items:flex-end}
.p-create label{display:block;font-size:13px;font-weight:700;color:var(--ink-soft);margin-bottom:4px}
.p-create input,.p-create select{background:var(--paper);border:2px solid var(--ink);border-radius:10px;
  padding:9px 12px;font:inherit;color:var(--ink)}
.p-create .btn{padding:11px 22px;font-size:15px}
.p-inline{display:inline-flex;gap:6px;align-items:center;margin:0 6px 4px 0}
.p-inline select,.p-inline input{background:var(--paper);border:1.5px solid var(--ink);border-radius:8px;
  padding:5px 8px;font:inherit;font-size:13px;color:var(--ink);max-width:150px}

/* site settings */
.p-hint{color:var(--ink-soft);font-size:13.5px;margin:0 0 12px}
.p-settings-form{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.p-settings-form input{flex:1;min-width:260px;background:var(--paper);border:2px solid var(--ink);
  border-radius:10px;padding:10px 12px;font:inherit;color:var(--ink)}
.p-settings-form .btn{padding:11px 22px;font-size:15px}
.p-settings-col{flex-direction:column;align-items:stretch}
.p-settings-col label{font-size:13px;font-weight:700;color:var(--ink-soft)}
.p-settings-col .btn{align-self:flex-start}

/* SLA age tints — on the STATUS BADGE, not the row (row tints made text
   hard to read); "late" is the urgent state past the 24-hour limit. */
.p-st.p-age-warn{background:var(--amber)}
.p-st.p-age-late{background:var(--red);color:#fff;border-color:#26333B}

/* inquiry actions live in their own column between Status and When.
   Buttons wrap/stack as WHOLE units when space is tight; the text inside
   each button never wraps (.p-act is nowrap). */
.p-actcell{white-space:normal}
.p-actcell form{display:inline-block;margin:0 4px 4px 0}

/* status filter pills */
.p-filters{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 16px}
.p-filters a{border:1.5px solid var(--ink);border-radius:999px;padding:5px 14px;
  font-size:13px;font-weight:700;text-decoration:none;color:var(--ink);background:var(--panel)}
.p-filters a:hover{background:var(--sky-soft)}
.p-filters a.on{background:var(--ink);color:var(--paper)}
.p-filters a.p-f-urgent{border-color:var(--red);color:var(--red)}
.p-filters a.p-f-urgent:hover{background:var(--red);color:#fff}
.p-filters a.p-f-urgent.on{background:var(--red);color:#fff}
.p-filters a.p-f-mine{border-style:dashed}
.p-filters a.p-f-mine.on{background:var(--fern);border-color:var(--fern);border-style:solid;color:#fff}

/* contact-log sub-line under the status badge */
.p-subline{margin-top:5px;font-size:12px;color:var(--ink-soft);max-width:180px}

/* notes open in a single centered MODAL above the table — opaque card,
   scrollable for long histories, closed via ✕, backdrop, or Escape;
   opening another note replaces the current one. */
.p-modal{position:fixed;inset:0;z-index:100;display:flex;align-items:flex-start;
  justify-content:center;background:rgba(15,25,32,.55);padding:60px 20px 20px;overflow:auto}
.p-modal[hidden]{display:none}
.p-modal-card{position:relative;background:var(--panel);border:2px solid var(--ink);
  border-radius:16px;box-shadow:var(--pop);padding:20px 24px;width:min(560px,100%);
  max-height:min(80vh,720px);overflow:auto}
.p-modal-x{position:absolute;top:10px;right:12px;border:0;background:transparent;
  color:var(--ink);font-size:18px;font-weight:800;cursor:pointer;line-height:1;padding:4px}
.p-modal-x:hover{color:var(--red)}
.p-modal-h{margin:0 24px 10px 0;font-size:15px;font-weight:800}
.p-notetext{margin:0;font-weight:600;white-space:normal;overflow-wrap:anywhere}
.p-notenone{color:var(--ink-soft);font-weight:400}
.p-notelog-h{margin:14px 0 6px;font-size:12px;font-weight:800;text-transform:uppercase;
  letter-spacing:.04em;color:var(--ink-soft)}
.p-notelog{margin:0;padding:10px 0 0;border-top:1px solid var(--line);list-style:none;
  font-size:13px;color:var(--ink-soft)}
.p-notelog li{padding:6px 0;border-bottom:1px solid var(--line)}
.p-notelog li:last-child{border-bottom:0}
.p-ev-head{font-size:12px;color:var(--ink-soft)}
.p-ev-edited{font-style:italic}
.p-ev-body{margin:2px 0 4px;color:var(--ink);font-weight:600;white-space:pre-wrap;overflow-wrap:anywhere}
/* Small pill buttons used inside the notes log (Edit / Save / Cancel). */
.p-act.p-mini{padding:2px 12px;font-size:12px;margin:2px 6px 2px 0}
/* style.css makes every <form> a 2-column grid (for the booking form); the
   modal's note forms want a plain block so children stack — and so the
   [hidden] edit form actually stays hidden (an explicit display:grid would
   otherwise beat the UA [hidden] rule). */
.p-note-add,.p-note-edit{display:block}
.p-note-edit[hidden]{display:none}
.p-note-edit{margin:4px 0 2px}
.p-note-edit textarea,.p-note-add textarea{width:100%;background:var(--paper);
  border:2px solid var(--ink);border-radius:10px;padding:8px 10px;font:inherit;
  font-size:13px;color:var(--ink);min-height:64px;resize:vertical}
.p-note-editbtns{margin-top:4px}
/* Add-note form under the log. */
.p-note-add{margin-top:16px;padding-top:14px;border-top:2px solid var(--line)}
.p-note-addlabel{display:block;font-size:13px;font-weight:800;margin-bottom:6px;color:var(--ink)}
.p-note-add textarea{min-height:84px}
.p-note-hint{margin:6px 0 8px;font-size:12px;color:var(--ink-soft)}
.p-note-addbtn{margin-top:2px}

/* children registry + video review */
.p-crumbs{margin:0 0 6px;font-size:13px;color:var(--ink-soft)}
.p-crumbs a{color:var(--fern)}
.p-h2{margin:22px 0 10px;font-size:18px}
.p-panel{background:var(--panel);border:2px solid var(--ink);border-radius:14px;
  box-shadow:var(--pop);padding:16px 18px;margin:14px 0}
.p-panel h2{margin:0 0 10px;font-size:16px}
.p-row-archived{opacity:.55}
.p-note-add input[type=text],.p-note-add input:not([type]){width:100%;background:var(--paper);
  border:2px solid var(--ink);border-radius:10px;padding:8px 10px;font:inherit;
  font-size:13px;color:var(--ink);margin-bottom:8px}
.p-note-add input[type=file]{display:block;margin:8px 0;font-size:13px;color:var(--ink)}
.p-video-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.p-vst-pending{background:var(--amber);color:#26333B}
.p-vst-approved{background:var(--green);color:#fff}
.p-vst-denied{background:var(--red);color:#fff}
.p-video .p-actcell{margin:8px 0}
.p-videoframe{position:relative;padding-top:56.25%;border:2px solid var(--ink);
  border-radius:14px;overflow:hidden;box-shadow:var(--pop);background:#000}
.p-videoframe iframe{position:absolute;inset:0;width:100%;height:100%}

/* collapsible add/upload panels */
.p-addfold summary{cursor:pointer;font-size:15px;padding:2px 0;list-style:none}
.p-addfold summary::-webkit-details-marker{display:none}
.p-addfold summary::before{content:"＋ ";color:var(--fern);font-weight:800}
.p-addfold[open] summary::before{content:"− "}
.p-addfold[open] summary{margin-bottom:10px;border-bottom:1px solid var(--line);padding-bottom:8px}

/* video grid — YouTube-style tiles, responsive columns */
.p-vgrid{display:grid;gap:18px;margin:16px 0;
  grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.p-vtile{background:var(--panel);border:2px solid var(--ink);border-radius:14px;
  box-shadow:var(--pop);overflow:hidden;display:flex;flex-direction:column}
.p-vtitle{margin:0;padding:10px 12px 8px;font-size:14px;font-weight:800;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.p-vthumb{position:relative;padding-top:56.25%;background:#000;overflow:hidden}
.p-vthumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.p-vthumb iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.p-vproc{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  color:var(--ink-soft);font-size:13px}
.p-vplay{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;
  border:2px solid #fff;background:rgba(20,30,38,.62);color:#fff;font-size:20px;
  cursor:pointer;display:flex;align-items:center;justify-content:center;padding-left:4px}
.p-vplay:hover{background:var(--red);border-color:#fff}
.p-vbadge{position:absolute;top:8px;left:8px;font-size:11px}
.p-vdur{position:absolute;bottom:8px;right:8px;background:rgba(20,30,38,.8);color:#fff;
  border-radius:6px;padding:1px 6px;font-size:11.5px;font-weight:700}
.p-vexpand{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;
  border:0;border-top:1px solid var(--line);background:transparent;color:var(--ink-soft);
  font:inherit;font-size:12.5px;padding:9px 12px;cursor:pointer;text-align:left}
.p-vexpand:hover{background:var(--paper);color:var(--ink)}
.p-vmeta{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.p-sortsep{color:var(--ink-soft);font-size:12.5px;margin-left:8px;align-self:center}
/* video panel: action rows never overlap — they wrap on one aligned grid */
.p-actrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:12px 0}
.p-actrow .p-act{margin:0}
.p-crow{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
.p-crow .p-act{margin:0}
.p-vrec{margin:2px 0 10px;font-size:14px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.p-recbox{background:var(--paper);border:2px solid var(--ink);border-radius:12px;
  padding:10px 12px;margin:0 0 12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
/* an explicit display: rule beats the UA [hidden] rule, so restore it */
.p-recbox[hidden]{display:none}
.p-statusrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:6px 0 2px}
.p-vtitle-clickable{cursor:pointer}
.p-vtitle-clickable:hover{color:var(--fern)}
/* upload progress overlay */
.p-uplist{list-style:none;margin:6px 0 0;padding:0}
.p-uplist li{padding:8px 0;border-bottom:1px solid var(--line)}
.p-uplist li:last-child{border-bottom:0}
.p-upname{font-size:13px;font-weight:700;overflow-wrap:anywhere}
.p-upstate{font-size:12px;color:var(--ink-soft);margin-top:2px}
.p-upstate-err{color:var(--err-text);font-weight:600}
.p-upstate-ok{color:var(--green)}
.p-upstate-dupe{color:var(--wood-deep);font-weight:600}
.p-recbox input[type=datetime-local]{background:var(--panel);border:2px solid var(--ink);
  border-radius:8px;padding:5px 8px;font:inherit;font-size:13px;color:var(--ink)}
.p-act-warn{background:var(--amber);border-color:#26333B;color:#26333B}
.p-act-warn:hover{background:#DCA62F;color:#26333B}
.p-vst-changes_required{background:var(--amber);color:#26333B}
.p-vst-unresolved{background:var(--red);color:#fff}
.p-vst-resolved{background:var(--green);color:#fff}
.p-vbadge2{position:absolute;top:8px;right:8px;font-size:11px}
.p-tag-parent{background:var(--sky-soft);color:var(--ink)}

/* upload progress (resumable/tus) */
.p-progress{height:10px;background:var(--paper);border:2px solid var(--ink);
  border-radius:999px;overflow:hidden;margin:10px 0 6px}
.p-progress-bar{height:100%;width:0;background:var(--green);transition:width .25s ease}

/* parent accounts — search */
.p-search{display:flex;gap:8px;align-items:center;margin:14px 0}
.p-search input[type=search]{flex:1;max-width:480px;background:var(--panel);
  border:2px solid var(--ink);border-radius:999px;padding:9px 16px;font:inherit;
  font-size:14px;color:var(--ink)}

/* parent accounts — compact expandable list */
.p-parlist{border:2px solid var(--ink);border-radius:14px;background:var(--panel);
  box-shadow:var(--pop);overflow:hidden;margin:14px 0}
.p-parfold{border-bottom:1px solid var(--line)}
.p-parfold:last-child{border-bottom:0}
.p-parfold > summary{display:flex;align-items:center;gap:10px;list-style:none;cursor:pointer;
  padding:10px 16px;font-size:14px}
.p-parfold > summary::-webkit-details-marker{display:none}
.p-parfold > summary:hover{background:var(--paper)}
.p-parfold[open] > summary{border-bottom:1px dashed var(--line)}
.p-parname{flex-shrink:0}
.p-parkids{color:var(--ink-soft);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.p-parphone{color:var(--ink-soft);white-space:nowrap;font-size:13px}
.p-parfold .chev{color:var(--ink-soft);font-size:11px}
.p-parfold[open] .chev{transform:rotate(180deg)}
.p-pardot{width:10px;height:10px;border-radius:50%;background:var(--amber);flex-shrink:0}
.p-pardot-ok{background:var(--green)}
.p-parbody{padding:10px 16px 14px}
.p-parbody .p-inline-link input{background:var(--paper);border:2px solid var(--ink);
  border-radius:8px;padding:4px 8px;font:inherit;font-size:13px;color:var(--ink);max-width:220px}
.p-parbody .p-inline-link input[type=date]{max-width:160px;color-scheme:light dark}
.p-inline-link{display:flex;gap:6px;align-items:center;margin-top:6px}
.p-inline-link select,.p-inline-form select,.p-select{background:var(--paper);border:2px solid var(--ink);
  border-radius:8px;padding:4px 6px;font:inherit;font-size:12px;color:var(--ink);max-width:220px}
.p-select{display:block;padding:8px 10px;font-size:13px;margin-bottom:8px}
.p-inline-form{display:inline-flex;gap:6px;align-items:center;margin:0 6px 4px 0}
.p-childline{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.p-fold{margin:10px 0}
.p-fold summary{cursor:pointer;font-size:13px;font-weight:700;color:var(--ink-soft)}
.p-fold[open] summary{margin-bottom:6px}
.p-fold-inner{margin:12px 0 4px;padding-left:10px;border-left:2px solid var(--line)}
/* every control on a child line sits on one aligned row */
.p-childline{align-items:center}
.p-childline .p-inline-form,.p-childline .p-inline-link{margin:0;display:inline-flex;align-items:center}
.p-childline .p-act{margin:0}

/* hamburger menu (reuses the main page's .langsel dropdown) */
.p-hmenu summary{padding:8px 10px}
.p-hmenu ul{min-width:220px}
/* Keep the portal header dropdowns anchored to their own button at ALL
   widths. The public-site mobile rule switches .langsel to position:static,
   which in the portal's flex-wrap header pushed the opened menu far down the
   page (out of view). Higher specificity (.p-bar .langsel) overrides it. */
.p-bar .langsel{position:relative}
.p-bar .langsel ul{position:absolute;right:0;left:auto;top:calc(100% + 8px);
  width:max-content;min-width:200px;max-width:calc(100vw - 32px)}
.p-hmenu li a{white-space:nowrap}
.p-menu-out{border-top:1px solid var(--line);margin-top:6px;padding-top:6px}
.p-menu-out button{display:block;width:100%;text-align:left;border:0;background:transparent;
  padding:8px 12px;border-radius:8px;font:inherit;font-size:15px;font-weight:700;
  color:var(--red);cursor:pointer}
.p-menu-out button:hover{background:var(--red);color:#fff}

/* responsive inquiries table: full info on any device — cells wrap on
   desktop, rows become stacked cards on narrow screens */
.p-table td{white-space:normal;overflow-wrap:anywhere}
.p-table td.p-nowrap{white-space:nowrap}
/* date and time may stack on two lines to keep the table narrow */
.p-table td.p-when{max-width:90px}
@media (max-width:760px){
  .p-tablewrap{overflow-x:visible;background:transparent;border:0;box-shadow:none}
  .p-table thead{display:none}
  .p-table,.p-table tbody{display:block}
  .p-table tr{display:block;background:var(--panel);border:2px solid var(--ink);
    border-radius:14px;box-shadow:var(--pop);margin-bottom:14px;padding:6px 0}
  .p-table td{display:flex;gap:12px;justify-content:space-between;align-items:baseline;
    border-bottom:0;padding:7px 14px;white-space:normal}
  .p-table td.p-nowrap,.p-table td.p-when{white-space:normal}
  .p-table td::before{content:attr(data-label);font-size:12px;font-weight:800;
    text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft);flex-shrink:0}
  .p-table td[data-label=""]::before,.p-table td:not([data-label])::before{content:none}
  /* on cards the action buttons stack vertically under their label —
     never marching off the right edge of the card */
  .p-actcell{white-space:normal;flex-direction:column;align-items:flex-start;gap:6px}
  .p-actcell form{display:block;margin:0}
  .p-table td.p-when{max-width:none}
  .p-subline{white-space:normal;max-width:none}
}

/* the inquiries table gets more room than the other portal pages and
   tighter cells so it fits a 1080p screen without horizontal scrolling */
.p-main-wide{max-width:1600px}
.p-main-wide .p-table{font-size:14px}
.p-main-wide .p-table th{padding:12px 10px}
.p-main-wide .p-table td{padding:10px 10px}

/* Domain-email registry */
.p-addrpair{display:inline-flex;align-items:center;gap:6px}
.p-domain{font-weight:700;color:var(--ink-soft);white-space:nowrap}
.p-card .p-hint{margin-top:12px;max-width:720px}

/* Read-only impersonation strip: permanent, slim, at the very top of
   every authenticated page. Fixed light colors with EXPLICIT dark text —
   var(--ink) flips light in dark mode and made the text unreadable. */
.p-impbar{position:sticky;top:0;z-index:60;display:flex;align-items:center;
  justify-content:center;gap:14px;flex-wrap:wrap;background:#FBF0D4;color:#26333B;
  border-bottom:2px solid #26333B;padding:6px 16px;font-size:13px}
.p-impbar b{color:#26333B}
.p-impbar form{margin:0}
.p-impbar button{border:1.5px solid #26333B;background:transparent;color:#26333B;
  border-radius:999px;padding:3px 12px;font:inherit;font-size:12.5px;font-weight:700;
  cursor:pointer;white-space:nowrap}
.p-impbar button:hover{background:#26333B;color:#FBF0D4}

/* Pending email-change tag */
.p-tag-pending{background:#FBF0D4;color:#26333B;border-color:#B8A67A}

/* Profile page */
.p-profile{display:flex;flex-direction:column;gap:14px;max-width:640px}
.p-profile label{display:block;font-size:13px;font-weight:700;color:var(--ink-soft);margin-bottom:4px}
.p-profile input,.p-profile textarea{width:100%;background:var(--paper);border:2px solid var(--ink);border-radius:10px;padding:10px 12px;font:inherit}
.p-profile .btn{align-self:flex-start}
.p-profile-ro{margin:0 0 10px;line-height:1.7}

/* Login-code entry */
.p-code-input{font-size:26px;font-weight:800;letter-spacing:8px;text-align:center}

/* ---- title row: page heading with its primary action beside it ----
   Carries the SAME bottom margin an <h1> has on its own (see .p-main h1), so
   a page with an action button beside its title lines up with every page
   without one. */
.p-titlerow{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:0 0 18px}
.p-titlerow h1{margin:0}

/* Change-password page when signed in: normal page shape (title under the
   header, form directly below) rather than the centred login card. */
.p-pwpage .p-login-card{margin:0;width:min(460px,100%)}

/* optional physical address, shown under the name it belongs to */
.p-addr{font-size:12px;color:var(--ink-soft);overflow-wrap:anywhere}

/* notification-recipient list and its picker */
.p-reciplist{margin-bottom:10px}
.p-picklist{max-height:340px;overflow:auto;border:2px solid var(--line);
  border-radius:10px;padding:6px 10px;margin:4px 0 8px}
/* Specific enough to beat `.p-fm label{display:block}` below, and to stop the
   global `input{width:100%}` from stretching the checkbox across the row. */
.p-fm label.p-pickrow{display:flex;align-items:flex-start;gap:10px;padding:7px 2px;
  border-bottom:1px solid var(--line);font-size:13px;font-weight:500;
  cursor:pointer;margin:0}
.p-fm label.p-pickrow:last-child{border-bottom:0}
.p-fm label.p-pickrow input[type=checkbox]{width:16px;height:16px;flex:none;
  margin:2px 0 0;padding:0;accent-color:var(--fern)}
.p-fm label.p-pickrow b{font-weight:800}

/* the shared data-entry overlay: fields stack, actions sit on one row */
.p-fm .p-modal-card{width:min(620px,100%)}
.p-fm label{display:block;font-size:13px;font-weight:800;margin:10px 0 4px;color:var(--ink)}
.p-fm input[type=text],.p-fm input[type=email],.p-fm input[type=tel],
.p-fm input[type=date],.p-fm input:not([type]),.p-fm select,.p-fm textarea{
  width:100%;background:var(--paper);border:2px solid var(--ink);border-radius:10px;
  padding:8px 10px;font:inherit;font-size:13px;color:var(--ink)}
.p-fm input:disabled{background:var(--line);color:var(--ink-soft)}
.p-fm textarea{min-height:84px;resize:vertical}
.p-fm-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.p-fm-acts [hidden]{display:none}
.p-fm-notes{margin-top:18px;padding-top:12px;border-top:2px solid var(--line)}

/* ---- header: hamburger first, then the logo and page name ----
   The menu is the thing people navigate with, so it leads the bar rather than
   trailing it. brand takes the free space so the account chip stays right. */
.p-bar .p-hmenu-left{order:-1;flex:none}
.p-bar .p-brand{margin-bottom:0;margin-right:auto}
/* A dropdown on the LEFT must open rightwards, or it runs off the viewport. */
.p-bar .p-hmenu-left ul{left:0;right:auto}

/* label + Translate button on one line above a banner field, both kept to the
   LEFT so the button sits with the label it belongs to rather than drifting to
   the far edge of the card. */
.p-trrow{display:flex;align-items:center;justify-content:flex-start;gap:10px;margin:10px 0 4px}
.p-fm .p-trrow label{margin:0}
.p-trrow .p-act{margin:0;flex:none}

/* ---- Caseload page (§4a.1b) ------------------------------------------- */
/* The public site styles bare <section> with 48-70px of vertical padding.
   Portal sections are list panels, not landing-page bands, so that inherited
   padding was adding ~96px of empty space PER SECTION — the whitespace that
   made a team of five need scrolling on a phone. */
.p-main section.p-sect{padding:0}
.p-sect{margin:14px 0 0}
/* Sections on this page are dense lists, not articles: the generous default
   gap meant a dozen people needed scrolling on a phone. */
.p-main-wide .p-sect+.p-sect{margin-top:6px}
.p-sect-first{margin-top:2px}
.p-sect-h{margin:0 0 2px;font-size:13px;font-weight:800;text-transform:uppercase;
  letter-spacing:.04em;color:var(--ink)}
/* Children sit UNDER the heading or the person they belong to, and the page
   reads badly when they start at the same left edge (owner, 2026-07-30): a
   long team block becomes one flat column with nothing to tell a child from a
   section. The rule marks the depth without spending width on it — indent
   alone gets lost once a row wraps. */
.p-caselist{margin:8px 0 0 14px;padding:0 0 0 10px;list-style:none;
  border-top:1px solid var(--line);border-left:1px solid var(--line)}
.p-caselist li{display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  padding:8px 2px;border-bottom:1px solid var(--line)}
/* The last row's border would run past the end of the left rule and look
   like a dropped edge. */
.p-caselist li:last-child{border-bottom:0}
@media (max-width:640px){
  /* On a phone the width matters more than the depth does. */
  .p-caselist{margin-left:6px;padding-left:6px}
}
.p-case-name{font-weight:700;color:var(--ink);text-decoration:none}
a.p-case-name:hover{text-decoration:underline}
.p-case-parent{color:#5A6B75;font-size:13px}
.p-case-meta{margin-left:auto;color:#5A6B75;font-size:12px;white-space:nowrap}
.p-teamblock{margin:4px 0 0;padding:4px 10px;border:1px solid var(--line);border-radius:12px;
  background:var(--panel)}
.p-team-h{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0;font-size:14px}

/* collapsed history blocks (caseload + team) */
.p-histbox{border-top:1px solid var(--line);padding-top:8px}
.p-histbox>summary{cursor:pointer;list-style:revert;padding:4px 0}
.p-histbox>summary::marker{color:var(--ink-soft)}
.p-histbox .p-notelog{max-height:420px;overflow-y:auto}
/* GUID chips in log lines: readable short form, full value on hover/copy.
   Names make a line readable; duplicate names are allowed here, so the GUID
   is what makes it certain which child or employee is meant. */
.p-guid{display:inline-block;margin-left:6px;padding:0 6px;border:1px solid var(--line);
  border-radius:6px;background:var(--cream);color:var(--ink-soft);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;
  letter-spacing:.02em;cursor:help;user-select:all}

/* ---- My Team: ragged hierarchy + drag and drop ------------------------ */
/* NOTE THE SELECTOR: `.p-caselist li` is (0,1,1) and would beat a bare
   `.p-tmrow` (0,1,0), so the indent silently never applied. Qualify it. Same
   trap as `.p-fm label` beating `.p-pickrow` on the overlay. */
.p-caselist li.p-tmrow{
  position:relative;
  padding-left:calc(14px + var(--tm-depth, 0) * 26px);
  padding-top:4px;padding-bottom:4px;
  gap:6px;
}
/* The elbow: a short horizontal stub joining each row to its parent's guide
   line. Indentation alone reads as "roughly over there"; the connector makes
   the rollup unambiguous. */
.p-caselist li.p-tmrow::before{
  content:"";position:absolute;
  left:calc(var(--tm-depth, 0) * 26px - 12px);
  top:0;bottom:0;width:2px;background:var(--line);
}
.p-caselist li.p-tmrow::after{
  content:"";position:absolute;
  left:calc(var(--tm-depth, 0) * 26px - 12px);
  top:50%;width:11px;height:2px;background:var(--line);
}
.p-caselist li.p-tm-root::before,
.p-caselist li.p-tm-root::after{display:none}
.p-tmrow.p-tm-root>.p-case-name{font-weight:800;font-size:15px}
.p-tm-grip{cursor:grab;color:var(--ink-soft);font-size:14px;line-height:1;
  padding:0 2px;user-select:none}
.p-tmrow:active .p-tm-grip{cursor:grabbing}
.p-tm-dragging{opacity:.4}
.p-tm-dnd .p-tmrow,.p-tm-dnd .p-tmslot{transition:background .08s}
.p-tm-over{outline:2px dashed var(--blue);outline-offset:-2px;background:var(--sky-soft)}
.p-tmzone{min-height:8px}
.p-tag-total{background:var(--cream);color:var(--ink)}

/* Empty slots: the drop targets that change WHICH team somebody is on, rather
   than who they report to. Visible at rest so they are discoverable, and lit
   only while something is being dragged over them. */
.p-tmslot{margin:6px 0 0;padding:6px 10px;border:2px dashed var(--line);
  border-radius:10px;color:var(--ink-soft);font-size:13px;text-align:center}
.p-tm-dnd .p-tmslot{border-color:var(--blue);color:var(--ink)}
.p-tmhint{margin:0 0 6px;font-size:12.5px}

/* Foldable sections. Same affordance as the history box, but these hold rows
   you can drop onto, so a closed one opens on drag-over (see team.html). */
.p-fold{border-top:1px solid var(--line);padding-top:4px}
.p-fold>summary{cursor:pointer;list-style:revert;padding:2px 0}
.p-fold>summary::marker{color:var(--ink-soft)}
.p-fold[open]>summary{margin-bottom:4px}

/* The team size sits with the page title rather than repeating it as a
   section heading directly underneath. */
.p-titlecount{display:inline-flex;align-items:center;justify-content:center;
  min-width:26px;height:24px;padding:0 8px;border-radius:999px;
  background:var(--ink);color:var(--paper);font-size:13px;font-weight:800;
  cursor:help}
/* History lines read as sentences: the names carry the weight, the verb sits
   between them, and the metadata drops to a quiet second line. */
.p-ev-verb{color:var(--ink-soft);font-weight:400;margin:0 2px}
.p-notelog .p-ev-body{margin-bottom:1px}
.p-notelog .p-ev-head{color:var(--ink-soft);font-size:11.5px}
/* A COMPOSED history line — subject, verb, object assembled from elements —
   as opposed to .p-ev-body's other job, holding a note somebody typed. That
   one keeps `pre-wrap` so the author's own line breaks survive; here pre-wrap
   turned the template's source indentation into seven rendered lines. Each
   entry is exactly two: the sentence, then when and who. Clipped rather than
   wrapped, because a log is scanned down the left edge — the row's `title`
   carries the full text and the full GUIDs. */
.p-notelog li.p-ev-2{padding:3px 0}
.p-ev-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  overflow-wrap:normal;line-height:1.45}
.p-ev-line .p-case-meta{margin-left:6px}
/* The reason a change happened, when nobody chose it: quieter than the names,
   louder than the metadata line. */
.p-ev-why{color:var(--ink-soft);font-weight:400;font-style:italic;margin-left:4px}

@media (max-width: 560px){
  .p-caselist li.p-tmrow{gap:4px;padding-left:calc(8px + var(--tm-depth, 0) * 16px)}
  .p-caselist li.p-tmrow::before{left:calc(var(--tm-depth, 0) * 16px - 8px)}
  .p-caselist li.p-tmrow::after{left:calc(var(--tm-depth, 0) * 16px - 8px);width:7px}
  .p-tmrow .p-tag,.p-tmrow .p-level{font-size:10.5px;padding:1px 6px}
  .p-tmrow .p-act.p-mini{font-size:11px;padding:1px 8px;margin:1px 3px 1px 0}
  .p-tmrow .p-case-meta{font-size:11px}
  .p-tmslot{padding:5px 8px;font-size:12px}
}

/* Flash toast: fixed to the VIEWPORT so it appears where the reader is
   looking. A notice pinned to the top of the document is invisible to anyone
   working further down a long roster — and scrolling them up to show it costs
   them their place. */
.p-toast{position:fixed;top:12px;left:50%;transform:translateX(-50%);
  z-index:60;max-width:min(560px,calc(100vw - 24px));
  display:flex;align-items:center;gap:10px;
  padding:10px 12px 10px 16px;border:2px solid #26333B;border-radius:12px;
  background:var(--amber);color:#26333B;font-size:14px;font-weight:700;
  box-shadow:0 6px 18px rgba(0,0,0,.28)}
.p-toast[hidden]{display:none}
.p-toast-x{border:0;background:transparent;color:#26333B;font-size:15px;
  font-weight:800;cursor:pointer;line-height:1;padding:2px 4px}
.p-toast-x:hover{opacity:.6}

/* ---- "You cannot open this page" -----------------------------------------
   Built on the sign-in card so a refusal still looks like this site rather
   than like a server error. It carries the reason, WHO is signed in (a
   colleague left logged in on a shared laptop is the usual explanation), and
   a way out that suits the reader's own level. */
.p-denied{max-width:520px;text-align:left}
.p-denied-h{margin:18px 0 8px;font-size:22px;font-weight:800;color:var(--ink)}
.p-denied-b{margin:0 0 10px;color:var(--ink-soft);line-height:1.5}
.p-denied-who{margin:0 0 14px;padding:8px 12px;border:1px solid var(--line);
  border-radius:10px;color:var(--ink-soft);font-size:13px}
.p-denied .p-actcell{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
.p-denied .p-act{text-decoration:none;display:inline-block}

/* A heading INSIDE a settings section. The Schedules section holds three
   separate decisions (the lock, open-exception approval, the type list) and
   without a rung between the section title and the body they run together. */
.p-subh{margin:18px 0 6px;font-size:15px;font-weight:800;color:var(--ink)}
/* A <details> used as a card: the summary carries the old <h2> weight, and the
   marker sits where a reader expects to click. */
.p-card>summary.p-sect-h{cursor:pointer;font-size:18px;font-weight:800;margin:0}
.p-card[open]>summary.p-sect-h{margin-bottom:12px}

/* ---- My Schedule (TODO §4a.2a) -------------------------------------------
   The week is a row of seven day columns that collapse to a single column on
   a phone; the day view is the same markup with one column. Nothing here is
   a table, because a schedule with holes in it is not tabular data — a day
   somebody does not work has no cells at all. */
.p-schbar{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;margin:0 0 14px}
.p-schnav{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.p-schnav a{text-decoration:none}
.p-schrange{font-size:15px;color:var(--ink);min-width:150px;text-align:center}
.p-schgrid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;margin-bottom:22px}
/* The day view is ONE column, so it can afford to be wide — and it has to be
   when several exceptions stack: three lanes in a 420px card truncate every
   name. */
.p-schgrid-day{grid-template-columns:minmax(0,760px)}
.p-schday{background:var(--panel);border:2px solid var(--ink);border-radius:12px;padding:10px;min-width:0}
.p-schday-today{border-color:var(--blue);box-shadow:var(--pop)}
/* Locked is DIMMED, not hidden: a closed week is still the answer to "what
   did she work", it just cannot be changed. */
.p-schday-locked{opacity:.62}
.p-schhead{display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;margin-bottom:8px}
.p-schhead b{font-size:13.5px}
.p-schoff{margin:0;font-style:italic}
.p-schslots{list-style:none;margin:0;padding:0;font-size:12.5px}
.p-schslot{display:flex;flex-wrap:wrap;gap:4px;align-items:baseline;padding:3px 0;border-bottom:1px solid var(--line)}
.p-schslot:last-child{border-bottom:0}
.p-schhour{font-variant-numeric:tabular-nums;color:var(--ink-soft);min-width:44px}
/* A CLOSED hour is struck through: it is gone, and the strike says so at a
   glance without needing the legend. An open one is not. */
.p-schslot-closed .p-schhour{text-decoration:line-through}
.p-schnote{border-radius:999px;padding:1px 8px;font-size:11px;font-weight:700;white-space:nowrap}
/* CLOSED and OPEN must not be a matter of squinting: one means the hour is
   gone, the other means it is still there. Warm-red for gone, green for
   standing — the same two ideas the rest of the portal uses for refused and
   accepted. The ALL-DAY shade is deeper, because "out all day" and "out for
   an hour" are not the same news at a glance. */
.p-schnote-closed{background:#F6D2CC;color:#5A2018;border:1px solid #C98277}
.p-schnote-closed.p-schnote-allday{background:#E8574B;color:#fff;border-color:#26333B}
.p-schnote-open{background:#C4E3C0;color:#1F3D22;border:1px solid #7FA97F}
.p-schnote-open.p-schnote-allday{background:#4E8C55;color:#fff;border-color:#26333B}
/* Pending has NOT taken the hour away yet — dashed, so a request never reads
   as a decision. */
.p-schnote-pending{border-style:dashed;border-width:1.5px;border-color:#26333B}
/* An exception you may change is a control, and says so on hover. */
.p-schnote-edit{cursor:pointer}
.p-schnote-edit:hover{filter:brightness(1.08)}
.p-schnote-edit:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
/* A five-day week: the working days get the room the weekend was taking. */
.p-schgrid-5{grid-template-columns:repeat(5,minmax(0,1fr))}
.p-schgrid-day.p-schgrid-5{grid-template-columns:minmax(0,760px)}
/* The two context hours either side of a shift: present, plainly not on
   shift. */
.p-schslot-margin{opacity:.5}
.p-schslot-margin .p-schhour{font-style:italic}
.p-schpattern li{gap:12px}
.p-schrow{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.p-schrowname{min-width:110px}
.p-mini-select{max-width:110px}
@media (max-width: 900px){
  .p-schgrid,.p-schgrid-5{grid-template-columns:1fr}
  .p-schrange{min-width:0}
}
/* The team sections show the same week at a glance, so the columns are
   tighter and the hour list is capped — a lead scans for what is MISSING,
   and reading every hour of every person is not scanning. */
.p-schgrid-team{gap:6px;margin-bottom:6px}
.p-schgrid-team .p-schday{padding:7px}
.p-schgrid-team .p-schslots{max-height:150px;overflow-y:auto}
.p-schgrid-team .p-schhead b{font-size:12.5px}
/* Was #sch-pending, when there was one queue. There are two now — your own
   team's and, for a manager, everybody else's — so it is a class. */
.p-pendlist li{gap:10px;align-items:baseline}
/* The same trap `.p-fm label.p-pickrow` documents above: the global
   `input{width:100%}` stretches the tick to the full width of the row, which
   pushes it onto a line of its own and leaves it looking centred over a
   request rather than attached to one. */
.p-pendlist input[type=checkbox]{width:16px;height:16px;flex:none;
  margin:0;padding:0;accent-color:var(--fern);align-self:center}

/* An exception spanning consecutive hours is ONE bubble stretched over them,
   not the same words repeated on every row.

   The rows are a FIXED height so the span arithmetic is exact — with a
   min-height the bubble and the hours it covers drift apart as soon as a row
   wraps. Overlapping exceptions are laid out in columns: two facts about the
   same afternoon are two facts, and one drawn on top of the other is worse
   than no bubble at all. */
:root{--sch-row:26px;--sch-gut:50px}
.p-schslot{position:relative;height:var(--sch-row);padding:0;align-items:center}
.p-schgrid-team{--sch-row:24px;--sch-gut:44px}
.p-schnote-span{
  position:absolute;top:2px;z-index:1;
  /* One column per overlapping run, all sized against the same count so they
     line up down the day. */
  left:calc(var(--sch-gut) + (var(--sch-lane, 0) * (100% - var(--sch-gut) - 4px) / var(--sch-lanes, 1)));
  width:calc((100% - var(--sch-gut) - 4px) / var(--sch-lanes, 1) - 3px);
  /* Only as tall as the hours it covers, and no wider than its text needs
     when it has the column to itself. */
  max-width:190px;
  height:calc(var(--sch-span, 1) * var(--sch-row) - 5px);
  /* `align-items` centres ACROSS the column — the bubble is a flex column, so
     justify-content was already centring it vertically and left the text
     hard against the padding. Both axes now. */
  display:flex;flex-direction:column;justify-content:center;align-items:center;gap:0;
  border-radius:10px;padding:2px 8px;overflow:hidden;
  text-align:center;white-space:normal;line-height:1.15}
/* The name reads first; the length is a quieter second line rather than more
   words on the same one. */
.p-schnote-t{font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.p-schnote-n{font-style:normal;font-weight:600;opacity:.75;font-size:10px}
/* A one-hour bubble has no room for two lines. */
.p-schslot .p-schnote-span[style*="--sch-span: 1"] .p-schnote-n{display:none}

/* Dragging a child onto a team member. While one is held every member block
   reads as a possible destination, and the one under the pointer as THE
   destination — without the first, a drag gives no clue where it may be let
   go. */
.p-cl-drag{cursor:grab}
.p-cl-drag:active{cursor:grabbing}
body.p-dragging .p-teamblock[data-cl-target]{outline:1px dashed var(--line);outline-offset:2px}
.p-teamblock.p-cl-over{outline:2px solid var(--blue) !important;outline-offset:2px;background:var(--sky-soft)}
/* Nobody holds them, but their week is still arranged — a different job from
   placing a child with no sessions at all, so a different mark. */
.p-caselist li.p-row-tempfree{border-left:3px solid var(--blue);padding-left:9px}

/* A child somebody is responsible for who has nothing booked. Amber down the
   edge rather than a tinted row: the row already uses tint for archived, and
   two tints on one list stop meaning anything. */
.p-caselist li.p-row-nosession{border-left:3px solid var(--amber);padding-left:9px}

/* A child expected in an hour with nobody delivering it. Amber and dashed:
   amber because it needs attention rather than being an error, dashed because
   nothing is actually booked there — a solid chip would read as a session. */
.p-schgap{border:1px dashed #C9922B;background:#FDF3DC;color:#5A4213;
  border-radius:999px;padding:0 6px;font-size:11px;font-weight:700;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* The same fact on a day with no hours to hang it on. */
.p-schgapday{margin:2px 0 0;font-size:11px;font-weight:700;color:#5A4213;
  background:#FDF3DC;border:1px dashed #C9922B;border-radius:8px;padding:2px 6px}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .p-schgap, html:not([data-theme="light"]) .p-schgapday{background:#3A2E10;color:#F3DFAE;border-color:#8A6A20}
}
/* The same, chosen rather than inherited from the OS. */
html[data-theme="dark"] .p-schgap, html[data-theme="dark"] .p-schgapday{background:#3A2E10;color:#F3DFAE;border-color:#8A6A20}

/* Dragging. The grab cursor is the only affordance an hour cell can carry
   without adding furniture to a calendar that is already dense. */
.p-schnote-edit[draggable="true"],.p-schkid-drag{cursor:grab}
.p-schnote-edit[draggable="true"]:active,.p-schkid-drag:active{cursor:grabbing}
/* While something is held, every hour reads as a possible destination, and the
   one under the pointer reads as THE destination. Without the first half a
   drag gives no clue where it may be let go. */
body.p-dragging .p-schslot{outline:1px dashed var(--line);outline-offset:-1px}
body.p-dragging .p-schslot-margin{outline-color:transparent}
.p-schslot-over{background:var(--sky-soft);outline:2px solid var(--blue) !important;outline-offset:-2px}

/* The day name in the week view is the way into that day. */
.p-schdaylink{color:inherit;text-decoration:none;border-bottom:1px dotted currentColor}
.p-schdaylink:hover{color:var(--blue)}

/* The child in an hour. Sits left of the exception lanes so a session and the
   reason it may not happen are both readable at once. */
.p-schkid{font-size:11.5px;font-weight:700;color:var(--ink);background:var(--sky-soft);
  border:1px solid var(--line);border-radius:8px;padding:0 6px;max-width:120px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.p-schkid-x{padding:0 5px;font-size:11px;line-height:1.4}
/* An empty working hour offers itself, quietly: visible on hover or focus so
   a day full of plus signs does not read as a day full of content. */
.p-schfree{border:1px dashed var(--line);background:transparent;color:var(--ink-soft);
  border-radius:8px;padding:0 7px;font:inherit;font-size:11px;cursor:pointer;opacity:.35}
.p-schslot:hover .p-schfree,.p-schfree:focus{opacity:1;border-color:var(--blue);color:var(--blue)}

/* A few characters of the child's GUID, shown ONLY when another active child
   answers to the same name (owner, 2026-07-30). Duplicate names are allowed
   here on purpose, so the name alone cannot be the identifier; this is the
   smallest thing that makes two chips distinguishable without turning every
   other chip into a database row. Dimmed and monospaced so it reads as a
   reference rather than as part of the name. */
.p-schtag{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:9px;
  opacity:.55;letter-spacing:.02em;vertical-align:2px}

/* Schedules running out. Sits above the calendar because it is the one thing on
   this page that has a deadline: a term that ends is not visible anywhere else,
   an empty hour being the ordinary look of a free hour. Amber rather than red —
   nothing has gone wrong yet, and it is a week away. */
.p-schexp{border-left:3px solid var(--amber,#c8860a)}
.p-schexp .p-plainlist li{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:6px 0;border-bottom:1px solid var(--line)}
.p-schexp .p-plainlist li:last-child{border-bottom:0}
.p-inline-lab{font-size:11px;color:var(--ink-soft);margin-left:auto}
/* Narrow on purpose: it holds a number of weeks, and a full-width box invites
   the reader to think something longer belongs in it. */
.p-input-tiny{width:64px;flex:0 0 auto}

/* Which weekdays an hour applies to. Laid out as a row of small boxes rather
   than a stacked list: it is one decision about a week, and seven full-width
   rows read as seven decisions. */
.p-daypick{display:flex;flex-wrap:wrap;gap:4px 10px;margin:2px 0 6px}
.p-daypick .p-daybox{width:auto;flex:0 0 auto;margin:0;padding:2px 0}
.p-daypick .p-daybox span{font-size:12px}

/* One time slot on one line: the day, the hour, and the way to remove it. The
   markup shipped without this rule, so each slot stacked into three full-width
   blocks 123px tall and a five-slot week became 628px of content inside a 340px
   scroller — a list you could not see the shape of, which is the one thing a
   week editor has to show. */
.p-kidrow{display:flex;align-items:center;gap:6px;margin:0 0 6px}
.p-kidrow select{flex:1 1 auto;min-width:0;margin:0}
.p-kidrow select[data-kid-h]{flex:0 0 92px}
.p-kidrow button{flex:0 0 auto}

/* ---- WHAT SHOUTS, AND WHAT WHISPERS (owner, 2026-08-01) -------------------
   The loudest thing on the calendar was a salmon block saying "Sick", and the
   quietest was a small chip saying a child has nobody. An absence is a fact
   somebody has already recorded; an uncovered child is work that has to happen
   today. Those weights were backwards.

   So the exception bubble goes quiet — a tinted panel with a coloured edge
   rather than a filled slab — and amber becomes the only saturated fill on the
   grid. Kind is still legible at a glance from the edge colour: warm for hours
   taken away, green for hours that stay. */
.p-schnote-closed{background:#FBEEEB;color:#5A2018;border:1px solid #E2BAB2;
  border-left:4px solid #C9584A}
.p-schnote-closed.p-schnote-allday{background:#F7DFDA;color:#5A2018;
  border-color:#D9A79E;border-left:4px solid #C9584A}
.p-schnote-open{background:#EDF5EC;color:#1F3D22;border:1px solid #BBD4B8;
  border-left:4px solid #5E9366}
.p-schnote-open.p-schnote-allday{background:#DDEBDB;color:#1F3D22;
  border-color:#A8C6A5;border-left:4px solid #5E9366}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) /* The light fills were left untouched in dark mode, html:not([data-theme="light"]) which is where the
     inversion was worst: a near-white salmon slab on a navy page. */
  .p-schnote-closed{background:#33222A;color:#F0C4BC;border-color:#5C3A3A;
    border-left-color:#C9584A}html:not([data-theme="light"]) .p-schnote-closed.p-schnote-allday{background:#452A30;color:#F6D5CE;
    border-color:#70474A;border-left-color:#E8574B}html:not([data-theme="light"]) .p-schnote-open{background:#1F3327;color:#BEDCBB;border-color:#3D5A42;
    border-left-color:#5E9366}html:not([data-theme="light"]) .p-schnote-open.p-schnote-allday{background:#28422E;color:#CFE7CC;
    border-color:#4C6E52;border-left-color:#6FAE78}
}
/* The same, chosen rather than inherited from the OS. */
html[data-theme="dark"] /* The light fills were left untouched in dark mode, html[data-theme="dark"] which is where the
     inversion was worst: a near-white salmon slab on a navy page. */
  .p-schnote-closed{background:#33222A;color:#F0C4BC;border-color:#5C3A3A;
    border-left-color:#C9584A}html[data-theme="dark"] .p-schnote-closed.p-schnote-allday{background:#452A30;color:#F6D5CE;
    border-color:#70474A;border-left-color:#E8574B}html[data-theme="dark"] .p-schnote-open{background:#1F3327;color:#BEDCBB;border-color:#3D5A42;
    border-left-color:#5E9366}html[data-theme="dark"] .p-schnote-open.p-schnote-allday{background:#28422E;color:#CFE7CC;
    border-color:#4C6E52;border-left-color:#6FAE78}

/* Amber now carries the alarm alone, so it is allowed to be bright. */
.p-schgap{border:1.5px solid #C9922B;background:#FBE7B8;color:#4A3608;font-weight:800}
.p-schgapday{color:#8A6410;font-weight:800}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .p-schgap{background:#6A4E11;color:#FFF0C9;border-color:#D9A93A}html:not([data-theme="light"]) .p-schgapday{color:#F0CE72}
}
/* The same, chosen rather than inherited from the OS. */
html[data-theme="dark"] .p-schgap{background:#6A4E11;color:#FFF0C9;border-color:#D9A93A}html[data-theme="dark"] .p-schgapday{color:#F0CE72}

/* ---- AN EMPTY HOUR IS AN INVITATION, NOT A DEAD ROW ----------------------
   The `+` rested at .35 opacity and only surfaced on hover, so a day with room
   in it read as a broken grid rather than as availability. Booking is the whole
   reason this screen is interactive; the affordance should be visible without
   being hunted for. Still quiet enough that a full day is not a row of plus
   signs competing with the children's names. */
.p-schfree{opacity:.62}
.p-schslot:hover .p-schfree,.p-schfree:focus{opacity:1}

/* ---- THE TIME COLUMN READS AS TIME ---------------------------------------
   One face was doing every job on this page — names, hints, tags and hours
   alike — so the calendar read as a list that happens to contain times. A
   monospaced, slightly tighter column gives the grid a spine to scan down. */
.p-schhour{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:12px;letter-spacing:-.01em}

/* ---- SECTIONS START SOMEWHERE --------------------------------------------
   Headings were 13px uppercase in the same weight and colour as the hint text
   under them, so nothing told the eye where one section ended and the next
   began. Bigger, in the main ink, with air above. */
.p-sect-h{font-size:15px;color:var(--ink);letter-spacing:.04em}
.p-sect+.p-sect{margin-top:26px}

/* Seven day names on a flex row wrapped 6 + 1, leaving Sunday stranded on its
   own line. A grid wraps evenly whatever the language: Russian day names are
   half again as long as the English ones, so a rule that only looks right in
   one alphabet is not a rule. */
.p-daypick{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:2px 10px}

/* A control that is available but is not what the row is for. Ending an
   assignment sat in red beside Sessions, so the page's least-used action was
   its loudest; making them both plain fixed the shouting and left the row with
   no lead at all. This recedes instead: Sessions keeps ordinary weight and
   reads first, and the way to undo an assignment is there when looked for. */
.p-act-quiet{border-color:var(--line);color:var(--ink-soft)}
.p-act-quiet:hover{background:var(--ink-soft);border-color:var(--ink-soft);color:var(--paper)}

/* Measured after the recolour above: the exception panel came out at 1.09
   luminance contrast against the page in dark mode — quiet to the point of not
   reading as a panel at all, so a block spanning four hours lost its shape and
   only the left edge said anything. Amber sits at 2.11 and should keep the lead;
   these bring the absence back to roughly 1.5, present but plainly secondary. */
.p-schnote-closed{background:#F7E3DF}
.p-schnote-closed.p-schnote-allday{background:#F2D6D0}
.p-schnote-open{background:#E6F0E4}
.p-schnote-open.p-schnote-allday{background:#D7E8D4}
@media (prefers-color-scheme: dark){
html:not([data-theme="light"]) .p-schnote-closed{background:#3E2B33}html:not([data-theme="light"]) .p-schnote-closed.p-schnote-allday{background:#4C3038}html:not([data-theme="light"]) .p-schnote-open{background:#263B2D}html:not([data-theme="light"]) .p-schnote-open.p-schnote-allday{background:#2F4936}
}
/* The same, chosen rather than inherited from the OS. */
html[data-theme="dark"] .p-schnote-closed{background:#3E2B33}html[data-theme="dark"] .p-schnote-closed.p-schnote-allday{background:#4C3038}html[data-theme="dark"] .p-schnote-open{background:#263B2D}html[data-theme="dark"] .p-schnote-open.p-schnote-allday{background:#2F4936}

/* Measured in LIGHT mode: the amber chip sat at 1.16 against the page and the
   absence panel at 1.17 — indistinguishable, so the ordering this whole change
   exists to create held in dark mode and not in light. A pale fill cannot lead
   on a near-white page; luminance is the wrong lever there. This is the brand
   amber already used for the level badge and the notice bar, which puts the
   alarm at ~1.6 and well clear of the absence. */
.p-schgap{background:var(--amber);color:#3A2B05;border-color:#B07E12}
.p-schgapday{color:#7A5606}
@media (prefers-color-scheme: dark){
/* Unchanged: dark mode already had the ordering right. */
html:not([data-theme="light"]) .p-schgap{background:#6A4E11;color:#FFF0C9;border-color:#D9A93A}html:not([data-theme="light"]) .p-schgapday{color:#F0CE72}
}
/* The same, chosen rather than inherited from the OS. */
html[data-theme="dark"] .p-schgap{background:#6A4E11;color:#FFF0C9;border-color:#D9A93A}html[data-theme="dark"] .p-schgapday{color:#F0CE72}

/* The theme switch sits in the menu among the links, so it has to look like
   one: the only <button> in that list otherwise announces itself as a different
   kind of thing for no reason the reader benefits from. Matched to the anchors
   above it rather than to the sign-out button below, which is red on purpose. */
.p-menu-theme{display:block;width:100%;text-align:left;border:0;background:transparent;
  padding:8px 12px;border-radius:8px;font:inherit;font-size:15px;font-weight:700;
  color:var(--ink);cursor:pointer;white-space:nowrap}
.p-menu-theme:hover{background:var(--sky-soft)}

/* A schedule that something later took over. Recessive on purpose: the timeline
   is read to find what is in force and what is coming, and the weeks behind it
   are context. Distinct from the pending tag, which is a question still open. */
.p-tag-past{opacity:.65;font-style:italic}

/* ==== Site Reports (owner, 2026-08-04) ====================================
   Every colour below comes from a custom property, so light and dark are the
   same rules rather than two sets that drift apart. The last design pass on
   this project found an inversion that had survived a "fix" precisely because
   two themes were maintained side by side. */

.p-repbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;
  justify-content:space-between;margin:0 0 14px}
.p-repwin{display:inline-flex;flex-wrap:wrap;gap:4px;background:var(--cream);
  border:1px solid var(--line);border-radius:999px;padding:4px}
.p-repwin a{padding:5px 13px;border-radius:999px;text-decoration:none;
  color:var(--ink-soft);font-weight:700;font-size:14px}
.p-repwin a:hover{background:var(--sky-soft);color:var(--ink)}
.p-repwin a.on{background:var(--sky);color:var(--paper)}
.p-repacts{display:inline-flex;gap:8px;align-items:center}

/* The four headline figures. Number first and label under it: the number is
   what somebody came to read, and putting the word first makes them read a
   caption before they get to the answer. */
.p-repnums{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;
  list-style:none;margin:0 0 12px;padding:0}
.p-repnums li{display:flex;flex-direction:column;gap:2px}
.p-repnums b{font-size:30px;font-weight:900;line-height:1.05;letter-spacing:-.02em}
.p-repnums span{font-size:13px;color:var(--ink-soft);font-weight:600}

/* A bar per row. The track is always drawn, so a row with no visits reads as
   an empty bar rather than as a missing line — which is the whole reason the
   report lists every weekday and every hour including the quiet ones. */
.p-bars{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
.p-bars li{display:grid;grid-template-columns:minmax(84px,26%) 1fr auto;
  gap:10px;align-items:center}
.p-barlab{font-size:13px;color:var(--ink-soft);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The bar fill needs its OWN colour rather than a borrowed one.
   --sky is a pale background tint in light mode and a bright accent in dark,
   so using it here inverted with the theme: measured 1.37:1 against the track
   in light mode, where a bar chart stops carrying any information at all. A
   fill IS the data, so it is held to the 3:1 that non-text content needs, in
   both themes — light takes the solid blue, dark takes the bright sky. */
:root{--chart:var(--blue)}
@media (prefers-color-scheme: dark){html:not([data-theme="light"]){--chart:var(--sky)}}
html[data-theme="dark"]{--chart:var(--sky)}
html[data-theme="light"]{--chart:var(--blue)}

.p-bartrack{height:14px;background:var(--cream);border:1px solid var(--line);
  border-radius:999px;overflow:hidden}
.p-barfill{display:block;height:100%;background:var(--chart);border-radius:999px;
  min-width:2px}
.p-barnum{font-size:13px;font-weight:800;font-variant-numeric:tabular-nums;
  text-align:right;min-width:3.5em}

.p-repcols{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.p-repcols h3{font-size:14px;margin:0 0 8px;color:var(--ink)}

.p-notice-warn{border-left:4px solid var(--amber)}

@media (max-width:760px){
  .p-repnums{grid-template-columns:repeat(2,1fr)}
  .p-repnums b{font-size:25px}
  .p-repcols{grid-template-columns:1fr;gap:18px}
  .p-repbar{flex-direction:column;align-items:stretch}
  .p-repacts{justify-content:flex-end}
  .p-bars li{grid-template-columns:minmax(70px,34%) 1fr auto}
}

/* ---- PDF ---------------------------------------------------------------
   The owner asked for reports exportable to PDF. This IS that export: the
   browser's own print-to-PDF against these rules, so what is saved is what
   was on screen. A server-side renderer would be a second implementation of
   the same page, free to disagree with it after the next change.

   Controls are hidden because a printed page cannot be clicked, and the bars
   are forced to print their fill — browsers drop background colours by
   default, which would turn every chart into a row of empty tracks. */
@media print{
  .p-bar, .p-hmenu, .p-repbar, .p-impbar, .p-nav{display:none !important}
  body.portal{background:#fff;color:#000}
  .p-main{max-width:none;margin:0;padding:0}
  .p-card{break-inside:avoid;page-break-inside:avoid;box-shadow:none;
    border:1px solid #bbb;margin:0 0 12px}
  .p-repcols{grid-template-columns:repeat(3,1fr)}
  .p-bartrack{border:1px solid #999;background:#fff;
    -webkit-print-color-adjust:exact;print-color-adjust:exact}
  .p-barfill{background:#5b7f99 !important;
    -webkit-print-color-adjust:exact;print-color-adjust:exact}
  .p-hint, .p-note-hint{color:#333}
  a[href]:after{content:""}
}
