/* shell.css — /ui/v1 · the app shell s-* (Claude Design canvas "trinsik Portal und App-Drawer"): side bar with the app
   drawer on top, account at the bottom, phone top and bottom bar, skip link, login page. Markup: templates/portal/base.html.
   v1 changelog: 08.10.2026 split from static/css/portal.css (design system stage DS1); values as tokens.
   Breakpoints (tokens.css --bp-*, plan E5, since migration M4): below 1024 px the side bar folds away behind „Mehr“
   (top and tab bar, tablet and phone), below 768 px the phone rules; spacing on the --s* scale (M4: off-scale values
   rounded to the nearest step, a tie to the smaller one). The wordmark sizes (20/18/16 px) are the brand mark's own.
   08.10.2026 (Marcel: "das Menü ist besser strukturiert durch die Icons", as in the Brain): navigation with icons —
   icon + label in the side bar (platform_web.nav_item(icon=…), registry _docs/designsystem/icons.md), the collapsed
   rail html.s-rail (≥ 1024 px, icons only, labels as tooltips .s-tip), icon above the label in the bottom bar.
   11.10.2026 density: navigation rows, rail toggle, group chevron, „Melden“ and the account menu are --target high
   (32 px with a mouse, 44 px on touch and below 1024 px; were 40/44 px), the account button 44 px (was 52). */
/* wordmark and avatar of the shell */
.s-word { font-family: var(--wordmark); font-weight: 400; font-size: 20px; letter-spacing: -0.01em; text-decoration: none; }
.s-bracket { font-family: var(--serif); font-weight: 200; font-size: 20px; }
.s-avatar { flex: none; width: 36px; height: 36px; border-radius: 999px; background: var(--ink); color: var(--bg); display: flex;
  align-items: center; justify-content: center; font-size: var(--fs-hint); font-weight: 500; text-decoration: none; }
.s-avatar img { width: 100%; height: 100%; border-radius: 999px; object-fit: cover; display: block; }
/* the app drawer holds its 44 px before its script has run, so the wordmark beside it never jumps (Feedback loads it
   after hydration; guidelines §9: one left edge in the top bar) */
trinsik-app-drawer:not(:defined) { display: inline-block; flex: none; width: 44px; height: 44px; }

/* ── the shared app shell (Portal, HR): sidebar with drawer on top, account at the bottom; phone: top bar + bottom bar */
.s-app { display: flex; min-height: 100vh; min-height: 100dvh; }  /* dvh: the visible height on phone browsers (design panel M11) */
/* z-index: sticky makes the sidebar a stacking context — without one the app drawer opened in it lay under
   positioned content further down the page (record photo, 07.10.2026) */
.s-side { position: sticky; top: 0; z-index: var(--z-side); height: 100vh; width: var(--side-w); flex: none; display: flex; flex-direction: column; gap: var(--s2);
  background: var(--side); border-right: 1px solid var(--line); padding: var(--s4) var(--s3); box-sizing: border-box; overflow-y: auto; }
.s-brand { display: flex; align-items: center; gap: var(--s3); padding: 0 var(--s1) var(--s4); }
.s-name { display: flex; align-items: baseline; gap: var(--s1); text-decoration: none; color: var(--ink); min-width: 0; }
.s-name .s-word { font-size: 18px; } .s-name .s-bracket { font-size: 18px; }
/* a long app name (Reporting) stays on one line next to the drawer */
.s-name { white-space: nowrap; }
.s-brand:has(.s-name.long) { gap: var(--s2); }
/* … and one longer than the side bar (Gesprächspartner) puts the bracket under the word instead of being cut off */
.s-name.long { flex-wrap: wrap; row-gap: 0; }
.s-name.long .s-word, .s-name.long .s-bracket { font-size: var(--fs-text); }
.s-nav { display: flex; flex-direction: column; gap: 2px; }
.s-nav a { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); min-height: var(--target); padding: 0 var(--s3);
  color: var(--ink); text-decoration: none; font-size: var(--fs-table); }
.s-nav a:hover { background: var(--line); }
.s-nav a.on { background: var(--line); color: var(--ink); font-weight: 500; }
/* icons (decorative, 20 px, the label beside them): muted, ink on the current page — the eye finds the area by its shape */
.s-nav a .s-lbl { flex: 1; min-width: 0; }
.s-nav .k-ico, .s-rail-t .k-ico, .s-report .k-ico { flex: none; color: var(--muted); }
.s-nav a.on .k-ico, .s-nav a:hover .k-ico { color: var(--ink); }
.k-ico.s-rail-only { display: none; }  /* .k-ico (components.css) loads later */
/* the rail toggle under the navigation (≥ 1024 px; only when every entry has an icon) */
.s-rail-t { display: flex; align-items: center; gap: var(--s3); min-height: var(--target); margin-top: var(--s2); padding: 0 var(--s3); background: transparent; border: 0;
  color: var(--muted); font: var(--fs-hint) var(--sans); text-align: left; cursor: pointer; }
.s-rail-t:hover { background: var(--line); color: var(--ink); }
.s-rail-t:focus-visible, .s-nav a:focus-visible { outline: var(--focus-width) solid var(--ink); outline-offset: calc(-1 * var(--focus-width)); }
.s-rail-t .k-ico.on { display: none; }
.s-tip { position: fixed; z-index: var(--z-menu); transform: translateY(-50%); padding: var(--s1) var(--s2); background: var(--ink); color: var(--bg);
  font: var(--fs-hint) var(--sans); white-space: nowrap; pointer-events: none; }
.s-tip[hidden] { display: none; }
/* the collapsed rail: icons only, the label stays the link's name (visually hidden) and shows as a tooltip */
@media (min-width: 1024px) {
  html.s-rail .s-side { width: 72px; padding: var(--s4) var(--s3); }
  html.s-rail .s-brand { padding: 0 0 var(--s4); justify-content: center; }
  html.s-rail .s-brand .s-name { display: none; }
  html.s-rail .s-nav a, html.s-rail .s-rail-t { position: relative; justify-content: center; padding: 0; min-height: var(--target); }
  html.s-rail .s-nav .s-lbl, html.s-rail .s-rail-t .s-lbl, html.s-rail .s-report > span, html.s-rail .s-me-text {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  html.s-rail .s-sec { height: 1px; margin: var(--s3) var(--s2); padding: 0; overflow: hidden; color: transparent; background: var(--line); }
  html.s-rail .s-nav .s-count { position: absolute; top: 2px; right: 0; padding: 0 var(--s1); line-height: 16px; font-size: var(--fs-caps); }
  html.s-rail .s-nav .s-count:not(.strong) { background: var(--side); }
  html.s-rail .s-rail-t .k-ico.on { display: block; }
  html.s-rail .s-rail-t .k-ico.off { display: none; }
  html.s-rail .s-me { justify-content: center; padding: 0; }
  html.s-rail .s-report { justify-content: center; align-items: center; padding: 0; min-height: var(--target); }
  html.s-rail .k-ico.s-rail-only { display: block; }
}
.s-sec { padding: var(--s4) var(--s3) var(--s1); font-size: var(--fs-label); font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
/* „Einstellungen“ is always the last entry (Marcel 11.10.2026, platform_web.settings_last); after a section it stands
   apart on a hairline, so it does not read as part of that section */
.s-sep { width: 100%; margin: var(--s2) 0; border: 0; border-top: 1px solid var(--line); }
.s-count { font: var(--fs-label) var(--mono); color: var(--muted); }
.s-count.strong { background: var(--ink); color: var(--bg); padding: 2px var(--s2); border-radius: 999px; }
.s-nav a.on .s-count:not(.strong) { color: var(--ink); }
/* grouped navigation (Marcel 10.10.2026: „die Seiten bei ‚Bereiche' müssen doch auch in die Navigation“): an entry with
   sub-pages is a group — the entry itself (a link), a chevron button (aria-expanded) and its sub-entries indented under
   it (s-sub, each with its icon). Opt-in: platform_web.nav_item(children=[nav_sub(…)]), Feedback NavItem.children.
   Open while it holds the current page, otherwise as the viewer left it (localStorage trinsik_nav_open); at most ~7
   top-level entries, sub-entries do not count (guidelines §12.1). The rail (icons only) shows the entries without their
   sub-entries and marks the one that holds the current page (.in). */
.s-grp-h { display: flex; align-items: stretch; gap: 2px; }
.s-grp-h > a { flex: 1; min-width: 0; }
.s-grp-t { flex: none; display: flex; align-items: center; justify-content: center; width: var(--target); min-height: var(--target); padding: 0;
  background: transparent; border: 0; color: var(--muted); cursor: pointer; }
.s-grp-t::before { content: ""; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateX(-1px) rotate(-45deg); }
.s-grp-t[aria-expanded="true"]::before { transform: translateY(-2px) rotate(45deg); }
.s-grp-t:hover { background: var(--line); color: var(--ink); }
.s-grp-t:focus-visible { outline: var(--focus-width) solid var(--ink); outline-offset: calc(-1 * var(--focus-width)); }
.s-sub { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 var(--s1) calc(var(--s3) + 10px); padding-left: var(--s2);
  border-left: 1px solid var(--line); }
.s-sub[hidden] { display: none; }
.s-nav a.in { font-weight: 500; }
.s-nav a.in .k-ico { color: var(--ink); }
@media (min-width: 1024px) {
  html.s-rail .s-grp-t, html.s-rail .s-sub { display: none; }
  html.s-rail .s-nav a.in { background: var(--line); }
}
@media (max-width: 1023px) {
  .s-grp-t { width: var(--target); min-height: var(--target); }
}
.s-acct { position: relative; margin-top: auto; border-top: 1px solid var(--line); padding-top: var(--s2); }
/* „Melden“ under the account (UI review D6): a quiet line, the panel of report.js opens next to the side bar */
.s-report { width: 100%; display: flex; align-items: baseline; gap: var(--s2); min-height: var(--target); padding: 0 var(--s2) 0 calc(var(--s2) + 36px + var(--s2)); background: transparent;
  border: 0; color: var(--ink); font: var(--fs-hint) var(--sans); text-align: left; cursor: pointer; }
.s-report span:not(.s-lbl) { font-size: var(--fs-label); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.s-report .s-lbl { flex: none; }
.s-report:hover, .s-report[aria-expanded="true"] { background: var(--line); }
a.s-report, .s-menu > a.s-report-item { text-decoration: none; }  /* „Hilfe“ (P4): a link with the look of „Melden“ */
.s-menu > .s-report-item { display: none; }
.s-version { padding: 0 var(--s4) var(--s2); font: var(--fs-caps) var(--mono); color: var(--muted); }
.s-me { width: 100%; display: flex; align-items: center; gap: var(--s2); min-height: 44px; padding: 0 var(--s2); background: transparent;
  border: 0; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.s-me:hover, .s-me[aria-expanded="true"] { background: var(--line); }
.s-me-text { display: flex; flex-direction: column; min-width: 0; }
.s-me-text strong { font-size: var(--fs-table); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.s-me-text span { font-size: var(--fs-label); color: var(--muted); }
.s-menu { position: fixed; left: 12px; width: 232px; bottom: 76px; z-index: var(--z-side); background: var(--surface);
  border: 1px solid var(--line2); display: flex; flex-direction: column; }
.s-menu[hidden] { display: none; }
.s-menu > a { display: flex; align-items: center; min-height: var(--target); padding: 0 var(--s4); color: var(--ink); text-decoration: none; border-top: 1px solid var(--line); }
.s-menu > a:hover { background: var(--line); }
.s-who { display: flex; flex-direction: column; gap: 2px; padding: var(--s3) var(--s4); }
.s-who strong { font-weight: 500; } .s-who span { font-size: var(--fs-hint); color: var(--muted); overflow-wrap: anywhere; }
.s-theme { margin: 0; border: 0; border-top: 1px solid var(--line); padding: var(--s2) var(--s4) var(--s3); }
.s-theme legend { padding: var(--s2) 0 var(--s2); font-size: var(--fs-caps); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); float: left; width: 100%; }
.s-seg { clear: both; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--mark); }  /* --mark: 3:1 like k-btn.line (was --line2, 1,4–1,9:1) */
.s-seg label { position: relative; display: flex; align-items: center; justify-content: center; min-height: var(--target); cursor: pointer; font-size: var(--fs-hint); }
.s-seg label + label { border-left: 1px solid var(--mark); }
.s-seg input { position: absolute; opacity: 0; inset: 0; width: auto; height: auto; margin: 0; cursor: pointer; }
.s-seg input:checked + span { font-weight: 500; }
.s-seg label:has(input:checked) { background: var(--ink); color: var(--bg); }
.s-seg label:has(input:focus-visible) { outline: var(--focus-width) solid var(--ink); outline-offset: var(--focus-offset); }
.s-theme fieldset { margin: 0; padding: 0; border: 0; }
.s-seg.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.s-seg button { min-height: var(--target); border: 0; background: none; color: inherit; font: inherit; font-size: var(--fs-hint); cursor: pointer; }
.s-seg button + button { border-left: 1px solid var(--mark); }
.s-seg button[aria-pressed="true"] { background: var(--ink); color: var(--bg); font-weight: 500; }
.s-seg button:focus-visible { outline: var(--focus-width) solid var(--ink); outline-offset: var(--focus-offset); }
.s-content { flex: 1; min-width: 0; }
.s-content:focus { outline: none; }
/* skip link (WCAG 2.4.1): hidden until it gets the keyboard focus */
.s-skip { position: absolute; left: 8px; top: -60px; z-index: var(--z-skip); padding: var(--s2) var(--s3); background: var(--ink); color: var(--bg);
  font: 500 var(--fs-table) var(--sans); text-decoration: none; }
.s-skip:focus { top: 8px; }
.s-close { display: none; }
.s-top, .s-bottom { display: none; }
@media (max-width: 1023px) {
  .s-app { display: block; }
  .s-side { display: none; position: fixed; inset: 0 auto 0 0; z-index: var(--z-drawer); width: min(300px, 86vw); height: 100%; }
  .s-side.open { display: flex; box-shadow: 0 0 0 100vmax var(--scrim-strong); }
  .s-side.open .s-close { display: flex; align-items: center; justify-content: center; min-height: 44px; margin-top: var(--s2);
    background: transparent; border: 1px solid var(--line2); color: var(--ink); font: inherit; cursor: pointer; }
  .s-side .s-acct { display: none; }
  .s-top { display: flex; align-items: center; gap: var(--s2); position: sticky; top: 0; z-index: var(--z-bar); height: 64px; padding: 0 var(--s4);
    background: var(--bg); border-bottom: 1px solid var(--line); }
  .s-top .s-name .s-word, .s-top .s-name .s-bracket { font-size: 16px; }
  .s-top .s-name { align-items: center; min-height: var(--target); }
  .s-side .s-brand .s-name { align-items: center; min-height: var(--target); }  /* the app name is a link home: 44 px to touch (mobile pass 15.10.2026) */
  .s-me-mini { margin-left: auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; cursor: pointer; }
  .s-menu { left: 0; right: 0; width: auto; bottom: 0; top: auto; z-index: var(--z-menu); border: 0; border-top: 1px solid var(--ink); padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px)); }
  .s-menu > .s-report-item { display: flex; align-items: baseline; gap: var(--s2); min-height: 44px; padding: 0 var(--s4); background: transparent; border: 0;
    border-top: 1px solid var(--line); color: var(--ink); font: var(--fs-text) var(--sans); text-align: left; cursor: pointer; }
  .s-menu > .s-report-item span { font-size: var(--fs-hint); color: var(--muted); }
  .s-content { padding-bottom: calc(var(--bar-h) + var(--s3) + env(safe-area-inset-bottom, 0px)); }
  .s-bottom { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-bar);
    height: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px)); padding-bottom: env(safe-area-inset-bottom, 0px); background: var(--side); border-top: 1px solid var(--line); }
  /* env(safe-area-inset-*) is 0 until the viewport meta says viewport-fit=cover (iPhone home indicator; design panel M1) */
  .s-bottom a, .s-bottom button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 0 var(--s1); font: var(--fs-label) var(--sans); white-space: nowrap;
    color: var(--muted); text-decoration: none; background: transparent; border: 0; border-top: 2px solid transparent; cursor: pointer; text-align: center; }
  .s-bottom a.on, .s-bottom .s-more.on { color: var(--ink); font-weight: 500; border-top-color: var(--ink); }
  /* touch targets ≥ 44 px on phones (design panel M9): navigation and „Melden“ in the drawer */
  .s-nav a, .s-report { min-height: var(--target); }
  .s-bottom a, .s-bottom button { min-width: 0; overflow: hidden; padding-inline: 0; }  /* no side padding: „Abrechenbar“, „Rechnungen“ fit a fifth of 375 px (mobile pass 15.10.2026) */   /* labels never overlap: they shrink and end in "…" (UI review, 08.10.2026); „Mehr“ too, so 5 cells always fit 320–375 px (Abnahme 13.10.2026) */
  .s-bottom .s-lbl { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  /* the icon above the label (as in the Brain's phone view): the area is found by its shape, the label stays */
  .s-bottom .k-ico { flex: none; }
  .s-rail-t, .s-tip { display: none; }
  /* the count sits as a badge over the label's end, so the label keeps the whole cell and stays centred
     (it was squeezed to „Für …“ beside the pill; guidelines §9) */
  .s-bottom a { position: relative; }
  .s-bottom a > .s-count { position: absolute; top: var(--s1); right: var(--s1); padding: 0 var(--s1); line-height: 16px; }
}

/* login (no shell) */
.s-login { min-height: 100vh; min-height: 100dvh; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }
.s-login > div { padding: 56px clamp(24px, 6vw, 96px); display: flex; flex-direction: column; gap: var(--s5); }
.s-login .left { justify-content: space-between; border-right: 1px solid var(--line); }
.s-login .right { justify-content: center; }
.s-statement { font-family: var(--serif); font-weight: 200; font-size: clamp(40px, 6vw, 72px); line-height: 1.05; letter-spacing: -0.02em; text-wrap: balance; margin: 0; }
.s-login .k-head-text, .s-login .k-ph, .s-login .k-msg, .s-login .k-btn, .s-login .k-note { max-width: 420px; }
@media (max-width: 767px) { .s-login .left { border-right: 0; border-bottom: 1px solid var(--line); } }
/* 09.10.2026: iPhone safe area. templates/portal/base.html says viewport-fit=cover, so the page reaches under the notch
   and the home indicator; these keep content out of them (env() is 0 on every other device, so nothing moves there).
   iPhones are below 1024 px in both orientations, so the phone shell carries it: content and bars step in from the notch
   side in landscape (left/right), the top bar grows by the status bar of a home-screen app (top), the tab bar already
   sits above the home indicator (bottom, rules above), the drawer and the account sheet pad their edges. */
@media (max-width: 1023px) {
  .s-top { height: calc(64px + env(safe-area-inset-top, 0px)); padding-top: env(safe-area-inset-top, 0px);
    padding-left: calc(var(--s4) + env(safe-area-inset-left, 0px)); padding-right: calc(var(--s4) + env(safe-area-inset-right, 0px)); }
  .s-content { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
  .s-bottom { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
  .s-side { padding-top: calc(var(--s4) + env(safe-area-inset-top, 0px)); padding-left: calc(var(--s3) + env(safe-area-inset-left, 0px));
    padding-bottom: calc(var(--s4) + env(safe-area-inset-bottom, 0px)); }
  .s-menu { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
}
