﻿/* The tenant panel's own shell chrome: sidebar (and its mobile drawer), topbar, page title
 * and the read-only banner - see Pages/Shared/_TenantAppLayout.cshtml for why it exists as
 * its own escape rather than a LeptonX Lite override (there is no Application layout to
 * override; see that file's own remarks). Below the shell, this file also carries the
 * reusable component rules (button, input, file input, table, badge, tabs, alert, card,
 * list, empty state) a page opts into by class - see each section's own remarks for where
 * they came from.
 *
 * Unlike wwwroot/console/console.css, this stylesheet is NOT standalone: the tenant-facing
 * application keeps LeptonX Lite's own bundle (Bootstrap 5.3 among it), because roughly
 * eighty existing pages and every ABP module screen are written in Bootstrap classes
 * (docs/tenant-app-ui-design-brief.md). So every rule here is scoped to a `tapp-` prefixed
 * class, never a bare element selector (button, input, table, a) - the one thing that would
 * reach into a page's own Bootstrap markup and restyle it by accident. The `.cr` class
 * carries only custom properties, no rules of its own, for the same reason: declaring it as
 * an ancestor of the page body is unavoidable (the body sits inside the same flex shell),
 * but a variable declaration cannot touch anything that does not reference it, and nothing
 * outside this file does.
 *
 * The token set (--bg through --badbg) and every colour in it is taken verbatim from the
 * approved design (scratchpad/design/panel.dc.html, its own `.cr` rule) - not re-derived
 * from wwwroot/console/console.css's `.ac`, even though the two palettes are close: they
 * are two different design files for two different screens, and this one is authoritative
 * for the tenant panel.
 *
 * FAZ 6 (colour): the owner's complaint - "site çok renksiz... sade derken çirkin ve cansız
 * duruyor" - pointed at arcuby-hub's board-web panel as the reference
 * (apps/board-web/src/theme.generated.css). That file's dark grounds are warm (its surface/
 * border tokens carry a consistent R>G>B undertone); this file's were neutral, several of
 * them even drifting slightly cool (--card, --border, --thead etc. previously had B as the
 * *highest* channel). That neutrality - not the absence of accent colour - is judged to be
 * the bigger reason this panel read as lifeless, so --bg through --hover below are warmed
 * toward Hub's own ratio rather than left grey, and the light block is re-derived from a warm
 * cream ground to stay coherent with it (not Hub's own light values pasted in - contrast was
 * re-checked against this file's own text tokens, not assumed from the source). --brand-*
 * mirrors Hub's own five-colour set (cardVisuals.tsx's own reasoning: hash an id, get a
 * colour, so a reader learns a place's colour without reading) - same hex, since the two
 * products sharing one accent set is the point, not a coincidence to avoid. It is used here
 * only to colour the sidebar's own icons (MenuIconPalette, hashed server-side so the class is
 * in the markup before paint and never flashes in) - it is not a per-tenant accent and does
 * not touch AccentPaletteResolver's own --acc-* / --accent tokens, which are unrelated and stay.
 */

/* The canvas the browser paints before, between and around this document - the frame of
   ground shown on every navigation, the overscroll area, the scrollbar track, and the surface
   a native picker or a select's popup is drawn on. It is taken from the root element, not from
   body, which is why this rule is written against <html>'s own theme attribute rather than
   against .cr below: with it declared only on .cr, a dark panel still flashed white between
   pages and opened light date pickers inside a dark screen.
   Apple's own advice is to ease a brightness jump; here the jump cannot be eased, because the
   theme toggle reloads the page on purpose (the accent palette is resolved on the server), so
   the answer is to remove the jump instead. */
html[data-bs-theme="dark"] {
    color-scheme: dark;
}

html[data-bs-theme="light"] {
    color-scheme: light;
}

/* Shared, theme-independent primitives referenced from this file and from the other
   tenant-app stylesheets loaded on the same page (module-readonly.css, onboarding.css and
   its siblings). Unlike .cr's own set below, none of these flip between light and dark, so
   they belong on the true root rather than on the theme-scoped selector. This is a pure
   naming pass over values that were already written somewhere in this file as bare
   literals - no computed value changes by wiring a rule to one of these instead. */
:root {
    /* Radii, named by where the shared 999px/12px/10px/8px/7px/6px/5px steps land. */
    --r-pill: 999px;  /* fully round: pills, dots, avatars, switch tracks, scrollbar thumbs */
    --r-xl: 12px;     /* the largest card corner still short of a dialog */
    --r-card: 10px;   /* the default card/dialog corner across the panel */
    --r-ctl: 8px;      /* inputs, buttons and most other controls */
    --r-sm: 7px;       /* a step below --r-ctl, used by a handful of smaller cards/chips */
    --r-xs: 6px;       /* small tiles, icon buttons, note dots */
    --r-2xs: 5px;      /* the smallest corner still rounded rather than square */

    /* Below here, radii that do not belong to the shared step above - each used by one or
       two rules only, so (same reasoning as the font sizes just below) named by their
       literal value rather than folded into a scale word the file would not otherwise
       follow. Introduced when the architecture test that forbids a bare px radius in a
       rule found them still written as literals. */
    --r-20: 20px;      /* .tapp-badge, .tapp-chips .btn */
    --r-16: 16px;      /* install.css .tapp-install-sheet-body's own outer corner */
    --r-14: 14px;      /* install.css .tapp-install-bar-body's own corner */
    --r-9: 9px;        /* .tapp-card .card-header:first-child's own top corners */
    --r-4: 4px;        /* .tapp-check, .tapp-slice-bar */
    --r-3: 3px;        /* .tapp-staff-bar and its fill */
    --r-2: 2px;        /* .tapp-chart-swatch */

    /* Font sizes, named by their literal value: this panel's type sizes were not written
       against a single ratio scale, so a numeric name is the honest one rather than an
       invented xs/sm/md that would imply an order the file does not actually follow. */
    --t-10: 10px;
    --t-11: 11px;
    --t-11-5: 11.5px;
    --t-12: 12px;
    --t-12-5: 12.5px;
    --t-13: 13px;
    --t-13-5: 13.5px;
    --t-15: 15px;

    /* The dialog shadow and its backdrop scrim, repeated by every modal in this file. */
    --shadow-dlg: 0 18px 48px rgba(0, 0, 0, .55);
    --scrim: rgba(0, 0, 0, .55);

    /* Named by what draws them, same reasoning as --shadow-dlg above - each is a different
       depth/opacity a design actually used, not points on a scale. */
    --shadow-pop: 0 20px 48px rgba(0, 0, 0, .28);    /* .tapp-nav-hidden's fixed popover */
    --shadow-menu: 0 12px 28px rgba(0, 0, 0, .28);   /* .tapp-daterange's dropdown menu */
    --shadow-panel: 0 18px 48px rgba(0, 0, 0, .45);  /* .tapp-dr, the daily-reminders window */
    --shadow-sheet: 0 18px 40px rgba(0, 0, 0, .25);  /* install.css's install sheet */
    --shadow-bar: 0 14px 34px rgba(0, 0, 0, .28);    /* install.css's install offer bar */
    --shadow-dlg-tight: 0 18px 40px -24px rgba(0, 0, 0, .55); /* modules-mine.css's .tapp-ml-dlg - same colour as --shadow-dlg, tighter spread */

    /* Scrims other than --scrim above - each a different backdrop a design actually used. */
    --scrim-native: rgba(0, 0, 0, .5);   /* .tapp-dialog::backdrop, the native <dialog> element's own */
    --scrim-sheet: rgba(0, 0, 0, .45);   /* install.css's install sheet backdrop */

    /* The hover/focus transition timing repeated throughout - written both as 120ms and
       as .12s depending on the rule, but the same duration either way. */
    --t-fast: 120ms ease;

    /* White text or icon drawn on a solid accent fill (primary buttons, active chips, the
       checked checkbox's mark, the active pager button). */
    --on-accent: #fff;

    /* The opposite: dark ink drawn on a bright brand-coloured fill (the primary button's
       text in the dark theme, a module tile's icon whose background is a hashed --brand-*
       hue) - theme-independent, unlike --on-indigo would have to be, because neither
       caller flips it in the light theme either. */
    --on-brand: #15130f;

    /* One-off translucent overlays that are not a scrim (those dim a whole surface behind a
       dialog; these sit on top of a small, already-coloured element). */
    --overlay-white: rgba(255, 255, 255, .25);  /* .tapp-chips .badge.bg-light.text-dark's own wash */
    --swatch-ring: rgba(0, 0, 0, 0.12);         /* the calendar swatch's outline against its own inline colour */
}

/* On a phone the reading sizes step up and fold together. The panel's text was 13-13.5px at
   arm's length on a 360px screen, under the 16px the web treats as a body minimum and well
   under iOS's own 17pt (Apple, "The Details of UI Typography"); and a page used eight to
   fifteen distinct sizes, several of them half a pixel apart, which the eye reads as noise
   rather than as hierarchy. Here the half steps collapse into their neighbours and the
   running text lands at 15-16px. Only the tokens move, so every rule that already uses
   them follows; the shell's own inherited size is the 16px body. */
@media (max-width: 767.98px) {
    :root {
        --t-11-5: 12px;
        --t-12: 13px;
        --t-12-5: 13px;
        --t-13: 15px;
        --t-13-5: 15px;
        --t-15: 16px;
    }

    .tapp-shell {
        font-size: 16px;
    }
}

/* ---------------------------------------------------------------- palette layer

   A palette is the ground/text set the panel paints with: --bg, --card, --border,
   --input, --body, --head, --muted, --thead, --side, --hover and --zebra - the eleven
   tokens consumed throughout this file wherever a surface or a piece of text is
   drawn. The [data-bs-theme] block above still decides light or dark; a palette only
   decides what colour each of those two variants actually is, which is why every
   palette below is written as a pair of rules - one for dark, one qualified
   [data-bs-theme="light"] - covering the same eleven names both times. Adding a
   palette means adding one such pair here; nothing else in this file changes.

   A palette must NOT declare --ok/--okbg/--warn/--warnbg/--bad/--badbg (status
   colours carry meaning, not identity, and stay identical across every palette) or
   --brand-* (Hub's own shared, hashed icon hues - see the FAZ 6 remark at the top of
   this file for why those are neither a per-tenant nor a per-theme colour). It must
   not declare --acc-* or --accent either - those belong to AccentPaletteResolver and
   are the tenant's own colour, not the panel's.

   "arcuby" is the shipped default and is byte-for-byte what .cr and
   .cr[data-theme="light"] used to hardcode directly below - a visitor with no
   Theming.ThemeConsts.PaletteCookieName cookie, or an unrecognised one, resolves to
   this palette (ThemeConsts.DefaultPalette) and the panel looks exactly as it did
   before this layer existed. "koyu-mavi" is a second palette added only to prove the
   layer actually drives the panel's colours: a blue-grey ground in both variants,
   with its own text-on-surface contrast checked directly rather than assumed from
   "arcuby"'s numbers. */
:root,
:root[data-palette="arcuby"] {
    --bg: #15130f;
    --card: #201d19;
    --border: #302b25;
    --input: #161310;
    --body: #d7d2c7;
    --head: #ece6dc;
    --muted: #9c948a;
    --thead: #1c1916;
    --side: #1b1815;
    --hover: #292420;
    --zebra: transparent;

    /* The hue a translucent scrim over THIS palette should carry - declared once here,
       not repeated in the [data-bs-theme="light"] block below, so it stays the palette's
       own dark ground in both theme modes rather than flipping to the light block's cream
       --bg (a near-white scrim would barely dim anything). Consumed as
       color-mix(in srgb, var(--scrim-tint) NN%, transparent) wherever a rule used to hardcode
       rgba(21, 19, 15, NN%) - this "arcuby" value is that same #15130f, byte for byte, so
       the fix changes nothing under the shipped default; a differently-hued palette now gets
       its own tint instead of staying stuck on arcuby's brown. */
    --scrim-tint: #15130f;
}

:root[data-bs-theme="light"],
:root[data-palette="arcuby"][data-bs-theme="light"] {
    --bg: #faf7f2;
    --card: #ffffff;
    --border: #e4ddd2;
    --input: #f3efe8;
    --body: #4a443c;
    --head: #24201b;
    --muted: #857d72;
    --thead: #f1ece4;
    --side: #f5f1ea;
    --hover: #ece6dc;
    --zebra: #faf7f2;
}

:root[data-palette="koyu-mavi"] {
    --bg: #12161d;
    --card: #1a2029;
    --border: #2a3240;
    --input: #141920;
    --body: #cfd6e0;
    --head: #eef1f5;
    --muted: #8c96a6;
    --thead: #171c24;
    --side: #161b23;
    --hover: #232a35;
    --zebra: transparent;

    /* Same reasoning as "arcuby"'s own --scrim-tint above: this palette's dark ground,
       constant across both theme modes rather than flipping in the light variant. */
    --scrim-tint: #12161d;
}

:root[data-palette="koyu-mavi"][data-bs-theme="light"] {
    --bg: #eef1f6;
    --card: #ffffff;
    --border: #d7dee8;
    --input: #e4e9f0;
    --body: #3c4552;
    --head: #1b212b;
    --muted: #6b7684;
    --thead: #e7ebf1;
    --side: #e9edf3;
    --hover: #dde3ec;
    --zebra: #eef1f6;
}

.cr {
    /* The same declaration one level down, where a control actually reads it: a date picker
       or a select popup inside the panel takes its own surface from the nearest ancestor that
       declares one, and until this pair existed both opened as light panes inside a dark
       screen. */
    color-scheme: dark;

    /* --bg through --zebra are no longer declared here - they cascade down from the
       palette layer above (:root / :root[data-palette]) by inheritance, since this rule
       no longer sets them itself. Only the tokens a palette must not own stay local
       to the mode block that colours them. */
    --ok: #5fd67a;
    --okbg: rgba(47, 179, 68, .14);
    --warn: #f0b45a;
    --warnbg: rgba(245, 159, 0, .14);
    --bad: #f07070;
    --badbg: rgba(224, 49, 49, .15);
    --brand-indigo: #8084fc;
    --brand-purple: #d05bfb;
    --brand-pink: #f84f98;
    --brand-cyan: #0cb6eb;
    --brand-green: #14a656;
    /* Four hues added for the 21 September 2026 top-level colour collision fix
       (MenuIconPalette's own remarks) - same bright, fully-saturated register as the five
       above. */
    --brand-amber: #f2a93c;
    --brand-teal: #2dd4bf;
    --brand-rose: #fb6f92;
    --brand-blue: #3b9eff;
    /* Three spares no module declares - MenuIconPalette.AssignDistinct hands them to a
       favourite whose own colour is already on screen (23 September 2026). Picked to sit
       away from every hue above: a true red, a yellow-green, an orange with more red in it
       than amber has. */
    --brand-red: #f87171;
    --brand-lime: #a3e635;
    --brand-orange: #fb7c2c;
}

/* Status and brand colours only now - --bg through --zebra used to be hardcoded here
   too, but now come from the palette layer above ("arcuby"'s own light block), which
   carries the same warm-cream ground this rule always painted. --brand-* stays
   darkened here rather than reused from the dark block: those hues fill a menu tile
   whose glyph is drawn in var(--bg), and at their dark-theme brightness that glyph
   disappeared against a light ground. */
.cr[data-theme="light"] {
    color-scheme: light;

    --ok: #1f8a4c;
    --okbg: #e8f5ec;
    --warn: #b26a12;
    --warnbg: #fdf1e0;
    --bad: #c0392f;
    --badbg: #fbeae8;
    --brand-indigo: #4f52d6;
    --brand-purple: #9b2bc4;
    --brand-pink: #c81a63;
    --brand-cyan: #0a7ea4;
    --brand-green: #0f7a3f;
    /* Darkened the same way as the five above, and for the same reason (this block's own
       comment): a menu tile's glyph is drawn in var(--bg), so the dark-block brightness of
       amber/teal/rose/blue would leave the glyph illegible against a light ground. */
    --brand-amber: #8a5a08;
    --brand-teal: #0f766e;
    --brand-rose: #9d174d;
    --brand-blue: #1660c9;
    --brand-red: #b91c1c;
    --brand-lime: #4d7c0f;
    --brand-orange: #c2410c;
}

/* ---------------------------------------------------------------- utility */

/* The single visibility switch this shell has. It carries !important because everything it
   hides - a card, a band, an alert strip - declares its own `display: flex` on the element
   itself, and a utility that loses that race silently does nothing. Its reach is only the
   elements this class is put on, so it cannot touch an ABP module screen under the same
   shell, which is the property the whole file is scoped for. */
.tapp-off {
    display: none !important;
}

/* ---------------------------------------------------------------- navigation progress */

/* ARCP-139 item 4: does not make a navigation faster - it makes the click register
   immediately, which is the actual complaint ("her boka refresh yapıyor"). tenant-app.js adds
   `.is-active` on a link click or a form submit and never has to take it off itself: a real
   navigation replaces the document before the bar would finish, and a page restored from the
   back-forward cache never re-runs this script at all. Sits above the sidebar drawer (z-index
   41) and the notification panel (60) - see tenant-app.js's own remarks for the one case
   (a cancelled navigation) this leaves it sitting at width. */
.tapp-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 0;
    height: 2px;
    z-index: 100;
    background: var(--acc-solid, var(--accent));
    opacity: 0;
    pointer-events: none;
    transition: width 4s cubic-bezier(.1, .7, .3, 1), opacity .15s ease-out;
}

.tapp-progress.is-active {
    width: 85%;
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    /* No sliding growth - the bar simply appears, static, rather than animating toward 85%. */
    .tapp-progress {
        transition: none;
    }
}

/* ---------------------------------------------------------- basılma tepkisi
 *
 * Feedback belongs on the press, not on the release (Apple, "Designing Fluid Interfaces"
 * §1): a surface that only answers :hover answers nothing at all on a phone, and on a
 * desktop it answers before the click rather than at it. Until this rule the whole panel
 * had exactly one pressed state - the primary button's own brightness dip.
 *
 * Two different answers, because two different things are being pressed. A control (a
 * button, a chip, a segment, a close cross) gives a little under the finger, the way a real
 * key does. A row or a card - things that are mostly text, often the full width of the
 * screen - dims instead: scaling a table row drags every column with it and reads as a
 * glitch rather than a press.
 *
 * Kept off :focus deliberately. A keyboard user gets the focus ring, not a permanently
 * squashed button. */
.tapp-btn:not(:disabled):active,
.tapp-iconbtn:active,
.tapp-chip:active,
.tapp-seg-item:active,
.tapp-pager-btn:active,
.tapp-period-nav:active,
.tapp-bell:active,
.tapp-theme:active,
.tapp-burger:active,
.tapp-dr-x:active,
.tapp-tdo-x:active,
.tapp-wo-pick-x:active,
.tapp-rl-search-clear:active,
.tapp-yn-danger-btn:active,
.tapp-staff-pay:active,
.tapp-sf-ctl:active {
    transform: scale(.97);
    transition: transform 90ms ease-out;
}

.tapp-nav-row:active,
.tapp-nav-item:active,
.tapp-nav-fav:active,
.tapp-nav-group-label:active,
.tapp-list-item:active,
.tapp-yn-link:active,
.tapp-ay-nitem:active,
.tapp-ay-mod-item:active,
.tapp-dr-row:active,
.tapp-rl-row:active,
.tapp-rl-gitem:active,
.tapp-rl-perm-row:active,
.tapp-ku-row:active,
.tapp-ku-rolrow:active,
.tapp-ku-mitem:active,
.tapp-notif-item:active,
.tapp-trio-item:active,
.tapp-tdo-i:active,
.tapp-wo-row:active,
.tapp-wo-rowlink:active,
.tapp-wo-card:active,
.tapp-wo-tile:active,
.tapp-wo-step:active,
.tapp-wo-link:active,
.tapp-wo-more:active,
.tapp-wo-res:active {
    filter: brightness(.93);
    transition: filter 90ms ease-out;
}

/* ------------------------------------------------------- hareket ve saydamlık
 *
 * The panel had prefers-reduced-motion on five rules and forty-odd transitions ignoring it.
 * A blanket first, exceptions never: every one of those transitions exists to soften a
 * change, and a reader who has asked for less motion is asking for the change without the
 * softening - not for the change to be withheld. Durations are shortened to nothing rather
 * than removed, so a transitionend handler still fires and nothing waits forever.
 *
 * The two neighbouring queries are answered as well, since a reader who turns one of these
 * on has usually turned the others on too: less transparency means a solid surface, more
 * contrast means a visible edge on every card. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

@media (prefers-contrast: more) {
    .tapp-card,
    .tapp-pr-card,
    .tapp-dialog,
    .tapp-input,
    .tapp-btn {
        border-color: var(--head);
    }
}

/* ---------------------------------------------------------------- shell */

/* The ground the browser paints a new document on. `.tapp-shell` below already carries
   var(--bg) and covers the viewport, but it is a child of <body> - and the canvas, which is
   what shows during the frame before the shell is laid out, in overscroll, and behind a
   scrollbar, is propagated from <body> instead. Left alone that background is Bootstrap's
   (--bs-body-bg: #212529 in dark, #fff in light), neither of which is this palette's ground
   (#15130f / #faf7f2). One value in a single-page app is a detail nobody sees; on a
   server-rendered panel it is a differently coloured frame on every single navigation.

   Class-scoped, like every other rule in this file: a bare `body` selector is the one thing
   this stylesheet must not do (see the file's own opening remarks), so <body> opts in by
   carrying `cr` - see Pages/Shared/_TenantAppLayout.cshtml's own remarks on why. */
body.cr {
    background: var(--bg);
}

/* The shell owns the viewport rather than growing with the page: the sidebar and topbar have
   to stay put while a long list moves under them, which a document-level scroll cannot do. */
.tapp-shell {
    display: flex;
    align-items: stretch;
    height: 100vh;
    overflow: hidden;
    background: var(--bg);
    color: var(--body);
    font-family: 'Manrope', 'Inter', system-ui, sans-serif;

    /* Every scrollbar inside the panel, in one declaration: scrollbar-color inherits, so a
       box that scrolls anywhere below here is themed without having to remember. The browser
       default is a light grey bar, which on the dark theme sat on the sidebar as a bright
       white stripe - reported 7 September, and more visible since .tapp-nav started reserving
       the gutter. The board's own rules below predate this and say the same thing about the
       warm palette; they stay because they also size the bar. */
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

/* The same for browsers that never shipped scrollbar-color (Chrome before 121, Safari before
   18). Only inside the panel: the console draws its own shell. */
.tapp-shell ::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

.tapp-shell ::-webkit-scrollbar-track {
    background: transparent;
}

.tapp-shell ::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: var(--r-pill);
    transition: background-color var(--t-fast);
}

.tapp-shell ::-webkit-scrollbar-thumb:hover {
    background: var(--muted);
}

.tapp-body {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    gap: 0;
}

/* This is the element that scrolls, which is why it needs `min-height: 0` - a flex child's
   default `min-height: auto` refuses to shrink below its content and the scroll never
   arrives at the child that was supposed to take it. */
.tapp-main {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 26px 28px 40px;
    display: flex;
    flex-direction: column;
    gap: 22px;
    background: var(--bg);
}

/* `.tapp-main` is a column flexbox that scrolls, so nothing inside it should ever be made
   shorter than its own content - and by default everything is: a flex item's `flex-shrink` is
   1, and the pane's height is definite, so an overlong page is resolved by squashing children
   rather than by scrolling.

   Most children survive that because their automatic minimum size is their content. A child
   that establishes its own scroll container does not: `overflow: hidden` sets its min-height
   to 0, so it shrinks to whatever is left. That is what hid the cariler list - the table wrap
   clips its own corners to the 10px radius, the pane squeezed it to 84px, and two of the three
   rows were behind the fold while the counter above them said three. Reported 7 September 2026
   as "the list is not drawing". */
.tapp-main > * {
    flex-shrink: 0;
}

/* The product credit line (Components/ArcubyCredit) is the last child of the scrolling column,
   because `.tapp-main` is what scrolls - the shell around it is exactly the window's height.
   `margin-top: auto` is what keeps a short page honest: with room to spare the line settles at
   the foot of the column instead of floating directly under a half-empty panel, and on a page
   taller than the window there is no spare room, so it simply follows the last card down. The
   column's own 22px gap is the space above it; its top padding would only double that. */
.tapp-main > .acb-credit-foot {
    margin-top: auto;
    padding-top: 0;
}

/* The legal links (Components/LegalFooter) sit directly above the credit line in the panel,
   so they take over the `margin-top: auto` that settles the foot at the bottom of a short
   page, and the credit line simply follows them. */
.tapp-main > .acb-legal-foot {
    margin-top: auto;
    padding-top: 0;
}

.tapp-main > .acb-legal-foot + .acb-credit-foot {
    margin-top: 0;
}

/* ---------------------------------------------------------------- sidebar */

.tapp-side {
    flex: 0 0 250px;
    width: 250px;
    min-height: 0;
    margin: 0;
    padding: 0;
    gap: 0;
    background: var(--side);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
}

/* No fixed height any more: the brand block carries the tenant's own name under the product
   name, and a second line does not fit in the topbar's 52px. */
.tapp-side-head {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 14px 14px 12px;
    border-bottom: 1px solid var(--border);
}

/* The logo is a link to the dashboard as well as the text beside it (ARCP-149). It is a
   bare anchor: no padding, no underline, and `flex-shrink: 0` so wrapping the image in it
   cannot let the logo be squeezed by a long tenant name the way the text block may be. */
.tapp-side-brand-logo {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    text-decoration: none;
}

/* Two stacked lines that must ellipsis instead of widening their rail - the
   brand/tenant pair here, the signed-in user's name/role at .tapp-user-text
   (that rail is 250px) - both rely on the same `min-width: 0` escape. */
.tapp-side-brand-text,
.tapp-user-text {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
    line-height: 1.25;
}

/* The tenant's own name, the brand block's first line. One line only: the rail is 250px wide
   and a long company name is the thing that would widen it, so it ellipsises rather than
   wraps into the logo beside it. */
.tapp-tenant-name {
    font-size: var(--t-13-5);
    font-weight: 700;
    letter-spacing: -.2px;
    line-height: 1.25;
    color: var(--head);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Drawn only when the tenant has no logo of its own - initials on the tenant's accent, never
   on a brand hue, since --brand-* identifies a module and not a company. */
.tapp-brand-initials {
    width: 28px;
    height: 28px;
    flex: 0 0 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-sm);
    background: var(--acc-soft, var(--hover));
    border: 1px solid var(--border);
    color: var(--acc-text, var(--head));
    font-size: var(--t-11);
    font-weight: 700;
    letter-spacing: .4px;
}

.tapp-logo {
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    border-radius: var(--r-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--acc-soft);
    color: var(--acc-text);
    font-size: var(--t-12);
    font-weight: 700;
}

/* Wraps the menu filter so the magnifier can sit inside the field rather than beside it: a
   250px rail has no column to spare for an icon of its own. */
.tapp-side-search {
    position: relative;
    display: block;
    padding: 12px 12px 4px;
}

/* Centred on the input, not on the wrapper - hence the offset by half the wrapper's own
   uneven vertical padding. Never a click target, so it is taken out of hit testing. */
.tapp-side-search > i {
    position: absolute;
    left: 23px;
    top: calc(50% + 4px);
    transform: translateY(-50%);
    font-size: var(--t-11);
    color: var(--muted);
    pointer-events: none;
}

/* The field tenant-app.js narrows the menu against (#tapp-nav-filter). The wide left padding
   is what keeps typed text clear of the glyph above; `box-sizing` because LeptonX's own
   bundle is loaded here and this file may not assume a page-wide reset it did not set. */
.tapp-nav-filter {
    width: 100%;
    box-sizing: border-box;
    padding: 8px 11px 8px 30px;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: var(--input);
    color: var(--head);
    font-family: inherit;
    font-size: var(--t-13);
}

.tapp-nav-filter::placeholder {
    color: var(--muted);
}

.tapp-nav-filter:focus {
    outline: none;
    border-color: var(--accent);
}

/* `scrollbar-gutter: stable` is what stops the menu twitching. This box scrolls, and on a
   platform with classic (non-overlay) scrollbars the bar is 15px of real width that appears
   only once the content is tall enough to need it - so opening a module, or landing on a page
   whose remembered groups are restored on the first frame, took 15px away from every label at
   once and gave it back when they closed again. Reserving the gutter whether or not the bar is
   there costs a fixed 15px inside a 250px rail and buys a menu that never moves sideways.
   Reported 7 September 2026 as "the sidebar narrows and widens when I pick a module". */
.tapp-nav {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-gutter: stable;
    padding: 4px 10px 14px;
    display: flex;
    flex-direction: column;
    gap: 0;
}

/* One heading and the entries under it, moving as a single block. `gap: 1px` rather than 0:
   the rows carry their own hover background, and a hairline between them is what stops two
   adjacent hovers reading as one target. */
.tapp-nav-section {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* A signpost, not an entry - uppercase and widely tracked at --muted so it never competes
   with the module names it sits over. */
.tapp-nav-section-label {
    padding: 14px 9px 5px;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color: var(--muted);
}

/* The first section follows the search field rather than a list of entries, so it needs less
   air above it than the ones after it. */
.tapp-nav-section:first-child .tapp-nav-section-label {
    padding-top: 10px;
}

.tapp-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    height: 34px;
    padding: 0 9px;
    border: 0;
    border-radius: var(--r-ctl);
    font-size: var(--t-13);
    text-align: left;
    text-decoration: none;
    color: var(--body);
    background: transparent;
}

a.tapp-nav-item:hover {
    background: var(--hover);
    color: var(--head);
    text-decoration: none;
}

.tapp-nav-item > i,
.tapp-nav-group-label > i:first-child {
    width: 15px;
    flex: 0 0 15px;
    font-size: var(--t-13);
    text-align: center;
    opacity: .9;
}

/* The filled tile a top-level entry draws its glyph on. Only the shape lives here - the fill
   is whichever .tapp-nav-icon-* class below the server picked. The glyph is var(--bg) because
   that fill is always a bright brand hue and the mark on it has to be as dark as the page
   ground, which is the same reasoning the palette block states next. */
.tapp-nav-icon {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-xs);
    font-size: 10.5px;
    color: var(--bg);
}

/* FAZ 6: one of the five brand hues, assigned to a menu entry's own key by
   MenuIconPalette.ClassFor (Pages/Shared/_TenantNavItem.cshtml) - hashed server-side so the
   class is already in the markup on first paint, never added by script after the fact. Kept
   to the icon (not the row's background or label) - the row still reads active/hover through
   the tenant's own accent tokens above; this is what makes a module recognisable at a glance,
   not a second accent system.
 *
 * There are two sets because one module colour has to survive two different marks. A
 * top-level entry carries a filled tile, so the hue is the tile's `background` and the glyph
 * sitting on it is drawn in var(--bg); a sub-entry carries a bare glyph one step quieter, so
 * the same hue is the glyph's own `color` instead. Same five names, same five values - the
 * only difference is which property the hue lands on, and a caller picks the set by which
 * mark the row draws, never by which colour it wants. */

.tapp-nav-icon-indigo {
    background: var(--brand-indigo);
}

.tapp-nav-icon-purple {
    background: var(--brand-purple);
}

.tapp-nav-icon-pink {
    background: var(--brand-pink);
}

.tapp-nav-icon-cyan {
    background: var(--brand-cyan);
}

.tapp-nav-icon-green {
    background: var(--brand-green);
}

/* Four more, added with amber/teal/rose/blue above (MenuIconPalette's own remarks) -
   same shape as the original five. */
.tapp-nav-icon-amber {
    background: var(--brand-amber);
}

.tapp-nav-icon-teal {
    background: var(--brand-teal);
}

.tapp-nav-icon-rose {
    background: var(--brand-rose);
}

.tapp-nav-icon-blue {
    background: var(--brand-blue);
}

/* The three spares, same shape again. */
.tapp-nav-icon-red {
    background: var(--brand-red);
}

.tapp-nav-icon-lime {
    background: var(--brand-lime);
}

.tapp-nav-icon-orange {
    background: var(--brand-orange);
}

.tapp-nav-subicon-indigo {
    color: var(--brand-indigo);
}

.tapp-nav-subicon-purple {
    color: var(--brand-purple);
}

.tapp-nav-subicon-pink {
    color: var(--brand-pink);
}

.tapp-nav-subicon-cyan {
    color: var(--brand-cyan);
}

.tapp-nav-subicon-green {
    color: var(--brand-green);
}

.tapp-nav-subicon-amber {
    color: var(--brand-amber);
}

.tapp-nav-subicon-teal {
    color: var(--brand-teal);
}

.tapp-nav-subicon-rose {
    color: var(--brand-rose);
}

.tapp-nav-subicon-blue {
    color: var(--brand-blue);
}

.tapp-nav-subicon-red {
    color: var(--brand-red);
}

.tapp-nav-subicon-lime {
    color: var(--brand-lime);
}

.tapp-nav-subicon-orange {
    color: var(--brand-orange);
}

/* The bare glyph itself - no tile, so it stays a step below the top-level entry it hangs
   under and the hierarchy survives without a second indent. It brightens on the row's own
   hover so the whole row still reads as one target. */
.tapp-nav-subicon {
    width: 14px;
    flex: 0 0 14px;
    text-align: center;
    font-size: var(--t-11);
    opacity: .85;
}

.tapp-nav-row:hover .tapp-nav-subicon {
    opacity: 1;
}

.tapp-nav-item > .tapp-nav-label,
.tapp-nav-group-label > .tapp-nav-label {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tapp-nav-item.is-active {
    background: var(--acc-soft);
    color: var(--acc-text);
    font-weight: 600;
}

/* The unread count on the Mesajlar row (design round 15, "Menü ve bağlantılar"): a quiet outlined
   pill at the row's far end, in the muted ink - the count is information, not an alarm, and the
   bell already carries the alarm. */
.tapp-ar-nav-new {
    margin-left: auto;
    font-size: var(--t-11);
    font-weight: 700;
    letter-spacing: .4px;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    padding: 1px 7px;
    font-variant-numeric: tabular-nums;
}

/* A module heading reads as a peer of the plain entries around it, not as a section caption
   above them: same weight, same colour, same box - the only difference is the chevron. Height
   comes from padding rather than a fixed 34px, so a wrapped two-word module name is not
   clipped. */
/* The collapsible group as a whole - its heading plus the children it hides. The type
   declarations are the baseline the rows inside it read from, stated rather than inherited:
   this shell sits under LeptonX's own bundle, and a group can be dropped straight into a
   .tapp-nav-section whose label treatment must not reach it. */
.tapp-nav-group {
    padding: 0;
    font-size: var(--t-13-5);
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    color: var(--body);
}

.tapp-nav-group-label {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 9px;
    border: 0;
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--body);
    font-family: inherit;
    font-size: var(--t-13-5);
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    transition: background-color var(--t-fast), color var(--t-fast);
}

/* One hover answer for the sidebar's rows and the topbar's icon buttons: the --hover ground,
   with the label or glyph lifted to --head. It was written four times, once per control, the
   same two declarations each time - one decision, so one rule. Each control's own shape and
   transition stay in its own rule. */
.tapp-nav-group-label:hover,
.cr.tapp-shell .tapp-nav-fav:hover,
.cr.tapp-shell .tapp-nav-hide:hover,
.cr.tapp-shell .tapp-nav-row .tapp-nav-item:hover,
.tapp-iconbtn:hover {
    background: var(--hover);
    color: var(--head);
}

.tapp-nav-group-label.has-active {
    color: var(--head);
}

/* `margin-left: auto` rather than a spacer element, so the chevron sits at the far edge
   whatever else the heading happens to carry (a longer label, say). */
.tapp-chev {
    margin-left: auto;
    font-size: 9px;
    color: var(--muted);
    transition: transform .15s ease;
}

/* Closed state points right instead of down - the same shape console.js's own chevron
   swap draws, done here with a rotation instead so the icon markup never has to change. */
.tapp-nav-group-label[aria-expanded="false"] > .tapp-chev {
    transform: rotate(-90deg);
}

/* The 0fr/1fr grid-rows trick: animates open/closed without either side needing to know
   the children's real height up front, which a plain max-height transition would. */
.tapp-nav-group-children {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows .15s ease;
}

.tapp-nav-group-children.tapp-collapsed {
    grid-template-rows: 0fr;
}

/* Put on `.tapp-nav` for the length of the restore tenant-app.js runs before the first
   frame, and taken off once that frame is on screen (see its own restoreNavState remarks).
   Without it the restore is *animated*: the sidebar paints in the state the server rendered,
   and then every group the tenant had left open swings itself open over 150ms, with the
   chevrons rotating, on every page they visit. That is the sidebar redrawing itself in front
   of the reader once per navigation - which is most of what "it feels like the page
   reloads" actually is. A real click still animates; only the restore does not. */
.tapp-nav-booting .tapp-nav-group-children,
.tapp-nav-booting .tapp-chev {
    transition: none;
}

/* Indented, and hung off a hairline that runs the height of the open group. Without it
   a child sits at exactly the same offset as the module above it and the two read as
   siblings - which is what the tree is there to deny. The rule is on the inner element
   rather than the animated one: the outer grid collapses to 0fr, and a border on a box
   with no height is a stray line under a closed group. */
.tapp-nav-group-children-inner {
    display: flex;
    flex-direction: column;
    gap: 1px;
    overflow: hidden;
    min-height: 0;
    margin: 2px 0 4px 20px;
    padding-left: 11px;
    border-left: 1px solid var(--border);
}

/* The row itself. It was never declared - the link filled it and nothing sat beside it - so
   the first thing that did (the favourite star) would have dropped onto its own line. */
.cr.tapp-shell .tapp-nav-row {
    display: flex;
    align-items: center;
    gap: 2px;
}

/* The star, and the eye beside it. Absent to the eye until the row is hovered or the button itself is focused, so a
   sidebar at rest reads as a list of screens rather than a list of controls - but present in
   the accessibility tree the whole time, and always visible once the entry is a favourite,
   which is the only way to un-pin it from here. */
.cr.tapp-shell .tapp-nav-fav-form {
    display: flex;
    flex: 0 0 auto;
}

.cr.tapp-shell .tapp-nav-fav,
.cr.tapp-shell .tapp-nav-hide {
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--muted);
    font-size: var(--t-12);
    cursor: pointer;
    opacity: 0;
    transition: opacity var(--t-fast), color var(--t-fast), background-color var(--t-fast);
}

/* The eye takes no room until it is wanted. The row was laid out for one action beside the
   label; a second one permanently in the flow shortened every entry's name by 26px, which is
   how it was noticed - "Hesap ve abonelik" became "Hesap ve abon..". So it collapses to zero
   width at rest and opens on hover or focus, where the row is already being read. */
.cr.tapp-shell .tapp-nav-hide {
    width: 0;
    flex-basis: 0;
    overflow: hidden;
    transition: opacity var(--t-fast), width var(--t-fast), flex-basis var(--t-fast),
                color var(--t-fast), background-color var(--t-fast);
}

.cr.tapp-shell .tapp-nav-row:hover .tapp-nav-hide,
.cr.tapp-shell .tapp-nav-hide:focus-visible,
.cr.tapp-shell .tapp-nav-hidden .tapp-nav-hide {
    width: 26px;
    flex-basis: 26px;
}

.cr.tapp-shell .tapp-nav-row:hover .tapp-nav-fav,
.cr.tapp-shell .tapp-nav-row:hover .tapp-nav-hide,
.cr.tapp-shell .tapp-nav-fav:focus-visible,
.cr.tapp-shell .tapp-nav-hide:focus-visible,
.cr.tapp-shell .tapp-nav-fav.is-on,
.cr.tapp-shell .tapp-nav-hide.is-on {
    opacity: 1;
}

.cr.tapp-shell .tapp-nav-fav.is-on {
    /* --brand-amber is always defined (both .cr and .cr[data-theme="light"] declare it),
       so the fallback here never fired - dropped rather than kept as dead weight. */
    color: var(--brand-amber);
}

/* "Gizlenenler" - a fold under the menu, closed by default. It is quieter than a section
   label: what is inside it was taken off the list on purpose, and it exists so that taking
   something off the list is reversible from the same place it was done. */
.cr.tapp-shell .tapp-nav-hidden {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
}

.cr.tapp-shell .tapp-nav-hidden-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--r-ctl);
    color: var(--muted);
    font-size: var(--t-11);
    letter-spacing: .04em;
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
}

.cr.tapp-shell .tapp-nav-hidden-head::-webkit-details-marker {
    display: none;
}

.cr.tapp-shell .tapp-nav-hidden-head:hover {
    background: var(--hover);
    color: var(--head);
}

.cr.tapp-shell .tapp-nav-hidden-count {
    margin-inline-start: auto;
    font-size: var(--t-11);
    letter-spacing: 0;
}

/* Inside the fold every row is muted: it is a list of things that are not in the menu. */
.cr.tapp-shell .tapp-nav-hidden .tapp-nav-item {
    color: var(--muted);
}

/* A menu entry is a row now, not a bare link: the link takes the width it can and whatever
   the row adds beside it (a per-entry action, a count) keeps its own space. The link's own
   box is declared here rather than on `.tapp-nav-item` so a link outside a row - the drawer
   copy, a page's own inline menu - is unaffected. */
.cr.tapp-shell .tapp-nav-row .tapp-nav-item {
    flex: 1;
    min-width: 0;
    padding: 7px 9px;
    border-radius: var(--r-ctl);
    font-size: var(--t-13-5);
    font-weight: 500;
    text-decoration: none;
    transition: background-color var(--t-fast), color var(--t-fast);
}

/* The page you are on, and the row the pointer happens to be over, have to look different.
   Both drew var(--hover) here, so on the settings screen the sidebar showed two selected
   entries - "Hesap ve abonelik" under the pointer and "Ayarlar" as the current page - which is
   how the owner reported it (21 September 2026). The current page takes the accent the rest of
   the panel already uses for it; hover stays the neutral ground it was. */
.cr.tapp-shell .tapp-nav-row .tapp-nav-item.is-active {
    background: var(--acc-soft);
    color: var(--acc-text);
    font-weight: 600;
}

.cr.tapp-shell .tapp-nav-row .tapp-nav-item.is-active:hover {
    background: var(--acc-soft);
    color: var(--acc-text);
}

/* One step down from a top-level entry, and only one: a second indent plus a smaller glyph
   plus a smaller type size would read as a third level that does not exist. */
.tapp-nav-sub {
    gap: 9px;
    padding: 6px 9px;
    font-size: var(--t-13);
    font-weight: 500;
}

.cr.tapp-shell .tapp-nav-row .tapp-nav-sub {
    padding: 6px 9px;
    font-size: var(--t-13);
    font-weight: 500;
}

/* Shown when the filter matches no entry. The visibility switch is .tapp-off in the markup,
   which tenant-app.js takes off and puts back - so this rule states only how the line looks,
   never whether it is there. */
.tapp-nav-empty {
    padding: 18px 12px;
    text-align: center;
    font-size: var(--t-12-5);
    color: var(--muted);
}

.tapp-side-foot {
    flex: 0 0 auto;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 12px 14px;
    border-top: 1px solid var(--border);
}

.tapp-user-name {
    font-size: var(--t-12-5);
    font-weight: 600;
    color: var(--head);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tapp-user-role {
    font-size: 10.5px;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Stays on the tenant's own accent rather than taking a brand hue: --brand-* names a module,
   and a person is not one - a cyan avatar would claim the stock module's colour for whoever
   happens to be signed in. */
.tapp-avatar {
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--acc-soft);
    color: var(--acc-text);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--t-11-5);
    font-weight: 700;
}

/* ---------------------------------------------------------------- topbar */

/* The topbar's own left edge lines up with `.tapp-main`'s content column, so the page title
   and the first thing under it sit on one vertical. */
.tapp-topbar {
    /* Named rather than repeated: on a phone the account menu drops out of the
       bar and positions itself against the viewport, which means it has to know
       how tall the bar is. A second literal 52px there would be a number that
       stops agreeing with this one the first time the bar changes. */
    --topbar-height: 52px;

    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--topbar-height);
    padding: 0 28px;
    background: var(--card);
    border-bottom: 1px solid var(--border);
}

/* The location trail, both crumbs plain text (_TenantAppLayout.cshtml's own remarks on why
   neither is a link). The trail is context and the leaf is where you are, so only the last
   crumb is lifted out of --muted rather than the whole row reading at title strength. */
.tapp-crumbs {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-size: var(--t-12-5);
    color: var(--muted);
}

.tapp-crumbs > span {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tapp-crumbs > span:last-child {
    color: var(--head);
    font-weight: 600;
}

/* Holds the topbar's right-hand controls apart from the trail. An element of its own rather
   than `margin-left: auto` on the first control, because which control comes first depends on
   what the tenant has enabled (language switcher, bell) and none of them may own the gap. */
.tapp-topbar-spacer {
    flex: 1;
}

/* An icon-only control sits at --muted until pointed at: a row of five of them at full text
   strength competes with the page title beside them, which is the thing the topbar is for. */
.tapp-iconbtn {
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--muted);
    font-size: var(--t-12);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--t-fast), color var(--t-fast);
}

/* ARCP-145: disabled rather than hidden, so the topbar's back/forward never look live while
   silently doing nothing (tenant-app.js's own updateHistoryButtons remarks). Higher specificity
   than the hover rule above on purpose, so a disabled button does not pick up the hover
   treatment from a pointer that happens to be resting on it. */
.tapp-iconbtn[disabled],
.tapp-iconbtn[disabled]:hover {
    opacity: .55;
    cursor: not-allowed;
    background: transparent;
    color: var(--muted);
}

/* The pair is one control ("history"), drawn as one joined pill rather than two separate
   buttons that happen to be adjacent. A live arrow carries the brand indigo on a light wash of
   the same, so it reads as something to press at a glance; a dead one drops to the quiet
   border-only look. The owner's words, 19 September 2026: "ileri geri butonu daha canlı daha
   anlaşılır olsun, yukarıda belli olmuyor" - two grey outlines were indistinguishable from the
   empty space around them. */
.tapp-history-nav {
    display: inline-flex;
    align-items: stretch;
    gap: 0;
    padding: 2px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--input);
}

.cr.tapp-shell .tapp-history-nav .tapp-iconbtn {
    flex: 0 0 34px;
    width: 34px;
    height: 30px;
    border: none;
    border-radius: var(--r-sm);
    font-size: var(--t-13);
}

.cr.tapp-shell .tapp-history-nav .tapp-iconbtn + .tapp-iconbtn {
    margin-left: 2px;
}

/* A history arrow that has somewhere to go, and the language switch's chosen pill (`.tapp-seg`,
   styled further down), share one wash. The pill is lifted out of the trough it sits in, not
   painted a solid accent. It was solid --accent with white text, which made the language
   switch the loudest thing in the topbar - louder than the page title, and louder than the
   bell, which is the one control up there that can actually be carrying news.
   The wash is the brand indigo the system reserves for the active tab, at a strength that
   tints the pill and nothing behind it. Mixed with `transparent` rather than with the page,
   so it is pure alpha and lands the same over either theme's card. */
.cr.tapp-shell .tapp-history-nav .tapp-iconbtn:not([disabled]),
.tapp-seg > a.is-on,
.tapp-seg > a.is-on:hover {
    background: color-mix(in oklab, var(--brand-indigo) 16%, transparent);
    color: var(--brand-indigo);
}

.cr.tapp-shell .tapp-history-nav .tapp-iconbtn:not([disabled]):hover,
.cr.tapp-shell .tapp-history-nav .tapp-iconbtn:not([disabled]):focus-visible {
    background: color-mix(in oklab, var(--brand-indigo) 30%, transparent);
    color: var(--head);
}

.cr.tapp-shell .tapp-history-nav .tapp-iconbtn[disabled] {
    opacity: .4;
}

/* On a phone the topbar answers one question, "where am I": the page's own title, whole. The
   tenant's name and the separator were cut in two places ("Örne… İş …") and said nothing the
   drawer does not already say, and the forward arrow - the rarest move there is, with the
   browser's and the system's own back gesture beside it - took a third of a strip that has
   no third to spare. Back stays: it is the one that gets used. */
@media (max-width: 767.98px) {
    .tapp-crumbs > span:not(:last-child) {
        display: none;
    }

    .tapp-crumbs {
        font-size: var(--t-15);
    }

    .tapp-history-nav [data-tapp-history="forward"] {
        display: none;
    }
}

/* One size down in the sidebar foot, to match the avatar it stands beside rather than the
   topbar it does not. */
.cr.tapp-shell .tapp-side-foot .tapp-iconbtn {
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
}

/* The day/night switch is a preference rather than an action on the page, so it is pinned to
   the quiet treatment even where a page drops it into a row that tints its own buttons. */
.tapp-theme {
    background: transparent;
    color: var(--muted);
}

/* The day/night switch and the bell answer the pointer the way the icon buttons beside them
   do, so the whole topbar row reads as one set of controls. */
.tapp-theme:hover,
.tapp-bell:hover {
    background: var(--hover);
    color: var(--head);
}

/* Mirrors wwwroot/console/console.css's .ac-seg (same segmented two-pill shape), tapp-
   prefixed and scoped for the reason this whole file is: it sits in a Bootstrap page and
   must not leak a bare selector into it. */
.tapp-seg {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    background: var(--input);
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
}

.tapp-seg > a {
    padding: 5px 12px;
    /* "Özel tarih" and "Bu hafta" are two words, and a pill narrow enough to break one of
       them turns the control into two rows of half-labels. A segmented control is read across,
       so the label holds its line and the pill is what gives way (see the phone rules further
       down, where the type shrinks with the screen instead). */
    white-space: nowrap;
    border-radius: var(--r-xs);
    color: var(--muted);
    font-size: var(--t-12);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    text-decoration: none;
}

.tapp-seg > a:hover {
    color: var(--brand-indigo);
    text-decoration: none;
}

/* The branch switcher (ARCP-86, the owner's decision of 2026-09-09) - only ever in the markup
   at all once IBranchVisibility.IsVisibleAsync() is true, so a single-branch tenant pays no
   cost for this rule existing. .tapp-branch-select is the interactive shape a
   PlatformPermissions.Branches.ViewAll holder gets; .tapp-branch-label is the plain-text
   shape everyone else gets instead of a dropdown with nothing they may change it to. */
.tapp-branch-switcher {
    display: inline-flex;
}

.tapp-branch-select {
    padding: 5px 10px;
    border-radius: var(--r-ctl);
    border: 1px solid var(--border);
    background: var(--input);
    color: var(--head);
    font-size: var(--t-12);
    font-weight: 600;
    max-width: 160px;
}

.tapp-branch-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: var(--r-ctl);
    border: 1px solid var(--border);
    color: var(--muted);
    font-size: var(--t-12);
    font-weight: 600;
}

/* ---------------------------------------------------------------- notification bell */

/* The bell is deliberately not a `.tapp-iconbtn`. The design system gives it a box of its own -
   a shade larger than the icon buttons beside it, and drawn at full text strength rather than
   --muted - because it is the one control in that row that can be carrying news. The rest of
   the row stays quiet so this one reads. `position: relative` is also what the unread count and
   the dropdown below are positioned against. */
.tapp-bell {
    position: relative;
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--body);
    font-size: var(--t-13);
    cursor: pointer;
    transition: background-color var(--t-fast), color var(--t-fast);
}

/* The two icons in the topbar each carry one fixed brand colour - indigo on the bell, cyan on
   the day/night switch - so the row is identifiable at a glance without any of it being an
   alarm. Only the glyph is coloured: the button keeps its size and its transparent ground, and
   goes back to plain text strength under the pointer so hover still reads as a state change. */
.tapp-topbar .tapp-bell i {
    color: var(--brand-indigo);
}

.tapp-topbar .tapp-theme i {
    color: var(--brand-cyan);
}

.tapp-topbar .tapp-bell:hover i,
.tapp-topbar .tapp-theme:hover i {
    color: var(--head);
}

/* ---------------------------------------------------------------- notification panel */

/* The bell's dropdown. An earlier `.tapp-bell-panel` set drew the same panel from different
   markup (a list of `<li><a>`, a header with one bulk action); the two were kept side by side
   while _NotificationBell.cshtml moved over, and the old one is gone now that it has. */

.tapp-notif,
.tapp-wo-more,
.tapp-ku-menu-wrap,
.tapp-pr-umenu-wrap {
    position: relative;
    display: inline-flex;
}

/* ARCP-178: the topbar's secondary controls travel together. `display: contents` means the
   wrapper draws nothing of its own on a wide screen - the branch switcher, the language pair,
   the bell and the quiet switch stay direct participants in the topbar's flex row, exactly as
   they were before the wrapper existed. tenant-app.js moves this one element into the drawer
   on a phone; the narrow rules for it live with the drawer's own media block below. */
.tapp-shelf {
    display: contents;
}

/* Empty and invisible until the shelf lands in it - see the drawer's own media block. */
.tapp-side-extras:empty {
    display: none;
}

/* Sits over the bell's own corner, so the count needs no space of its own in the topbar row
   and the row does not reflow when the first notification arrives. */
.tapp-bell-count {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-pill);
    background: var(--bad);
    color: var(--bg);
    font-size: var(--t-10);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.tapp-bell-count[hidden] {
    display: none;
}

.tapp-notif-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 60;
    width: 340px;
    max-width: calc(100vw - 32px);
    display: none;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--card);
    box-shadow: var(--shadow-dlg);
    overflow: hidden;
}

.tapp-notif-panel.is-open {
    display: flex;
}

/* The panel grows out of the bell and goes back into it, the way the dialogs grow out of
   their trigger (Apple, "Designing Fluid Interfaces" §7) - it used to appear and vanish in a
   single frame. `--tapp-notif-x` is the bell's centre measured from the panel's own left
   edge, written by tenant-app.js when it opens; without it the top-right corner, where the
   bell sits on a wide screen, is the origin. display with allow-discrete is what keeps the
   panel painted while it closes. */
.tapp-notif-panel {
    opacity: 0;
    transform: translateY(-4px) scale(.96);
    transform-origin: var(--tapp-notif-x, calc(100% - 16px)) 0;
    transition: opacity .16s ease-out, transform .16s ease-out, display .16s allow-discrete;
}

.tapp-notif-panel.is-open {
    opacity: 1;
    transform: none;
}

@starting-style {
    .tapp-notif-panel.is-open {
        opacity: 0;
        transform: translateY(-4px) scale(.96);
    }
}

@media (prefers-reduced-motion: reduce) {
    .tapp-notif-panel,
    .tapp-notif-panel.is-open {
        transform: none;
    }
}

.tapp-notif-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    font-size: var(--t-13);
    font-weight: 700;
    color: var(--head);
}

.tapp-notif-head .tapp-notif-unread {
    font-size: var(--t-11);
    font-weight: 600;
    color: var(--muted);
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

/* The list scrolls inside the panel rather than the panel growing: the footer's bulk actions
   have to stay reachable however many notifications are waiting. */
.tapp-notif-list {
    display: flex;
    flex-direction: column;
    max-height: 320px;
    overflow-y: auto;
}

.tapp-notif-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    background: transparent;
    border-left: none;
    border-right: none;
    border-top: none;
    width: 100%;
    text-align: left;
    font-family: inherit;
    cursor: pointer;
}

.tapp-notif-item:hover {
    background: var(--hover);
}

.tapp-notif-item.is-unread {
    background: var(--zebra, transparent);
}

/* The dot keeps its box once read rather than being removed, so marking one read does not
   shuffle every line under it. */
.tapp-notif-dot {
    width: 7px;
    height: 7px;
    flex: 0 0 7px;
    margin-top: 6px;
    border-radius: var(--r-pill);
    background: transparent;
}

.tapp-notif-item.is-unread .tapp-notif-dot {
    background: var(--bad);
}

.tapp-notif-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.tapp-notif-title {
    font-size: var(--t-13);
    font-weight: 600;
    color: var(--body);
    line-height: 1.35;
}

.tapp-notif-item.is-unread .tapp-notif-title {
    color: var(--head);
}

/* The message under the title. Quiet and a size down: the panel is a list of what happened,
   and the whole of it is on the page the item opens. */
.tapp-notif-body {
    font-size: var(--t-12);
    line-height: 1.45;
    color: var(--muted);
}

.tapp-notif-time {
    font-size: var(--t-11);
    color: var(--muted);
}

.tapp-notif-empty {
    padding: 28px 18px;
    text-align: center;
    font-size: var(--t-12-5);
    color: var(--muted);
    line-height: 1.5;
}

.tapp-notif-empty i {
    display: block;
    margin-bottom: 8px;
    font-size: 18px;
    color: var(--border);
}

.tapp-notif-foot {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px 12px;
    border-top: 1px solid var(--border);
    background: var(--thead);
}

.tapp-notif-act {
    padding: 6px 9px;
    border: none;
    border-radius: var(--r-xs);
    background: transparent;
    color: var(--body);
    font-family: inherit;
    font-size: var(--t-12);
    font-weight: 600;
    cursor: pointer;
}

.tapp-notif-act:hover {
    background: var(--hover);
    color: var(--head);
}

.tapp-notif-act:disabled {
    opacity: .45;
    cursor: default;
}

/* The primary action keeps its fill under the pointer - a ground that shifted on hover would
   read as a second, different button. */
.tapp-notif-act.is-primary,
.tapp-notif-act.is-primary:hover {
    background: var(--accent, var(--brand-indigo));
    color: var(--bg);
}

/* ---------------------------------------------------------------- page head */

.tapp-page-head {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.tapp-page-head h1 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    color: var(--head);
    letter-spacing: -.3px;
}

/* FAZ 3: the `content_toolbar` section a foreign (ABP module) page defines - see
   _TenantAppLayout.cshtml's own remarks next to where this renders - sits beside the title
   rather than under it, the same row a page's own "+ New X" button reads as everywhere else
   in this shell. Every first-party page's own `.tapp-page-head` still holds only the `<h1>`
   this row now wraps, so this is additive: nothing already shipped changes shape. */
/* The row wraps rather than squeezing: `space-between` is replaced by `margin-left: auto` on
   the trailing block, which is the only version of this that survives the wrap - once the
   toolbar drops to a second line, `space-between` has nothing left to push apart and the
   title column is what gets crushed instead. The title column carries its own floor
   (`flex: 1 1 280px`) so it is never the thing that gives way. */
.tapp-page-head-row {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}

.tapp-page-head-row .tapp-page-head-text {
    flex: 1 1 280px;
    min-width: 280px;
}

/* The page head's two trailing slots (the toolbar and the slot a page fills) sit at the far
   end of the row as one centred cluster - one decision, so one rule. Only the page-filled
   slot wraps, so that stays in its own rule below. */
.tapp-page-head-toolbar,
.tapp-head-slot {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

/* The trailing slot a page fills with its own controls - a period picker, a "+ Yeni", a link
   out to the full report - beside the title rather than above the first card. */
.tapp-head-slot {
    flex-wrap: wrap;
}

.tapp-page-title {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.4px;
    color: var(--head);
}

/* The optional qualifier under a page title (_TenantAppLayout's `page_subtitle` section) -
   which month the dashboard is counting, which branch a list is scoped to. Part of the
   head's own column, so it never drifts away from the title it qualifies. */
.tapp-page-head-sub {
    margin-top: 6px;
    font-size: var(--t-13);
    color: var(--muted);
}

/* ---------------------------------------------------------------- demo data notice */

/* ARCP-140: "bu kayıtlar örnektir" - a standing notice at the top of the panel's own content
   while a tenant still carries the wizard's retired demo-data seed
   (CoreOnboardingState.HasDemoData). Its own class rather than a reuse of `.tapp-ro-strip`
   (module-readonly.css - a write-block state, a different meaning entirely) or an alert (the
   result of what the caller just did, not a standing fact) - see DemoDataNoticeViewComponent's own
   remarks for where it renders. */
.tapp-demo-notice {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    margin-bottom: 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--thead);
    color: var(--body);
    font-size: var(--t-12-5);
}

.tapp-demo-notice > i {
    color: var(--muted);
    font-size: 14px;
}

.tapp-demo-notice > span {
    flex: 1;
}

/* ---------------------------------------------------------------- mobile drawer */

/* The design's own answer to "sol menü mobilde ne olur" (docs/tenant-app-ui-design-brief.md
   §7, scratchpad/design/panel.dc.html's drawer state) - the sidebar slides in from behind a
   burger button, not a bottom tab bar. Same shape and the same 991.98px breakpoint as
   wwwroot/console/console.css's own drawer, tapp- prefixed and reading this file's own tokens
   instead of console's, because the two shells answer the same question about the same
   interaction independently rather than sharing a stylesheet - see this file's own
   top-of-file remarks on why the two never share rules.

   Where it parts from console's: there is no separate drawer element here. The menu is
   rendered once and `.tapp-side` becomes the drawer itself below the breakpoint, so the
   off-canvas rules are in the responsive block further down rather than beside the burger -
   see _TenantAppLayout.cshtml's own remarks on why the second copy of the tree went away. */

.tapp-burger {
    display: none;
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--body);
    font-size: var(--t-13);
    cursor: pointer;
}

.tapp-burger:hover {
    background: var(--hover);
    color: var(--head);
}

/* One switch for the whole open state: `.tapp-shell.is-drawer-open`. The scrim defaults to
   none and the sidebar defaults to off canvas, and both read that same class - so there is no
   `hidden` attribute on either any more, and no second source of truth to keep in step. It is
   only shown inside the responsive block below, since above the breakpoint the rail is in the
   flow and nothing may cover the page. */
.tapp-scrim {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 40;
    border: 0;
    padding: 0;
    background: var(--scrim);
}

/* ---------------------------------------------------------------- responsive shell */

/* Below this the sidebar rail stops paying for itself, the same judgement call
   wwwroot/console/console.css's own remarks make at the same breakpoint for the same
   reason: a 226px rail out of ~375px is most of the screen. The static sidebar hides, the
   rail leaves the flow and becomes the drawer, reached from the burger this rule reveals in
   the topbar. */
@media (max-width: 991.98px) {
    /* Off canvas rather than hidden - it is the same element the wide layout uses, so one
       menu, one set of ids and one saved scroll position survive the breakpoint. `visibility`
       is what keeps the closed rail out of the tab order and the accessibility tree while it
       still has a box for the transform to animate, and it is transitioned alongside so the
       hide waits for the slide to finish instead of blanking it mid-way. */
    .tapp-side {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 41;
        flex: 0 0 auto;
        width: 290px;
        max-width: 84vw;
        visibility: hidden;
        transform: translateX(-100%);
        transition: transform var(--t-fast), visibility var(--t-fast);

        /* The drawer can be dragged shut (tenant-app.js): the browser has to hand horizontal
           movement over rather than treating it as a scroll, while vertical movement stays
           the menu's own scrolling. */
        touch-action: pan-y;
    }

    .tapp-shell.is-drawer-open .tapp-side {
        visibility: visible;
        transform: none;
    }

    /* The scrim is the thing that takes the class back off, so it exists exactly as long as
       the class is on. */
    .tapp-shell.is-drawer-open .tapp-scrim {
        display: block;
    }

    /* Two of them - the topbar's opener and the drawer head's closer - and neither means
       anything at a width where the rail is already in the flow. */
    .tapp-burger {
        display: inline-flex;
    }

    /* ARCP-178: what the topbar keeps on a phone is what gets used while reading a screen -
       back, forward and the theme. The rest rides into the drawer with .tapp-shelf, which
       stops being a pass-through wrapper the moment it lands there and becomes the row that
       lays them out. */
    .tapp-side-extras {
        display: block;
        padding: 10px 14px;
        border-top: 1px solid var(--border);
    }

    .tapp-side-extras .tapp-shelf {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 10px;
    }

    /* Muting notifications for an hour is a decision taken at a desk, and in a row of small
       round controls on a phone it was the one being hit by accident. Hidden rather than
       moved: /notifications/mute is still a page, reachable from the notification settings. */
    .tapp-dnd {
        display: none;
    }

    /* In the drawer there is no topbar corner to hang off: the bell takes a row of its own
       and its panel opens underneath it, part of the column instead of a dropdown floating
       over one - which off the side of a 290px drawer would be half off the screen. */
    .tapp-side-extras .tapp-notif {
        position: static;
        flex: 1 0 100%;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
    }

    .tapp-side-extras .tapp-notif-panel {
        position: static;
        width: 100%;
        max-width: none;
        margin-top: 8px;
        box-shadow: none;
    }

    .tapp-topbar {
        padding: 0 10px;
        gap: 8px;
    }

    .tapp-main {
        padding: 12px 12px 18px;
        gap: 12px;
    }

    .tapp-page-head h1 {
        font-size: 18px;
    }

    /* Anchored to the bell, a 340px panel hangs off the right edge on a phone; pinned to the
       viewport instead, with the topbar's own height as its top. */
    .tapp-notif-panel {
        position: fixed;
        top: 56px;
        left: 8px;
        right: 8px;
        width: auto;
        max-width: none;
    }
}

@media (prefers-reduced-motion: reduce) {

    .tapp-nav-group-children,
    .tapp-chev,
    .tapp-side {
        transition: none;
    }

    .tapp-dialog[open] {
        transform: none;
    }
}

/* ---------------------------------------------------------------- dialog */

/* FAZ 9: one-screen, one-question actions (export my data, stop the subscription, start a
   module trial) reached from wherever the caller already is instead of a bare full-page
   navigation for something this small - the owner's own complaint ("her boka ayrı sayfa
   açmak karışıklığı artırıyor"). The native <dialog> element is used rather than a
   hand-rolled overlay: showModal() gives Esc-to-close, an inert background and focus
   containment for free, none of which this file would otherwise have to reimplement and
   risk getting subtly wrong. tenant-app.js only wires backdrop-click-to-close and returning
   focus to whichever element opened the dialog - everything else here is the browser's own
   dialog behaviour, restyled through this file's own tokens the same way `.tapp-card`
   restyles Bootstrap's `.card` further down. Each dialog's own launching page keeps a plain
   `href` to the page the action already lives on, so the same trigger still works, unchanged,
   with JavaScript disabled - see tenant-app.js's own remarks on the trigger wiring. */

.tapp-dialog {
    position: fixed;
    inset: 0;
    margin: auto;
    width: min(480px, calc(100vw - 32px));
    max-height: calc(100vh - 64px);
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    background: var(--card);
    color: var(--body);
    box-shadow: var(--shadow-pop);
}

.tapp-dialog::backdrop {
    background: var(--scrim-native);
    opacity: 0;
    transition: opacity .16s ease, display .16s allow-discrete, overlay .16s allow-discrete;
}

/* Opens and closes along the same path, and from the thing that opened it.
 *
 * "If something disappears one way, we expect it to emerge from where it came" (Apple,
 * "Designing Fluid Interfaces" §7). This window used to arrive with a keyframe and leave
 * with nothing at all - one frame and gone - and it grew from the middle of the screen
 * whatever had been pressed. Both are fixed by making the open state a transition rather
 * than an animation: a transition runs in reverse for free, which is exactly what a
 * symmetric path is.
 *
 * `--tapp-dialog-x/y` is where the trigger was when it was pressed, written by
 * tenant-app.js; with no script, or a trigger that is off-screen by the time the dialog
 * opens, it falls back to the centre - the behaviour before this rule.
 *
 * display/overlay with allow-discrete is what keeps the element painted while it leaves;
 * without them the browser removes it on close and there is nothing left to animate. A
 * browser that does not understand them simply shows the old behaviour: instant close. */
.tapp-dialog {
    opacity: 0;
    transform: translateY(6px) scale(.97);
    transform-origin: var(--tapp-dialog-x, 50%) var(--tapp-dialog-y, 50%);
    transition: opacity .16s ease-out, transform .16s ease-out,
                display .16s allow-discrete, overlay .16s allow-discrete;
}

.tapp-dialog[open] {
    display: flex;
    flex-direction: column;
    opacity: 1;
    transform: none;
}

.tapp-dialog[open]::backdrop {
    opacity: 1;
}

@starting-style {
    .tapp-dialog[open] {
        opacity: 0;
        transform: translateY(6px) scale(.97);
    }

    .tapp-dialog[open]::backdrop {
        opacity: 0;
    }
}

.tapp-dialog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
}

.tapp-dialog-title {
    margin: 0;
    font-size: var(--t-15);
    font-weight: 600;
    color: var(--head);
}

.tapp-dialog-body {
    flex: 1 1 auto;
    min-height: 0;
    padding: 16px;
    overflow-y: auto;
    font-size: var(--t-13-5);
    color: var(--body);
}

/* Most windows put a <form> between the dialog and its body and footer, and that form was a
   plain block: the body could not take the leftover height, so it never scrolled, and the
   whole window scrolled instead - with "Kaydet" 40-160px below the bottom of a phone screen
   on Tahsilat, Gider and Yeni parça. As a flex column the form passes the height down, the
   body is the one thing that scrolls, and the head and the footer stay put (Apple's "every
   screen answers how do I get out" - and how do I finish). */
.tapp-dialog > form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.tapp-dialog-head,
.tapp-dialog-foot {
    flex: 0 0 auto;
}

/* On a phone a window is a sheet: it rises from the bottom edge, where the thumb already is,
   and goes back down the same way (§7) - not a card floating in the middle with its actions
   out of reach. The grabber says it can be pulled down; tenant-app.js does the pulling, from
   the head, the same way the drawer is dragged shut. `dialog.tapp-dialog` outranks the
   per-screen width modifiers (`.tapp-wo-modal`, `-wide`), which are desktop sizes. */
@media (max-width: 767.98px) {
    dialog.tapp-dialog {
        inset: auto 0 0 0;
        margin: 0;
        width: 100%;
        max-width: 100%;
        max-height: calc(100dvh - 24px);
        border-bottom: 0;
        border-radius: var(--r-xl) var(--r-xl) 0 0;
        padding-bottom: env(safe-area-inset-bottom);
        opacity: 1;
        transform: translateY(100%);
        transform-origin: 50% 100%;
        transition: transform .28s cubic-bezier(.2, .8, .2, 1),
                    display .28s allow-discrete, overlay .28s allow-discrete;
    }

    dialog.tapp-dialog[open] {
        transform: none;
    }

    @starting-style {
        dialog.tapp-dialog[open] {
            opacity: 1;
            transform: translateY(100%);
        }
    }

    .tapp-dialog-head {
        position: relative;
        padding-top: 18px;
        touch-action: none;
    }

    @media (prefers-reduced-motion: reduce) {
        dialog.tapp-dialog {
            opacity: 0;
            transform: none;
            transition: opacity .16s ease, display .16s allow-discrete, overlay .16s allow-discrete;
        }

        dialog.tapp-dialog[open] {
            opacity: 1;
        }

        @starting-style {
            dialog.tapp-dialog[open] {
                opacity: 0;
                transform: none;
            }
        }
    }

    .tapp-dialog-head::before {
        content: "";
        position: absolute;
        top: 7px;
        left: 50%;
        width: 36px;
        height: 4px;
        margin-left: -18px;
        border-radius: var(--r-pill);
        background: var(--border);
    }
}

.tapp-dialog-body .text-muted {
    color: var(--muted);
}

/* ---------------------------------------------------------------- buttons */

/* The design's button rules (scratchpad/design/panel.dc.html) applied here as reusable
   classes instead of the design's own inline styles - primary/secondary/danger, each with
   an explicit disabled and loading state. `.tapp-btn-primary`'s colour is `--acc-solid`
   (Branding/AccentPaletteResolver.cs), not `--accent` itself, because a filled button under
   white text has to hold WCAG AA for whatever colour a tenant has chosen, and only the
   solid variant is checked for that (see that type's own remarks). */

/* An anchor is the panel's own way of opening a dialog while keeping a link that works with
   no JavaScript (tenant-app.js's `data-tapp-dialog`), so a button here is as often an <a> as
   a <button> - and an <a> arrives underlined. */
a.tapp-btn,
a.tapp-btn:hover {
    text-decoration: none;
}

.tapp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 36px;
    padding: 0 14px;
    border: 1px solid transparent;
    border-radius: var(--r-ctl);
    background: transparent;
    font-family: inherit;
    font-size: var(--t-13);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}

/* A button and a checkbox show keyboard focus with the same ring, so a tab through a form
   never changes what focus looks like halfway. */
.tapp-btn:focus-visible,
.tapp-check:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--acc-soft);
}

/* The design system's own primary button: the brand indigo, with the page's ground colour
   as its text. It used to take the tenant's accent instead, which is a defensible idea and
   is not what the drawing shows - the owner picked this one, twice. The accent still drives
   everything the drawing drives with it: chips, steps, switches, the focus ring.

   The text flips in the light theme because the indigo does. `--brand-indigo` is #8084fc on
   the dark ground and #4f52d6 on the cream one, and dark text on the second is unreadable. */
.tapp-btn-primary {
    background: var(--brand-indigo);
    border-color: var(--brand-indigo);
    color: var(--on-brand);
}

.cr[data-theme="light"] .tapp-btn-primary {
    color: var(--on-accent);
}

.tapp-btn-primary:hover {
    filter: brightness(.92);
}

.tapp-btn-primary:active {
    filter: brightness(.85);
}

.tapp-btn-secondary {
    background: transparent;
    border-color: var(--border);
    color: var(--body);
    font-weight: 500;
}

.tapp-btn-secondary:hover {
    background: var(--hover);
    color: var(--head);
}

.tapp-btn-danger {
    background: transparent;
    border-color: var(--border);
    color: var(--bad);
}

.tapp-btn-danger:hover {
    background: var(--badbg);
    border-color: var(--bad);
}

/* FAZ 1b (.arcuby/orchestrate-tenant-panel/plan.md): three variants the button component
   was still missing, found while sweeping the shell's remaining `btn btn-*` pages onto this
   file. `-outline-primary` covers a page's own accent-coloured but lower-emphasis action
   (a per-row "Kaydet" beside a table, a "Test connection" beside a solid primary elsewhere on
   the same page) - distinct from `.tapp-btn-secondary`, which stays neutral on purpose.
   `-success` mirrors `-danger`'s own bordered-pill treatment (never solid, for the same
   unchecked-contrast reason `-primary`'s own remark gives) for a positive/confirm action
   that is not the page's main call to action. `-link` is for the handful of pages that want
   a plain text action (a wizard's "skip this step", an import's "undo") - not a button-shaped
   one, so it drops the box entirely rather than reusing `-secondary`'s bordered pill. */

.tapp-btn-outline-primary {
    background: transparent;
    border-color: var(--acc-solid);
    color: var(--acc-solid);
}

.tapp-btn-outline-primary:hover {
    background: var(--acc-soft);
}

.tapp-btn-success {
    background: transparent;
    border-color: var(--border);
    color: var(--ok);
}

.tapp-btn-success:hover {
    background: var(--okbg);
    border-color: var(--ok);
}

.tapp-btn-link {
    height: auto;
    padding: 0;
    background: transparent;
    border-color: transparent;
    color: var(--acc-solid);
    font-weight: 500;

    /* A link is a sentence, not a button caption. .tapp-btn's own `white-space: nowrap` keeps
       a two-word caption on one line, which is right for a button and wrong here: the price
       list's import-wizard link is a full sentence and ran straight out of its card. */
    white-space: normal;
    text-align: left;
}

.tapp-btn-link:hover {
    text-decoration: underline;
}

.tapp-btn:disabled,
.tapp-btn[aria-disabled="true"] {
    background: var(--card);
    border-color: var(--border);
    color: var(--muted);
    cursor: not-allowed;
    filter: none;
}

.tapp-btn-sm {
    height: 30px;
    padding: 0 11px;
    font-size: var(--t-12);
}

/* ---------------------------------------------------------------- inputs */

.tapp-input {
    display: block;
    width: 100%;
    height: 36px;
    padding: 0 11px;
    background: var(--input);
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    color: var(--head);
    font-family: inherit;
    font-size: var(--t-13-5);
}

.tapp-input::placeholder {
    color: var(--muted);
}

.tapp-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--acc-soft);
}

.tapp-input:disabled,
.tapp-input[readonly] {
    background: var(--thead);
    color: var(--muted);
    cursor: not-allowed;
}

.tapp-input.is-invalid {
    border-color: var(--bad);
}

.tapp-input.is-invalid:focus {
    border-color: var(--bad);
    box-shadow: 0 0 0 3px var(--badbg);
}

.tapp-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.tapp-field > label {
    font-size: var(--t-11-5);
    color: var(--muted);
}

.tapp-field-error {
    font-size: var(--t-12);
    color: var(--bad);
}

/* ---------------------------------------------------------------- checkbox */

/* A page's own "IsDefault" / "IsActive" toggle reaches for this instead of Bootstrap's
   `form-check-input`, which renders through `--bs-form-check-bg` and friends and stays a
   fixed white box regardless of `.cr`'s theme - the same bug `.tapp-card` exists to fix for
   `.card`, one section down. `appearance: none` replaces the native control outright rather
   than leaving it half-themed: `accent-color` alone would only recolour the checked state,
   and the unchecked box would still render the browser's own white square. Tenant panel
   shell rollout, continuing phase 2 (.arcuby/orchestrate-tenant-panel/plan.md) - `form-check`
   and `form-check-label` stay Bootstrap's own on the pages that use this, since neither
   carries a background colour that breaks under the dark theme. */

.tapp-check {
    appearance: none;
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    margin: 0;
    flex: 0 0 16px;
    background: var(--input);
    border: 1px solid var(--border);
    border-radius: var(--r-4);
    position: relative;
    cursor: pointer;
}

.tapp-check:checked {
    background: var(--acc-solid);
    border-color: var(--acc-solid);
}

.tapp-check:checked::after {
    content: '';
    position: absolute;
    left: 4px;
    top: 1px;
    width: 4px;
    height: 8px;
    border: solid var(--on-accent);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.tapp-check:disabled {
    background: var(--thead);
    border-color: var(--border);
    cursor: not-allowed;
}

/* The box and its words. `.tapp-check` styles the control itself - 16x16, appearance:none -
   so putting it on the wrapping <label> turns the label into a 16px square and its text spills
   out over whatever follows. That is what happened on the four windows written last: "Ödendi"
   was drawn on top of the "Kasa" label under it, and "Bu gider düzenli" came out one word per
   line. The row is a separate class, and the input keeps its own. */

.tapp-check-row {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: var(--t-13);
}

/* ---------------------------------------------------------------- file input */

/* A page's own import form (e.g. Pages/Finance/Parties/Index.cshtml) reaches for a native
   `<input type="file">` rather than `.tapp-input`: the pilot for that page left it on
   Bootstrap's `.form-control` because the browser draws its "choose file" part as a
   `::file-selector-button` pseudo-element that does not take `.tapp-input`'s own box-model
   rules. That pseudo-element is themeable on its own, so this class styles the input's own
   box the same way `.tapp-input` does and the button part through `::file-selector-button`,
   rather than leaving the exception standing. */

.tapp-file {
    display: block;
    width: 100%;
    padding: 6px 10px;
    background: var(--input);
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    color: var(--muted);
    font-family: inherit;
    font-size: var(--t-13);
}

.tapp-file::file-selector-button {
    height: 26px;
    padding: 0 12px;
    margin-right: 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-xs);
    background: var(--card);
    color: var(--body);
    font-family: inherit;
    font-size: var(--t-12-5);
    font-weight: 600;
    cursor: pointer;
}

.tapp-file::file-selector-button:hover {
    background: var(--hover);
}

.tapp-file:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--acc-soft);
}

/* ---------------------------------------------------------------- table */

.tapp-table-wrap {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    overflow: hidden;
}

.tapp-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-13);
}

.tapp-table thead tr {
    background: var(--thead);
}

.tapp-table th {
    padding: 9px 10px;
    text-align: left;
    font-size: var(--t-11);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted);
}

.tapp-table td {
    padding: 9px 10px;
    color: var(--body);
}

/* Not `td.num`: qualifying the element outweighs the stacked-card override below, which
   is one specificity point lighter, and a media query does not break that tie - the amounts
   would stay pinned right while their labels sat left. console.css sets `.ac-table .num`
   unqualified for the same reason. */
.tapp-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tapp-table tbody tr {
    border-top: 1px solid var(--border);
}

.tapp-table tbody tr:hover {
    background: var(--hover);
}

.cr[data-theme="light"] .tapp-table tbody tr:nth-child(even) {
    background: var(--zebra);
}

/* ---------------------------------------------------------------- table → card (narrow screens) */

/* docs/tenant-app-ui-design-brief.md §7's hardest mobile question - "yüzlerce satırlık bir
   tablo 375px'te ne olur" - answered by scratchpad/design/panel.dc.html's own "Cari listesi
   — mobil" and "İş emri — mobil" screens: a row becomes a card, not a horizontally scrolled
   table and not a table with columns dropped. One markup renders both states - no second,
   card-shaped copy of the same data - mirroring wwwroot/console/console.css's own answer to
   the same question one section down (same shape, same 767.98px breakpoint, tapp- prefixed
   and reading this file's own tokens, arrived at independently rather than shared - see this
   file's own top-of-file remarks on why the two never share rules).
 *
 * A page opts a cell into a role by tagging it tapp-c-title / tapp-c-badge / tapp-c-actions
 * (each positioned, `.tapp-c-title` also driving the whole card since a row's title is what
 * a caller opens); an untagged cell falls back to a labelled line using the value the page
 * put in its own `data-label` attribute (there being no `<th>` left once `thead` is hidden). */
@media (max-width: 767.98px) {
    .tapp-table-wrap {
        background: transparent;
        border: 0;
        border-radius: 0;
        overflow: visible;
    }

    .tapp-table,
    .tapp-table tbody,
    .tapp-table tr,
    .tapp-table td {
        display: block;
    }

    .tapp-table thead {
        display: none;
    }

    .tapp-table tbody tr {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
        background: var(--card);
        border: 1px solid var(--border);
        border-radius: var(--r-xl);
        padding: 12px;
        margin-bottom: 8px;
    }

    .tapp-table tbody tr:last-child {
        margin-bottom: 0;
    }

    .tapp-table td {
        padding: 0;
        flex: 1 1 100%;
        min-width: 0;
        margin-top: 8px;
        order: 3;
    }

    .tapp-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 2px;
        font-size: var(--t-10);
        font-weight: 600;
        letter-spacing: .05em;
        text-transform: uppercase;
        color: var(--muted);
    }

    .tapp-table td.tapp-c-title {
        margin-top: 0;
        flex: 1 1 auto;
        order: 0;
        font-weight: 600;
        color: var(--head);
    }

    .tapp-table td.tapp-c-title::before {
        content: none;
    }

    .tapp-table td.tapp-c-badge {
        margin-top: 0;
        margin-left: 8px;
        flex: 0 0 auto;
        align-self: center;
        order: 0;
    }

    .tapp-table td.tapp-c-badge::before {
        content: none;
    }

    /* The desktop column pins itself narrow with an inline `width:1%;white-space:nowrap`, which
       on a card made the cell a few pixels wide and pushed its buttons out past the card's right
       edge - the whole main area then scrolled sideways (Cari, Stok, Kasa, Gider). The
       !important is what overrides the inline style; the buttons wrap and the cell drops to its
       own line when it does not fit beside the title. */
    .tapp-table td.tapp-c-actions {
        margin-top: 0;
        margin-left: auto;
        padding-left: 8px;
        flex: 0 1 auto;
        max-width: 100%;
        width: auto !important;
        white-space: normal !important;
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 6px;
        text-align: right;
        order: 0;
    }

    .tapp-table td.tapp-c-actions::before {
        content: none;
    }

    /* Word actions ("Ekstre", "Düzenle", "Sil") need the card's own line - squeezed beside a
       title and a badge, three buttons run off a 375px card - the same reasoning as
       wwwroot/console/console.css's own `.is-stacked` for the same problem. */
    .tapp-table.is-stacked td.tapp-c-title {
        flex: 1 1 100%;
    }

    .tapp-table.is-stacked td.tapp-c-badge {
        margin-top: 8px;
        margin-left: 0;
    }

    .tapp-table.is-stacked td.tapp-c-actions {
        margin-top: 8px;
    }

    .tapp-table .num {
        text-align: left;
    }
}

/* ---------------------------------------------------------------- badge */

.tapp-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 20px;
    padding: 0 8px;
    border-radius: var(--r-20);
    font-size: var(--t-11);
    font-weight: 600;
    white-space: nowrap;
}

.tapp-badge-neutral,
.tapp-chips .badge.bg-secondary {
    background: var(--thead);
    color: var(--muted);
}

.tapp-badge-ok {
    background: var(--okbg);
    color: var(--ok);
}

.tapp-badge-warn {
    background: var(--warnbg);
    color: var(--warn);
}

.tapp-badge-bad {
    background: var(--badbg);
    color: var(--bad);
}

/* FAZ 1b: `bg-primary` had one use left (Messages/Index.cshtml's "unread" marker) that is
   neither an ok/warn/bad status nor a neutral tag - it is a highlight, the same accent tint
   the sidebar's own active item and the input's own focus ring already use (`--acc-soft` /
   `--acc-text`, see this file's own remarks near those). */
.tapp-badge-info {
    background: var(--acc-soft);
    color: var(--acc-text);
}

/* ---------------------------------------------------------------- tabs */

/* A page's own Bootstrap nav-tabs strip (Pages/Notifications/Channels/Index.cshtml) reads
   `--bs-nav-link-color` and paints its active pill with `--bs-nav-tabs-link-active-bg`
   (white), the same bug every other component in this file exists to fix. The active/
   inactive toggle there is a dynamic Razor expression on the `.nav-link` element itself
   (`class="nav-link @(cond ? "active" : "")"`) - not rewritten, since an earlier automated
   rename corrupted attributes shaped like that. So this scopes Bootstrap's own `.nav-link`
   class under the wrapper instead, the same way `.tapp-card .card-header` does two sections
   down: the page only adds `tapp-tabs` to the static `<ul>` wrapper, dropping `nav-tabs`,
   and every rule below reaches the unchanged `.nav-link` markup through that ancestor. */

.tapp-tabs {
    display: flex;
    align-items: center;
    gap: 4px;
    border-bottom: 1px solid var(--border);
}

.tapp-tabs .nav-link {
    padding: 9px 14px;
    margin-bottom: -1px;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: var(--r-ctl) var(--r-ctl) 0 0;
    background: transparent;
    color: var(--muted);
    font-size: var(--t-13);
    font-weight: 600;
}

.tapp-tabs .nav-link:hover {
    color: var(--head);
}

.tapp-tabs .nav-link.active {
    background: var(--card);
    border-color: var(--border);
    color: var(--head);
}

/* Pages/Undo/Index.cshtml's type filter is a row of chips whose selected state is a dynamic
   Razor ternary on both the chip's own `btn`/`btn-outline-secondary` and its count badge's
   `bg-light text-dark`/`bg-secondary` - not rewritten, same reason as `.tapp-tabs .nav-link`
   above. `tapp-chips` on the static wrapper reaches the unchanged markup instead. */
.tapp-chips .btn {
    border-radius: var(--r-20);
    font-weight: 600;
}

.tapp-chips .btn-primary {
    background: var(--acc-solid);
    border-color: var(--acc-solid);
    color: var(--on-accent);
}

.tapp-chips .btn-outline-secondary {
    background: transparent;
    border-color: var(--border);
    color: var(--body);
}

.tapp-chips .badge.bg-light.text-dark {
    /* Left as a literal, not --on-accent: the badge's own background here is a translucent
       white overlay, not a solid accent fill, so it is not the same case that token names. */
    background: var(--overlay-white);
    color: var(--on-accent);
}

/* ---------------------------------------------------------------- alert */

/* A generic version of this file's own .tapp-ro-banner, for a page that needs a success,
   error or informational strip rather than the specific read-only one the shell already
   renders (see that class's own remarks). Not merged with it: the shell's banner is a fixed
   part of the layout with its own render condition, and this is a page-level primitive. */

.tapp-alert {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--card);
}

.tapp-alert > i {
    font-size: 14px;
    color: var(--muted);
}

.tapp-alert-body {
    flex: 1;
    min-width: 180px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.tapp-alert-title {
    font-size: var(--t-13);
    font-weight: 600;
    color: var(--head);
}

.tapp-alert-text {
    font-size: var(--t-13);
    color: var(--body);
}

.tapp-alert-success {
    background: var(--okbg);
    border-color: var(--ok);
}

.tapp-alert-success > i {
    color: var(--ok);
}

.tapp-alert-danger {
    background: var(--badbg);
    border-color: var(--bad);
}

.tapp-alert-danger > i {
    color: var(--bad);
}

.tapp-alert-warning {
    background: var(--warnbg);
    border-color: var(--warn);
}

.tapp-alert-warning > i {
    color: var(--warn);
}

/* ---------------------------------------------------------------- card */

/* The generic boxed section - Bootstrap's own `.card`/`.card-header`/`.card-body`/
   `.card-title` - carried here as its own token-driven class for the same reason every
   other component in this file is: Bootstrap's version reads its own `--bs-card-bg` /
   `--bs-body-color` variables, never this file's tokens, so it renders as a fixed white box
   regardless of `.cr`'s theme. That is the bug this class exists to fix - first found on
   the dashboard's stat tiles (Pages/Dashboard/Index.cshtml, see `.tapp-stat` below), then
   found again on every other page under this shell that reaches for a boxed section, so it
   is fixed here once rather than per page. `.card-body`'s own descendant `.text-muted` is
   scoped under `.tapp-card` rather than renamed on every page, since it only ever matters
   once it is already inside a page's own opt-in `.tapp-card` - it cannot reach a `.card`
   that stayed Bootstrap's own, so it carries none of the risk a bare `.text-muted` rule
   would. */

/* The one surface every card family shares - border, radius, ground - shared
   here instead of repeated in `.tapp-pr-card`, `.tapp-sf-card` and
   `.tapp-wo-card` below; each of those keeps only the declarations that
   actually make it a different card (layout, cursor, overflow, ...). */
.tapp-card,
.tapp-pr-card,
.tapp-sf-card,
.tapp-wo-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
}

.tapp-card .card-header {
    padding: 11px 14px;
    font-size: var(--t-13);
    font-weight: 600;
    color: var(--head);
    background: var(--thead);
    border-bottom: 1px solid var(--border);
}

.tapp-card .card-header:first-child {
    border-radius: var(--r-9) var(--r-9) 0 0;
}

.tapp-card .card-body {
    padding: 16px;
    color: var(--body);
}

.tapp-card .card-title {
    margin: 0 0 8px;
    font-size: var(--t-15);
    font-weight: 600;
    color: var(--head);
}

.tapp-card .text-muted {
    color: var(--muted) !important;
}

/* ---------------------------------------------------------------- list */

/* Bootstrap's own `list-group` (Pages/Onboarding/Checklist.cshtml,
   Pages/Modules/Dispatch/Courier/Index.cshtml) reads `--bs-list-group-bg` and renders as a
   fixed white block, the bug `.tapp-card` exists to fix for `.card` above. The wrapper's
   own class is a static attribute on both pages and is renamed outright; the courier job
   list's selected item, though, is a dynamic Razor expression
   (`class="list-group-item list-group-item-action @(cond ? "active" : "")"`) - not
   rewritten, since an earlier automated rename corrupted attributes shaped like that. So
   `.list-group-item` and its `.active` state are scoped under `.tapp-list` instead, the
   same way `.tapp-tabs .nav-link` reaches its own unchanged markup above; a page written
   fresh can use `.tapp-list-item` directly instead. */

.tapp-list {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    overflow: hidden;
}

.tapp-list-item,
.tapp-list .list-group-item {
    padding: 10px 14px;
    background: var(--card);
    color: var(--body);
    font-size: var(--t-13-5);
    border-bottom: 1px solid var(--border);
}

.tapp-list-item:last-child,
.tapp-list .list-group-item:last-child {
    border-bottom: none;
}

.tapp-list .list-group-item-action:hover {
    background: var(--hover);
    color: var(--head);
    text-decoration: none;
}

.tapp-list .list-group-item.active {
    background: var(--acc-soft);
    color: var(--head);
}

/* ARCP-117 (Pages/Reports/Index.cshtml): a `.tapp-list-item` written fresh, as this file's
   own remarks above invite - a report the caller may run is an `<a>`, one they may not is a
   `<span>` dimmed by its own inline opacity, and both share this layout: a title/sub column
   that grows and an optional trailing icon (the lock) that does not. */
.tapp-list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    text-decoration: none;
}

a.tapp-list-item:hover {
    background: var(--hover);
    color: var(--head);
    text-decoration: none;
}

/* The selected report in the picker - `aria-current="page"` rather than a second `.active`
   spelling, since this list is a set of destinations (each an `asp-route-Key`) and not a
   toggle. */
.tapp-list-item[aria-current="page"] {
    background: var(--hover);
}

/* ---------------------------------------------------------------- stat tile */

/* The dashboard's own tile (Pages/Dashboard/Index.cshtml): a muted label, a large figure,
   an optional muted sub-line and a details link, on the same surface `.tapp-card` defines
   above rather than a second one - one dark-mode-safe box recipe for the whole shell. */

.tapp-stat {
    height: 100%;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.tapp-stat-label {
    font-size: var(--t-12-5);
    color: var(--muted);
}

/* Tracking is size-specific, never one value for the whole panel (Apple, "The Details of UI
   Typography"): large text reads too loose at the spacing small text needs, so the figures on
   every summary band are tightened, and the micro uppercase labels above them were widened far
   less than they used to be - 2.5px was legible but drifted apart at a glance. */
.tapp-stat-value {
    font-size: 26px;
    letter-spacing: -.02em;
    font-weight: 600;
    color: var(--head);
}

.tapp-stat-sub {
    font-size: var(--t-12);
    color: var(--muted);
}

/* FAZ 6: a tile's own reading, not decoration - Pages/Dashboard/Index.cshtml adds one of
   these where the number is good/bad news (revenue in, money owed out) and leaves a tile
   plain where it is only a count (open work orders, stock value) with no such reading. The
   border rides the same `.tapp-card` box these tiles already are (`.tapp-card.tapp-stat` is
   one element, not two) - only the leading edge changes colour, so the tinted tiles still
   read as the same component, not a different one. */
.tapp-stat-ok {
    border-left: 3px solid var(--ok);
}

.tapp-stat-ok .tapp-stat-value {
    color: var(--ok);
}

.tapp-stat-warn {
    border-left: 3px solid var(--warn);
}

.tapp-stat-warn .tapp-stat-value {
    color: var(--warn);
}

.tapp-stat-bad {
    border-left: 3px solid var(--bad);
}

.tapp-stat-bad .tapp-stat-value {
    color: var(--bad);
}

/* FAZ: the dashboard's own tile is a link now, whole. The old screen repeated a
   "Detaya git" anchor under all seven of them - seven identical tab stops carrying the
   same words, and six of them a smaller click target than the box they sat in. */
a.tapp-stat {
    text-decoration: none;
    transition: background-color var(--t-fast);
}

a.tapp-stat:hover {
    background: var(--hover);
}

/* One currency at figure size, the rest on a quiet line beside it. The old tile joined
   every currency with " \u00b7 " at 26px, so a tenant billing in two currencies overflowed
   the box on the widest tile it had. */
.tapp-stat-amount-alt {
    font-size: var(--t-13);
    color: var(--muted);
}

/* The one sentence that says what a figure means. A large number with nothing next to it
   was the thing this redesign set out to fix. */
.tapp-stat-caption {
    font-size: var(--t-13);
    color: var(--body);
}

/* Three readings of one subject in a single panel - stock count, stock value, stock at risk.
   They must not wrap to a second line when the panel narrows, because the three only mean
   anything read together, so the panel is a container and the type inside it scales with
   `cqi` instead. `clamp` puts a floor and a ceiling on each step, so the smallest panel is
   still legible and the widest does not turn the labels into headings. */
.tapp-stat-trio {
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
    padding: 0;
    background: var(--border);
    overflow: hidden;
    container-type: inline-size;
}

/* The first box of each trio is that band's headline - stock value, open work orders,
   revenue, receivables - and the order is DashboardBandView's own, so the emphasis follows
   the data rather than a hand-picked list here. Four panels of three identically weighted
   figures gave twelve numbers with no way in; the lead takes a wider share and a larger
   figure, its siblings step down. */
.tapp-stat-trio > .tapp-trio-item:first-child {
    flex: 1.35 1 0;
}

.tapp-stat-trio > .tapp-trio-item:first-child .tapp-trio-label {
    color: var(--body);
}

.tapp-stat-trio > .tapp-trio-item:first-child .tapp-trio-value {
    font-size: clamp(19px, 3.2cqi, 28px);
}

.tapp-stat-trio > .tapp-trio-item + .tapp-trio-item .tapp-trio-value {
    font-size: clamp(var(--t-15), 2.4cqi, 21px);
    letter-spacing: -.4px;
}

/* Three figures side by side stop being readable once the panel is this narrow, so they
   stack. The break comes from the panel's own container query rather than the viewport: the
   same panel is wide on a tablet and narrow on a phone, and both readings are right. */
@container (max-width: 420px) {
    .tapp-stat-trio > .tapp-trio-item,
    .tapp-stat-trio > .tapp-trio-item:first-child {
        flex: 1 1 100%;
    }
}

/* The 1px gap over the border-coloured panel is what draws the dividers - three real borders
   would double up against the panel's own edge. */
.tapp-trio-item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: clamp(11px, 1.7cqi, 18px) clamp(12px, 1.9cqi, 22px);
    background: var(--card);
    text-decoration: none;
}

.tapp-trio-item:hover {
    background: var(--hover);
}

.tapp-trio-item[hidden] {
    display: none !important;
}

.tapp-trio-label {
    font-size: clamp(8.5px, 1.1cqi, 10.5px);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tapp-trio-value {
    font-size: clamp(var(--t-15), 3.3cqi, 30px);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.8px;
    color: var(--head);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.tapp-trio-sub {
    font-size: clamp(9.5px, 1.3cqi, var(--t-12));
    line-height: 1.4;
    color: var(--muted);
}

/* The sub-lines run one to three lines, which left the boxes at ragged heights. A two-line
   floor lines them up; longer text still grows past it rather than being clipped, because
   this is the only place that sentence appears and a clipped one is simply lost.
   Only needed while the boxes are side by side - stacked, there is no neighbour to line up
   with and the floor would just leave a gap on a phone. */
@container (min-width: 421px) {
    .tapp-trio-sub {
        min-height: calc(2 * 1.4em);
    }
}

/* Past this the explanatory line is the first thing to go: the three figures are the point,
   and a sentence at 9px is not read anyway. */
@container (max-width: 340px) {
    .tapp-trio-sub {
        display: none;
    }
}

/* ---------------------------------------------------------------- dashboard band */

/* FAZ: the seven tiles used to sit in one flat Bootstrap row, which gave "how many cars
   are in the workshop" and "what the shelves are worth" the same weight - a number looked
   at every morning next to one looked at at month end. They are two bands now
   (Pages/Dashboard/Index.cshtml), each headed by the question its tiles answer. A band
   with no tile the caller may see is not rendered at all, so a heading never hangs over
   an empty row. */

/* The band-to-card gap is tighter than the gap between bands, so three bands read as three
   groups rather than one long stack of cards. */
.tapp-band {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.tapp-band + .tapp-band {
    margin-top: 12px;
}

.tapp-band[hidden] {
    display: none;
}

.tapp-band-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 2px;
}

/* The label is a signpost over the tiles, not a heading competing with the page title above
   them - hence --muted and the wide tracking rather than --head at full strength. */
.tapp-band-label {
    font-size: var(--t-11);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color: var(--muted);
}

.tapp-band-rule {
    flex: 1;
    height: 1px;
    background: var(--border);
}

/* ---------------------------------------------------------------- dashboard grid */

/* The auto-fit grid the mixed dashboard uses: it holds tiles and charts of two different
   widths, so the column count cannot be derived from a tile count. */
.tapp-dash-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
    align-items: stretch;
}

.tapp-span-all {
    grid-column: 1 / -1;
}

/* A grid item's default minimum is its min-content width, so one card holding a row that
   cannot wrap widened the single phone column past the screen and the whole main area slid
   sideways (Hesap - Menü, once the phone type scale made its labels longer). The column is
   the screen's width; what is inside a card wraps inside the card. */
.tapp-dash-grid > * {
    min-width: 0;
}

/* A permission-hidden card is out of the grid entirely, not an empty cell in it. */
.tapp-dash-grid > [hidden] {
    display: none;
}

/* The module boxes (IDashboardBox) are tiles, not bands: a lone box keeps a tile's width
   instead of stretching across the page, which auto-fit would do. */
.tapp-dash-grid.is-boxes {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

/* ...but a box that is the only one takes the row. At a tile's width it left two thirds of
   the line empty beside it on a desktop, which reads as something missing rather than as a
   deliberate tile; a box with a list in it has the rows to fill the width (fleet.css lays
   the fleet box's rows out in columns when it gets it). Counted by card, not `:only-child`:
   a box's component writes its own <link> beside it. */
.tapp-dash-grid.is-boxes:not(:has(> .tapp-card ~ .tapp-card)) > .tapp-card {
    grid-column: 1 / -1;
}

/* The module boxes' grid when every box declined to draw. */
.tapp-dash-grid:not(:has(> *)) {
    display: none;
}

/* Two columns of a 240px-minimum grid stop being two readable columns before they stop
   fitting, so the wide cards give up their span first. */

/* ---------------------------------------------------------------- charts */

/* A chart is the same surface as a stat tile (`.tapp-card`), with its own padding and its own
   head - the point of the redesign was that a figure with nothing beside it says nothing, and
   a chart with no stated question is the same failure one size up. */
.tapp-chart {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 18px 20px;
    min-width: 0;
}

.tapp-card.tapp-chart {
    padding: 18px 20px;
}

.tapp-chart-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.tapp-chart-title {
    font-size: var(--t-13-5);
    font-weight: 700;
    color: var(--head);
}

.tapp-chart-head .tapp-chart-title {
    white-space: nowrap;
}

/* One line saying which question the chart answers - the thing a bare axis label cannot. */
.tapp-chart-note {
    font-size: var(--t-12);
    color: var(--muted);
    line-height: 1.4;
}

.tapp-chart-total {
    margin-left: auto;
    font-size: var(--t-13);
    font-weight: 700;
    color: var(--head);
    font-variant-numeric: tabular-nums;
}

/* The plot is inline SVG at 100% width with a fixed height: the bars re-space themselves with
   the card, and nothing has to be re-rendered when the grid reflows. */
.tapp-chart-svg {
    display: block;
    width: 100%;
    height: 132px;
}

/* `preserveAspectRatio="none"` was pulling the columns sideways on a wide card - a fixed
   height against a growing width stretches the viewBox rather than re-spacing it. Tying the
   height to the viewBox's own ratio takes the stretch out.
   Only above the bar's existing 640px break: below it the ratio would give a 92px plot on a
   phone, so the app's own 112px stays. */
@media (min-width: 641px) {
    .tapp-chart-svg {
        height: auto;
        aspect-ratio: 560 / 132;
        max-height: 196px;
    }
}

.tapp-chart-xlabels {
    display: grid;
    grid-auto-flow: column;
    /* `minmax(0, 1fr)` rather than a bare `1fr`, which floors each track at its content, so
       one five-digit loss (-15.060) swells its own column and the strip grows past the chart
       it labels - 13px of sideways scroll on a 390px phone. Every other label is hidden at
       that width, so a long figure has its neighbour's room. */
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
    padding-top: 6px;
    font-size: 9.5px;
    color: var(--muted);
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* Each tick is a day with its figure under it, so the reader gets the value without a
   tooltip. The day comes first because it is what the axis is: a five-digit amount read
   before the date it belongs to is a number with nothing to attach to. */
.tapp-chart-xlabels span {
    display: flex;
    flex-direction: column;
    gap: 1px;
    line-height: 1.35;
}

.tapp-chart-xlabels b {
    font-size: 10.5px;
    font-weight: 700;
    color: var(--head);
}

.tapp-chart-legend {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 2px;
    font-size: var(--t-11-5);
    color: var(--muted);
}

.tapp-chart-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* The items with no swatch are notes rather than keys - the daily average, and the two
   sentences that own up to the drawn window not being the selected period. A tone behind the
   keyed items, by opacity rather than by a colour mixed towards the page, which would fade in
   one theme and brighten in the other. */
.tapp-chart-legend-item:not(:has(.tapp-chart-swatch)) {
    color: var(--muted);
    opacity: .8;
}

.tapp-chart-swatch {
    width: 9px;
    height: 9px;
    border-radius: var(--r-2);
    display: inline-block;
}

.tapp-bars {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

/* Label, bar, value on one grid rather than three floated pieces: the bars all start and end
   on the same two verticals however long the longest label is. */
.tapp-bar-row {
    display: grid;
    grid-template-columns: minmax(84px, auto) 1fr minmax(78px, auto);
    align-items: center;
    gap: 12px;
}

.tapp-bar-label {
    font-size: var(--t-12);
    color: var(--body);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tapp-bar-track {
    display: block;
    width: 100%;
    height: 10px;
}

.tapp-bar-value {
    font-size: var(--t-12);
    color: var(--head);
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* A bar with a zero line: profit right, loss left, so a losing row is visible as a shape
   before the number beside it is read. */
.tapp-diverge {
    height: 12px;
}

/* Below this a bar row folds to named areas instead of dropping a column, since every one of
   them is part of the answer. */
@media (max-width: 767.98px) {
    .tapp-head-slot {
        margin-left: 0;
        width: 100%;
    }

    .tapp-chart-xlabels > span:nth-child(even) {
        visibility: hidden;
    }

    .tapp-bar-row {
        grid-template-columns: 1fr auto;
        grid-template-areas: "label value" "track track";
        gap: 4px 10px;
    }

    .tapp-bar-label {
        grid-area: label;
    }

    .tapp-bar-value {
        grid-area: value;
    }

    .tapp-bar-track {
        grid-area: track;
    }
}

@media (max-width: 560px) {
    .tapp-dash-grid {
        grid-template-columns: 1fr;
    }

    .tapp-chart {
        padding: 14px 14px;
    }

    .tapp-chart-svg {
        height: 112px;
    }
}

/* A list page's figures (İş emirleri, Cari, Stok, Kasa: a grid holding nothing but stat
   tiles) are a glance, not the content. Stacked as full cards on a phone, three of them at
   ~110px each filled the first screen and pushed the list itself below it - the reverse of
   "the content first" (Apple, Principles of Great Design: simplicity). On a phone each tile
   becomes one slim row instead - the label on the left, the figure on the right, the way a
   grouped list reads on iOS. Rows rather than three columns because a cari's figure is a
   currency amount like ₺1.778.483,33, which does not fit a third of a phone's width at any
   readable size. The dashboard's own grids hold other kinds of card and are left alone; the
   selector only matches a grid whose every visible child is a `.tapp-stat`. */
@media (max-width: 767.98px) {
    .tapp-dash-grid:not(.is-boxes):has(> .tapp-stat):not(:has(> :not(.tapp-stat, [hidden]))) {
        grid-template-columns: 1fr;
        gap: 6px;
    }

    .tapp-dash-grid:not(.is-boxes) > .tapp-stat {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        column-gap: 12px;
        row-gap: 2px;
        min-width: 0;
        padding: 10px 14px;
    }

    .tapp-dash-grid:not(.is-boxes) > .tapp-stat .tapp-stat-label {
        font-size: var(--t-13);
    }

    .tapp-dash-grid:not(.is-boxes) > .tapp-stat .tapp-stat-value {
        font-size: 17px;
        font-variant-numeric: tabular-nums;
    }

    .tapp-dash-grid:not(.is-boxes) > .tapp-stat .tapp-stat-sub {
        flex-basis: 100%;
    }
}

/* ---------------------------------------------------------------- period navigator */

/* The arrows and the period picker are one block so that the custom-range panel below has a
   single thing to anchor to, whichever of them opened it. */
.tapp-period {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Hidden rather than disabled on a custom range: "previous month" has no meaning once the
   caller has named two dates themselves. */
.tapp-period-nav {
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--muted);
    font-size: var(--t-11);
    cursor: pointer;
}

.tapp-period-nav:hover {
    background: var(--hover);
    color: var(--brand-indigo);
}

.tapp-period-nav[hidden] {
    display: none !important;
}

/* The custom-range panel reuses `.tapp-field`, but its labels sit above inputs in a dropdown
   rather than in a form column, so they take body strength instead of the muted caption
   `.tapp-field > label` gives them everywhere else. */
.tapp-daterange .tapp-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.tapp-daterange .tapp-field label {
    font-size: var(--t-12);
    color: var(--body);
}

/* The calendar glyph on "custom range", in the brand cyan the system gives secondary icons. */
.tapp-range i {
    font-size: var(--t-11);
}

.tapp-seg > a.tapp-range i {
    color: var(--brand-cyan);
}

/* The row under the page title: which days the panel is showing, how to change them, and the
   way out to the full reports. It wraps rather than compressing - on a phone the date and the
   period buttons each get their own line, because a segmented control squeezed to four
   two-character labels is a control nobody can hit. */
.tapp-period-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 10px;
}

/* The dates themselves. This line answers the reader's next question after the title, so it
   is read at full strength rather than left as another grey line in a row of grey lines. */
.tapp-period-range {
    font-size: var(--t-13);
    font-weight: 600;
    color: var(--head);
    white-space: nowrap;
}

/* Forward, once the period has reached today. It keeps its 30px so the row does not jump
   sideways as the caller steps back through months and the arrow comes and goes, and it takes
   no hover: a control that lights up under the pointer and then does nothing is worse than one
   that plainly cannot be pressed. The reason is in its own title attribute. */
.tapp-period-nav-off,
.tapp-period-nav-off:hover {
    background: transparent;
    color: var(--border);
    cursor: default;
}

/* The two-date form, shown only while the period is custom. It hangs under the control rather
   than opening as a popover: it is already the selected state, so there is nothing to dismiss,
   and a panel that cannot be closed by mistake is one fewer thing to get wrong. */
.tapp-daterange {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 20;
    display: flex;
    align-items: flex-end;
    gap: 10px;
    padding: 12px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-menu);
}

.tapp-daterange .tapp-input {
    width: auto;
    min-width: 150px;
}

/* On a tile whose figure cannot follow the period: the shelf holds what it holds now, and no
   table records what it held last month.
   It sits inside the tile's own label, so it was inheriting that label's uppercase and 2.5px
   tracking - "STOK MALIYETI BUGUN ITIBARIYLA" read as two headings rather than a figure and
   its footnote. It speaks in a footnote's voice now: lower case, no tracking, faded, behind
   a separating dot. */
.tapp-asof {
    margin-left: 4px;
    font-size: 9px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    color: var(--muted);
    opacity: .62;
    white-space: nowrap;
}

.tapp-asof::before {
    content: "\00b7";
    margin-right: 3px;
    opacity: .7;
}

/* On a phone the tiles' container is narrow enough that the cqi-driven labels above sat at
   their floors - 8.5px headings, 9px "bugün itibarıyla", 9.5px sub-lines - which reads only
   by zooming in. 11px is the smallest the panel uses anywhere else for running text. */
@media (max-width: 767.98px) {
    .tapp-trio-label,
    .tapp-asof {
        font-size: 11px;
    }

    .tapp-trio-sub {
        font-size: var(--t-12);
    }
}

@media (max-width: 640px) {
    /* ARCP-179: the four periods stay one row on a phone. The row takes the full width and
       the type scales with the screen rather than the labels wrapping: at 360px that is about
       9.7px, which still reads, where a second row of broken words does not. clamp's floor is
       what stops it disappearing on a narrower phone and its ceiling keeps a large phone at
       the same 12px as everywhere else. min-width: 0 is what actually lets the pills shrink -
       a flex item refuses to go below its content width without it. */
    .tapp-period {
        flex: 1 1 100%;
        flex-wrap: nowrap;
        min-width: 0;
    }

    .tapp-period-bar .tapp-seg {
        flex: 1 1 auto;
        flex-wrap: nowrap;
        justify-content: space-between;
        min-width: 0;
    }

    .tapp-period-bar .tapp-seg > a {
        padding: 5px 7px;
        gap: 4px;
        font-size: clamp(9px, 2.7vw, var(--t-12));
    }

    .tapp-daterange {
        left: auto;
        right: 0;
    }
}

/* ---------------------------------------------------------------- permission empty state */

/* What the dashboard shows a caller with no reporting permission at all: not the generic
   `.tapp-empty` with its call to action, since there is no action this caller can take - the
   dashed edge says the space is intentionally empty rather than failed to load. */
/* The flex/centring/surface .tapp-empty-perm shares with the generic
   .tapp-empty below - only the border style, gap and padding actually tell
   the two states apart (a dashed edge and no icon tile, since there is no
   action this caller can take). */
.tapp-empty-perm,
.tapp-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    border-radius: var(--r-card);
    background: var(--card);
}

.tapp-empty-perm {
    gap: 10px;
    padding: 56px 24px;
    border: 1px dashed var(--border);
}

.tapp-empty-perm i {
    font-size: 22px;
    color: var(--muted);
}

.tapp-empty-perm h3 {
    margin: 0;
    font-weight: 700;
}

/* Both empty states title and explain themselves in the same type; only the weight and the
   spacing differ between the permission card and the plain empty card, so those stay with
   each. */
.tapp-empty-perm h3,
.tapp-empty h3 {
    font-size: var(--t-15);
    color: var(--head);
}

.tapp-empty-perm p {
    margin: 0;
    max-width: 44ch;
    line-height: 1.5;
}

.tapp-empty-perm p,
.tapp-empty p {
    font-size: var(--t-13);
    color: var(--muted);
}

/* ---------------------------------------------------------------- empty state */

.tapp-empty {
    border: 1px solid var(--border);
    padding: 54px 24px;
}

.tapp-empty-icon {
    width: 46px;
    height: 46px;
    border-radius: var(--r-xl);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--thead);
    color: var(--muted);
    font-size: 17px;
    margin-bottom: 14px;
}

.tapp-empty h3 {
    margin: 0 0 6px;
    font-weight: 600;
}

.tapp-empty p {
    margin: 0 0 16px;
    max-width: 420px;
}

/* The design system's own paragraph inside an empty state, narrower than `.tapp-empty p` and
   with no bottom margin because nothing follows it. It is what the approved screens use to
   name the permission a caller is missing, which is a sentence rather than a call to action -
   see the kasa detail's own locked state. The only class either the kasa or the gider drawing
   asked for that this stylesheet did not already have. */
.tapp-empty-body {
    font-size: var(--t-13);
    color: var(--muted);
    max-width: 340px;
    line-height: 1.5;
}

@media (max-width: 767.98px) {
    .tapp-empty {
        padding: 34px 18px;
    }
}

/* ---------------------------------------------------------------- info hint */

/* The circled-i beside a heading or label (Pages/Shared/_InfoHint.cshtml) that stands in for
   a secondary explanation moved off the screen and into a bubble a reader opens on purpose
   (ARCP, owner 21 September 2026 - "ekran karışık durmasın ama açıklamalarda kaybolmasın").
   `.tapp-notif-panel` above is this same anchor-and-clamp trick already blessed in this file:
   `position: absolute` off a `position: relative` wrapper, `max-width` cut against the
   viewport rather than a fixed figure, so the bubble never asks a 390px phone - the narrowest
   this panel supports - for more room than it has.

   That trick alone was not enough here: unlike the bell, this icon can land anywhere along a
   heading, so a fixed `left: 0` overflows a 390px screen whenever the heading before it is
   long enough to push the icon past the phone's own midpoint (measured against the actual
   Turkish text of every call site this first wave converts - "İş kategorisine göre kâr" and
   "Abonelik ve ödeme" both do this, most others do not). The `@supports` block below is the
   real fix, not decoration: CSS Anchor Positioning tracks the button's actual screen position
   and flips which side the bubble grows from when the default side would run past the
   viewport, which nothing expressible in `max-width` alone can do without knowing where the
   icon sits. `max-width` is still cut narrower than the bell's own panel so that a browser
   without anchor support - which keeps the plain `left: 0` below - still fits every one of
   those same real call sites without it. */
.tapp-hint {
    position: relative;
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
}

/* A checkbox row's own <label> already has its labelled control inside it (the checkbox
   itself), so a hint's <button> stays a sibling rather than nesting in too - see
   Pages/Finance/CashAccounts/_CashDialogs.cshtml's own remark. This keeps that sibling pair
   on one line instead of the row's parent (a column flex dialog body) dropping the hint onto
   an orphan line of its own. */
.tapp-check-row-hint {
    display: flex;
    align-items: center;
    gap: 8px;
}

.tapp-hint-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--muted);
    font-size: var(--t-13);
    line-height: 1;
    cursor: pointer;
    transition: color var(--t-fast);
}

.tapp-hint-btn:hover,
.tapp-hint-btn:focus-visible {
    outline: none;
    color: var(--acc-solid, var(--accent));
}

/* The glyph is 16x13, under the 24px a mouse pointer needs even at a desk (WCAG 2.5.8): an
   invisible 24px square centred on it, which the coarse-pointer block at the end of this file
   grows to 44px on a touch screen. */
.tapp-hint-btn {
    position: relative;
}

.tapp-hint-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, 24px);
    height: max(100%, 24px);
    transform: translate(-50%, -50%);
}

/* Opacity is what hides this, never `visibility` or `display`: the button's own
   `aria-describedby` names this element, and a screen reader reads an element's text
   regardless of its opacity but drops one that is `visibility: hidden` - which would silence
   the very description the button points at until a sighted reader happened to hover it. */
.tapp-hint-bubble {
    position: absolute;
    z-index: 60;
    top: calc(100% + 6px);
    left: 0;
    width: max-content;
    max-width: min(200px, calc(100vw - 32px));
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: var(--card);
    box-shadow: var(--shadow-dlg);
    color: var(--body);
    font-size: var(--t-12);
    font-weight: 400;
    line-height: 1.45;
    text-align: left;
    text-wrap: pretty;

    /* The icon sits beside whatever it explains, and some of those headings are drawn as
       uppercase micro-labels with widened tracking (the dashboard's own band titles, the
       stat tiles). The bubble inherits from the heading, so the explanation came out
       shouting - measured on the deployed page, 21 September 2026. It carries its own
       casing and tracking for that reason, not the heading's. */
    text-transform: none;
    letter-spacing: normal;
    word-wrap: break-word;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--t-fast);
}

/* `anchor-name` (on the button) and `position-anchor` (naming it back, here) are written per
   instance as inline styles keyed off the same `Model.Id` the aria wiring already needs -
   see _InfoHint.cshtml's own remarks - because two bubbles open on the same page and a single
   shared name in this stylesheet would leave the browser to guess which button either of them
   belongs to. `position: fixed` here (Chrome/Edge 125+, Safari 26+, Firefox 133+) also carries
   the bubble out of an ancestor's own `overflow: hidden` - the table wrapper's rounded corners,
   a dialog's own scroll body - the same way `.tapp-notif-panel` never has to worry about it
   because a bell never sits inside either. */
@supports (position-try-fallbacks: flip-inline) {
    .tapp-hint-bubble {
        position: fixed;
        top: calc(anchor(bottom) + 6px);
        left: anchor(left);
        position-try-fallbacks: flip-inline, --tapp-hint-gutter;
    }
}

/* The third try, for an icon near the middle of a phone: a 200px bubble then fits neither
   starting at the icon nor ending at it, and the browser kept the first try - 11px past the
   screen's edge on the signup card. Pinned to the page's own 16px gutter instead, still
   under the icon, so it always lands on screen. */
@position-try --tapp-hint-gutter {
    top: calc(anchor(bottom) + 6px);
    left: auto;
    right: 16px;
}

.tapp-hint:hover .tapp-hint-bubble,
.tapp-hint:focus-within .tapp-hint-bubble {
    opacity: 1;
    pointer-events: auto;
}

/* ---------------------------------------------------------------- foreign pages */

/* FAZ 3: Identity/Users, Identity/Roles and SettingManagement are ABP's own Razor pages,
   shipped compiled inside Volo.Abp.Identity.Web / Volo.Abp.SettingManagement.Web - Bootstrap
   markup this repository does not own and cannot add a page-level `tapp-` class to (every
   other section in this file is scoped under a class a page's own markup opts into; there is
   no page here to edit). `_TenantAppLayout.cshtml` adds `.tapp-foreign` to the content
   wrapper on its own behalf, once, when the page's model does not belong to this project's
   assembly - see that file's own remarks - so the opt-in still happens in exactly one place,
   it is just the layout making the call instead of the page. Every rule below is scoped under
   that wrapper for the same reason every `.tapp-*` component rule elsewhere in this file is
   scoped under its own wrapper: a bare `table`/`btn`/`card` selector here would reach the
   ~80 first-party pages this shell also serves, which is the one thing this stylesheet's own
   header forbids.

   Coverage is the page shell (typography, card, table, buttons, form controls, badges,
   nav-tabs, alerts, dropdown, pagination) - the pieces ABP's own Users/Roles/SettingManagement
   index pages actually render. Their own modal dialogs (CreateModal/EditModal,
   FeatureManagementModal) are injected by ABP's dynamic-modal script outside this wrapper
   entirely and are not covered here; see FAZ 3 report for why that is a known, separate gap
   rather than an oversight. */

.tapp-foreign {
    color: var(--body);
    font-size: var(--t-13-5);
}

.tapp-foreign h1,
.tapp-foreign h2,
.tapp-foreign h3,
.tapp-foreign h4,
.tapp-foreign h5,
.tapp-foreign h6 {
    color: var(--head);
}

.tapp-foreign a {
    color: var(--acc-solid);
}

.tapp-foreign .text-muted {
    color: var(--muted) !important;
}

.tapp-foreign .card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    color: var(--body);
}

.tapp-foreign .card-header {
    background: var(--thead);
    color: var(--head);
    border-bottom: 1px solid var(--border);
}

.tapp-foreign .card-footer {
    background: var(--thead);
    border-top: 1px solid var(--border);
}

.tapp-foreign .card-title {
    color: var(--head);
}

.tapp-foreign .table,
.tapp-foreign table.dataTable {
    color: var(--body);
    border-color: var(--border);
}

.tapp-foreign .table thead th,
.tapp-foreign table.dataTable thead th {
    background: var(--thead);
    color: var(--muted);
    border-color: var(--border);
}

.tapp-foreign .table td,
.tapp-foreign .table th,
.tapp-foreign table.dataTable td,
.tapp-foreign table.dataTable th {
    border-color: var(--border);
}

.tapp-foreign .table-striped > tbody > tr:nth-of-type(odd) > * {
    background: var(--zebra);
    color: var(--body);
}

.tapp-foreign .table-hover > tbody > tr:hover > * {
    background: var(--hover);
    color: var(--head);
}

.tapp-foreign .dataTables_wrapper .dataTables_length select,
.tapp-foreign .dataTables_wrapper .dataTables_filter input {
    background: var(--input);
    border: 1px solid var(--border);
    color: var(--head);
}

.tapp-foreign .dataTables_wrapper .dataTables_info,
.tapp-foreign .dataTables_wrapper .dataTables_length,
.tapp-foreign .dataTables_wrapper .dataTables_filter {
    color: var(--muted);
}

.tapp-foreign .dataTables_wrapper .dataTables_paginate .paginate_button {
    color: var(--body) !important;
    border-color: var(--border);
}

.tapp-foreign .dataTables_wrapper .dataTables_paginate .paginate_button.current {
    background: var(--acc-solid) !important;
    border-color: var(--acc-solid) !important;
    color: var(--on-accent) !important;
}

.tapp-foreign .dataTables_wrapper .dataTables_paginate .paginate_button.disabled {
    color: var(--muted) !important;
}

.tapp-foreign .btn {
    border-radius: var(--r-ctl);
    font-weight: 600;
}

.tapp-foreign .btn-primary {
    background: var(--acc-solid);
    border-color: var(--acc-solid);
    color: var(--on-accent);
}

.tapp-foreign .btn-secondary,
.tapp-foreign .btn-light {
    background: transparent;
    border-color: var(--border);
    color: var(--body);
}

.tapp-foreign .btn-outline-primary {
    background: transparent;
    border-color: var(--acc-solid);
    color: var(--acc-solid);
}

.tapp-foreign .btn-outline-secondary {
    background: transparent;
    border-color: var(--border);
    color: var(--body);
}

.tapp-foreign .btn-danger,
.tapp-foreign .btn-outline-danger {
    background: transparent;
    border-color: var(--bad);
    color: var(--bad);
}

.tapp-foreign .btn-success,
.tapp-foreign .btn-outline-success {
    background: transparent;
    border-color: var(--ok);
    color: var(--ok);
}

.tapp-foreign .btn:disabled,
.tapp-foreign .btn[aria-disabled="true"] {
    background: var(--card);
    border-color: var(--border);
    color: var(--muted);
}

.tapp-foreign .form-control,
.tapp-foreign .form-select,
.tapp-foreign textarea.form-control {
    background: var(--input);
    border: 1px solid var(--border);
    color: var(--head);
}

.tapp-foreign .form-control:focus,
.tapp-foreign .form-select:focus {
    background: var(--input);
    border-color: var(--accent);
    color: var(--head);
    box-shadow: 0 0 0 3px var(--acc-soft);
}

.tapp-foreign .form-control:disabled,
.tapp-foreign .form-control[readonly] {
    background: var(--thead);
    color: var(--muted);
}

.tapp-foreign .form-label,
.tapp-foreign .form-check-label {
    color: var(--body);
}

.tapp-foreign .form-text {
    color: var(--muted);
}

.tapp-foreign .input-group-text {
    background: var(--thead);
    border: 1px solid var(--border);
    color: var(--muted);
}

.tapp-foreign .badge.bg-primary {
    background: var(--acc-soft) !important;
    color: var(--acc-text) !important;
}

.tapp-foreign .badge.bg-success {
    background: var(--okbg) !important;
    color: var(--ok) !important;
}

.tapp-foreign .badge.bg-warning {
    background: var(--warnbg) !important;
    color: var(--warn) !important;
}

.tapp-foreign .badge.bg-danger {
    background: var(--badbg) !important;
    color: var(--bad) !important;
}

.tapp-foreign .badge.bg-secondary,
.tapp-foreign .badge.bg-light {
    background: var(--thead) !important;
    color: var(--muted) !important;
}

.tapp-foreign .nav-tabs {
    border-color: var(--border);
}

.tapp-foreign .nav-tabs .nav-link {
    color: var(--muted);
    border-color: transparent;
}

.tapp-foreign .nav-tabs .nav-link:hover {
    color: var(--head);
}

.tapp-foreign .nav-tabs .nav-link.active {
    background: var(--card);
    border-color: var(--border) var(--border) var(--card);
    color: var(--head);
}

.tapp-foreign .alert-success {
    background: var(--okbg);
    border-color: var(--ok);
    color: var(--ok);
}

.tapp-foreign .alert-danger {
    background: var(--badbg);
    border-color: var(--bad);
    color: var(--bad);
}

.tapp-foreign .alert-warning {
    background: var(--warnbg);
    border-color: var(--warn);
    color: var(--warn);
}

.tapp-foreign .alert-info {
    background: var(--acc-soft);
    border-color: var(--acc-solid);
    color: var(--acc-text);
}

.tapp-foreign .dropdown-menu {
    background: var(--card);
    border: 1px solid var(--border);
}

.tapp-foreign .dropdown-item {
    color: var(--body);
}

.tapp-foreign .dropdown-item:hover,
.tapp-foreign .dropdown-item:focus {
    background: var(--hover);
    color: var(--head);
}

.tapp-foreign .page-link {
    background: var(--card);
    border-color: var(--border);
    color: var(--body);
}

.tapp-foreign .page-item.active .page-link {
    background: var(--acc-solid);
    border-color: var(--acc-solid);
    color: var(--on-accent);
}

.tapp-foreign .page-item.disabled .page-link {
    background: var(--thead);
    color: var(--muted);
}

/* ---------------------------------------------------------------- payroll (K)

   The approved payroll screen is the first one in this application to need a
   period navigator over a detail header, a running-total block under a table and
   a filter strip with counted chips. Every class below is one of those - taken
   from the design's own `yeni-siniflar*.css`, and only the rules for classes this
   stylesheet did not already have.

   What was deliberately NOT taken: the design draws its own tabs (`tapp-tab`),
   field labels (`tapp-label`) and dialog as a div-plus-scrim. This file already
   has all three - `.tapp-tabs .nav-link`, `.tapp-field > label` and a real
   `<dialog class="tapp-dialog">` - so the screen uses those instead of a second
   spelling of the same thing. */

/* The page head: title on the left, period navigator and actions on the right,
   the actions dropping to their own line before the title is ever squeezed. */
.tapp-v3-head {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}

.tapp-v3-head .tapp-page-head-text {
    flex: 1 1 280px;
    min-width: 280px;
}

/* .tapp-head-slot itself is not redefined here - it is byte-identical to the
   shared definition above .tapp-page-title (this file's own remark there:
   "The trailing slot a page fills with its own controls"), so the payroll
   screen reuses that one instead of shipping a second, silently-overriding
   copy - the same reuse this section's own opening remark already applies
   to .tapp-tabs, .tapp-field and .tapp-dialog. */

/* One option of a segmented control - the statement's own date range. */
.tapp-seg-item {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border: none;
    border-radius: var(--r-xs);
    background: transparent;
    font-family: inherit;
    font-size: var(--t-12-5);
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    cursor: pointer;
}

.tapp-seg-item:hover {
    color: var(--head);
}

/* A segment's chosen item and a chip under the pointer take the same quiet fill - neither is
   the accent, because neither is a commitment yet. A chosen chip's own accent (.is-active)
   stays in the chip section. */
.tapp-seg-item.is-active,
.tapp-chip:hover {
    background: var(--hover);
    color: var(--head);
}

/* Search plus filters on one line, wrapping rather than scrolling. */
.tapp-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--card);
}

.tapp-toolbar-search {
    position: relative;
    flex: 1 1 220px;
    min-width: 180px;
}

.tapp-toolbar-search > i {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    font-size: var(--t-11);
    color: var(--muted);
    pointer-events: none;
}

.tapp-toolbar-search .tapp-input {
    padding-left: 30px;
}

.tapp-toolbar-end {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* A filter chip, with the count of what it would leave on screen. */
.tapp-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 11px;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: transparent;
    color: var(--body);
    font-family: inherit;
    font-size: var(--t-12-5);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}

.tapp-chip.is-active {
    border-color: var(--accent, var(--brand-indigo));
    color: var(--acc-text, var(--head));
    background: var(--acc-soft, var(--hover));
}

.tapp-chip-count {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* The calendar screen's own swatch (Pages/Modules/Appointments/Index.cshtml, ARCP-130): the
   colour an appointment type paints its own slots with. The colour itself is always inline
   (it is per-row tenant data, not a class this stylesheet could name in advance) - only its
   shape lives here. */
.tapp-cal-swatch {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: none;
    border: 1px solid var(--swatch-ring);
}

/* The week and month views' own grid - seven equal columns whatever the viewport, each cell a
   day. Reuses .tapp-table-wrap's own scroll behaviour on narrow screens rather than a second
   overflow rule. */
.tapp-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(120px, 1fr));
    gap: 6px;
}

.tapp-cal-cell {
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    padding: 6px 8px;
    min-height: 64px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.tapp-cal-cell-date {
    font-size: var(--t-11);
    font-weight: 700;
    color: var(--muted);
}

.tapp-cal-cell-item {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--t-12);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A titled block of content, with the title outside the surface rather than in
   a card header - so a table can run edge to edge under its own caption. */
.tapp-frame {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.tapp-frame-cap {
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--muted);
}

/* Numeric table cells. Right-aligned and tabular so a column of money reads as a
   column: proportional digits make 1.111 look narrower than 8.888. */
.tapp-table-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.tapp-num-neg {
    color: var(--bad);
}

.tapp-num-pos {
    color: var(--ok);
}

/* The third tone the pair was missing: a number that is not wrong, only worth noticing -
   a shelf down to its own critical level. Its badge says the same thing in words, so this
   is the second of two signals rather than the only one (stok ekranı, §11). */
.tapp-num-warn {
    color: var(--warn);
}

/* The detail header: who this is, and the standing facts about them. */
.tapp-detail-head {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    flex-wrap: wrap;
    padding: 18px 20px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--card);
}

.tapp-detail-title {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1 1 240px;
    min-width: 0;
}

.tapp-detail-name {
    font-size: 19px;
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.3px;
}

.tapp-detail-meta {
    font-size: var(--t-12-5);
    color: var(--muted);
}

.tapp-kv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 14px 22px;
    flex: 2 1 380px;
}

.tapp-kv {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.tapp-kv-k {
    font-size: var(--t-10);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--muted);
}

.tapp-kv-v {
    font-size: var(--t-13-5);
    font-weight: 600;
    color: var(--head);
    font-variant-numeric: tabular-nums;
}

/* The totals block under a document's own lines. */
.tapp-totals {
    display: flex;
    justify-content: flex-end;
    padding: 14px 16px;
    border-top: 1px solid var(--border);
    background: var(--thead);
}

.tapp-totals-inner {
    display: grid;
    grid-template-columns: auto minmax(110px, auto);
    gap: 7px 26px;
    min-width: 280px;
}

.tapp-total-k {
    font-size: var(--t-12-5);
    color: var(--muted);
}

.tapp-total-v {
    font-size: var(--t-12-5);
    color: var(--body);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tapp-total-grand.tapp-total-k,
.tapp-total-grand.tapp-total-v {
    font-size: var(--t-15);
    font-weight: 700;
    color: var(--head);
    padding-top: 7px;
    border-top: 1px solid var(--border);
}

/* A wide main column beside a narrower one, stacking on a small screen. */
.tapp-split {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

@media (max-width: 900px) {
    .tapp-split {
        grid-template-columns: 1fr;
    }
}

/* A field's own explanation, under the input it explains. */
.tapp-hint {
    font-size: var(--t-11-5);
    line-height: 1.45;
    color: var(--muted);
}

/* The dialog's own action row. `.tapp-dialog` and its head and body are already
   defined above; only the footer was missing. */
.tapp-dialog-foot {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    background: var(--thead);
}

/* ================================================================ iş emri (A)
   The approved iş emri board and detail (Claude Design "A - Is emri v2"). Two
   groups below: the page patterns the design system had that this stylesheet did
   not yet carry - steps, timeline, pager, row actions, form sections - and then
   the screen's own `tapp-wo-` classes, taken from `yeni-siniflar-isemri.css`
   as written.

   What was deliberately not taken: the design draws its dialogs as a div plus a
   scrim and writes `class="tapp-label"` on every label. This file already has a
   real `<dialog class="tapp-dialog">`, and `.tapp-label` is added below as an
   alias for the `.tapp-field > label` rule that was already here rather than as a
   second spelling of it. */

/* A label a page writes out itself, rather than relying on being inside a
   `.tapp-field`. Same rule, one selector wider - the design names the class
   directly and a page should not have to know which of the two it is in. */
.tapp-label {
    font-size: var(--t-11-5);
    color: var(--muted);
}

/* Required-field asterisk. */
.tapp-req {
    color: var(--bad);
    margin-left: 2px;
}

/* A form broken into headed sections - "Araç", "Cari", "İş". */
.tapp-form-section {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.tapp-form-section-head {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
}

.tapp-form-section-title {
    font-size: var(--t-13-5);
    font-weight: 700;
    color: var(--head);
}

.tapp-form-section-note {
    font-size: var(--t-12);
    color: var(--muted);
    line-height: 1.45;
}

/* Two columns where there is room, one where there is not. */
.tapp-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
}

.tapp-form-grid .tapp-field-wide {
    grid-column: 1 / -1;
}

/* --------------------------------------------------------- the status strip */

/* Passed, standing on, still to come. Every step is a button here - see
   `WorkOrderStatus`'s own remarks for why nothing moves a car but a person.

   ARCP-142: this used to carry `flex-wrap: wrap`, and the circle below a hard 22px - so a
   strip that did not fit dropped its last step to a second line with the connector left
   hanging. The step count comes from the vertical (`WorkOrderStages.All`), not a fixed six,
   so wrapping was never going to be right for all of them. `flex-wrap` is gone (the default
   is `nowrap`) and the sizes below use `cqi`/`clamp()` against `.tapp-wo-steps-row`'s own
   container query instead, so the strip shrinks to fit rather than wrapping - see that
   selector's own remarks for the phone case, where shrinking further stops being legible. */
.tapp-steps {
    display: flex;
    align-items: center;
    gap: 0;
    flex: 1;
    min-width: 0;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--card);
}

.tapp-step {
    display: flex;
    align-items: center;
    gap: clamp(5px, 1.2cqi, 9px);
    font-size: clamp(10.5px, 1.7cqi, var(--t-12-5));
    font-weight: 600;
    color: var(--muted);
    white-space: nowrap;
}

.tapp-step-no {
    width: clamp(16px, 2.6cqi, 22px);
    height: clamp(16px, 2.6cqi, 22px);
    flex: 0 0 clamp(16px, 2.6cqi, 22px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    font-size: clamp(9px, 1.3cqi, var(--t-11));
    font-variant-numeric: tabular-nums;
}

.tapp-step.is-done {
    color: var(--body);
}

.tapp-step.is-done .tapp-step-no {
    background: var(--ok);
    border-color: var(--ok);
    color: var(--bg);
}

.tapp-step.is-now {
    color: var(--head);
}

.tapp-step.is-now .tapp-step-no {
    background: var(--acc-solid, var(--brand-indigo));
    border-color: var(--acc-solid, var(--brand-indigo));
    color: var(--bg);
}

.tapp-step-line {
    flex: 1 1 24px;
    min-width: clamp(6px, 1.6cqi, 16px);
    height: 1px;
    margin: 0 clamp(4px, 1.4cqi, 12px);
    background: var(--border);
}

/* ------------------------------------------------------------ the movements */

.tapp-timeline {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.tapp-tl-item {
    display: grid;
    grid-template-columns: 14px 1fr auto;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
    align-items: baseline;
}

.tapp-tl-item:last-child {
    border-bottom: none;
}

.tapp-tl-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--r-pill);
    background: var(--border);
    margin-top: 5px;
}

.tapp-tl-item.is-ok .tapp-tl-dot {
    background: var(--ok);
}

.tapp-tl-item.is-bad .tapp-tl-dot {
    background: var(--bad);
}

.tapp-tl-item.is-warn .tapp-tl-dot {
    background: var(--warn);
}

.tapp-tl-text {
    font-size: var(--t-13);
    color: var(--body);
    line-height: 1.45;
}

.tapp-tl-time {
    font-size: var(--t-11-5);
    color: var(--muted);
    white-space: nowrap;
}

/* ---------------------------------------------------------------- the pager */

.tapp-pager {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding-top: 4px;
}

.tapp-pager-info {
    font-size: var(--t-12-5);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-pager-end {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 4px;
}

.tapp-pager-btn {
    min-width: 30px;
    height: 30px;
    padding: 0 9px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--body);
    font-family: inherit;
    font-size: var(--t-12-5);
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}

.tapp-pager-btn:hover:not(:disabled) {
    background: var(--hover);
    color: var(--head);
}

.tapp-pager-btn:disabled {
    opacity: .45;
    cursor: default;
}

/* --------------------------------------------------------- row-end actions */

/* Appear on hover; always visible on a touch screen, where there is no hover. */
.tapp-rowact {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: var(--r-ctl);
    background: transparent;
    color: var(--muted);
    font-size: var(--t-12);
    cursor: pointer;
}

.tapp-rowact:hover {
    background: var(--hover);
    color: var(--head);
    border-color: var(--border);
}

.tapp-rowact.is-bad:hover {
    color: var(--bad);
    border-color: var(--bad);
}

tr .tapp-rowact {
    opacity: 0;
}

tr:hover .tapp-rowact,
tr:focus-within .tapp-rowact {
    opacity: 1;
}

/* The same reveal, for a row whose actions are labelled buttons rather than bare icons.
   Scoped to .tapp-wo-row - the class a clickable row already carries - so no ordinary table
   loses its action cell. The stok drawing does this with component state and says so in its
   own notes ("CSS parent-hover kuralı yazılmadı"), which is the drawing admitting it could
   not write the rule, not asking for the state. */
.tapp-wo-row .tapp-c-actions {
    opacity: 0;
    transition: opacity var(--t-fast);
}

.tapp-wo-row:hover .tapp-c-actions,
.tapp-wo-row:focus-within .tapp-c-actions {
    opacity: 1;
}

/* "No hover" is a property of the screen, not of its width: keyed to the phone breakpoint
   alone, an iPad in landscape (over 767px, still touch) showed these rows with no actions at
   all. `hover: none` catches every touch screen; the width stays for a narrow window. */
@media (max-width: 767.98px), (hover: none) {
    tr .tapp-rowact {
        opacity: 1;
    }

    /* No hover on a touch screen, so the labelled actions stay put - the identical exception
       the icon buttons above already take. */
    .tapp-wo-row .tapp-c-actions {
        opacity: 1;
    }
}

/* ====================================== the iş emri screen's own classes ====
   From `yeni-siniflar-isemri.css`, as written. Every rule is scoped to a
   `tapp-wo-` class, which is the contract that file states for itself. */

/* Pano: yatayda kayan sütun şeridi. */
.tapp-wo-board{
  display:flex;
  gap:12px;
  overflow-x:auto;
  padding-bottom:12px;
  align-items:flex-start;
  /* Tarayıcı varsayılanı açık gri geliyor ve sıcak paletin dışında kalıyor;
     çubuk saç teli kenarlıkla aynı renge çekildi. */
  scrollbar-width:thin;
  scrollbar-color:var(--border) var(--bg);
}
.tapp-wo-board::-webkit-scrollbar{height:8px}
.tapp-wo-board::-webkit-scrollbar-track{background:var(--bg);border-radius:var(--r-pill)}
.tapp-wo-board::-webkit-scrollbar-thumb{
  background:var(--border);
  border-radius:var(--r-pill);
  transition:background-color var(--t-fast);
}
.tapp-wo-board::-webkit-scrollbar-thumb:hover{background:var(--muted)}
.tapp-wo-col{flex:0 0 258px;display:flex;flex-direction:column;gap:8px}

/* Sütun başlığı: durum rengini 2px çizgi ve nokta olarak taşır. */
.tapp-wo-col-head{display:flex;align-items:baseline;gap:8px;padding:0 2px 8px;border-bottom:1px solid var(--border)}
.tapp-wo-col-dot{width:8px;height:8px;border-radius:var(--r-pill);flex:0 0 8px;align-self:center}
.tapp-wo-col-name{font-size:var(--t-11);font-weight:700;letter-spacing:1.2px;text-transform:uppercase;color:var(--head)}
.tapp-wo-col-count{font-size:var(--t-11);color:var(--muted);font-variant-numeric:tabular-nums}
.tapp-wo-col-sum{margin-left:auto;font-size:var(--t-11-5);color:var(--muted);font-variant-numeric:tabular-nums}

/* İş emri kartı — zemini renklenmez, hover'da yüzey değişir. */
.tapp-wo-card{display:flex;flex-direction:column;gap:7px;padding:12px 14px;cursor:pointer;text-align:left;text-decoration:none;transition:background-color var(--t-fast),border-color var(--t-fast)}
.tapp-wo-card:hover{background:var(--hover)}
.tapp-wo-plate{font-size:var(--t-15);font-weight:700;color:var(--head);letter-spacing:-.2px}
.tapp-wo-sub{font-size:var(--t-12);color:var(--muted);line-height:1.4}
.tapp-wo-foot{display:flex;align-items:center;gap:8px;margin-top:2px}
.tapp-wo-amt{margin-left:auto;font-size:var(--t-12-5);font-weight:600;color:var(--head);font-variant-numeric:tabular-nums}
.tapp-wo-flags{display:flex;align-items:center;gap:10px;font-size:var(--t-11-5);color:var(--muted)}
.tapp-wo-flags i{margin-right:4px}

/* Not satırı: solda tip glifi, sağda metin ve o notun fotoğrafları. */
/* Not ayracı: saç teli kenarlık burada fazla siliniyordu, tokenden
   bir tık açık bir tona çekildi. Kalınlık yine 1px. */
.tapp-wo-note{display:grid;grid-template-columns:auto 1fr;gap:0 12px;padding:14px 0;border-bottom:1px solid color-mix(in oklch, var(--border) 55%, var(--muted))}
.tapp-wo-note:last-of-type{border-bottom:none}
.tapp-wo-note-dot{width:26px;height:26px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;font-size:var(--t-11);background:var(--hover);color:var(--muted);border:1px solid var(--border)}
.tapp-wo-note-body,
.tapp-sf-state-text {display:flex;flex-direction:column;gap:6px;min-width:0}
.tapp-wo-note-top{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.tapp-wo-note-title{font-size:var(--t-13-5);font-weight:700;color:var(--head)}
.tapp-wo-note-meta{font-size:var(--t-11-5);color:var(--muted);margin-left:auto}
.tapp-wo-note-text{font-size:var(--t-13);line-height:1.55;color:var(--body);margin:0;text-wrap:pretty}

/* Fotoğraf şeridi — hem galeride hem not içinde aynı kutu.
   ARCP-141: `overflow:hidden` clipped the strip at whatever the panel's own width allowed -
   about two and a half shots - with no way to reach the rest short of the "+N" overflow
   button. Scrolling reaches every photograph already rendered here; the scrollbar itself
   stays out of a strip this compact rather than taking the newer, wider `.tapp-shell` theme
   (see that selector's own remarks) that a thumbnail row this size has no room for. */
.tapp-wo-gal{
  display:flex;
  gap:8px;
  flex-wrap:nowrap;
  overflow-x:auto;
  overflow-y:hidden;
  scrollbar-width:none;
  -ms-overflow-style:none;
}
.tapp-wo-gal::-webkit-scrollbar{display:none}
.tapp-wo-shot{width:78px;height:58px;flex:0 0 78px;border-radius:var(--r-xs);border:1px solid var(--border);background:var(--input);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:var(--t-13);cursor:pointer;overflow:hidden;padding:0;transition:border-color var(--t-fast),color var(--t-fast)}
.tapp-wo-shot img,
.tapp-wo-photo-thumb img,
.tapp-wo-tile img {width:100%;height:100%;object-fit:cover;display:block}
.tapp-wo-shot:hover,
.tapp-wo-tile:hover,
.tapp-wo-chip-add:hover {border-color:var(--acc-solid,var(--brand-indigo));color:var(--head)}

/* Kalem satırı açılınca çıkan maliyet / parça no / stok bloğu. */
.tapp-wo-exp{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:14px;padding:14px 16px;background:var(--thead)}

/* Yön B — çalışma masası: solda notlar, sağda kalemler.
   Kalem sütunu daha geniş; tablo altı toplamlar Yön A ile aynı kalıpta. */
.tapp-wo-desk{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);
  gap:16px;
  align-items:start;
}
.tapp-wo-desk-col{display:flex;flex-direction:column;gap:14px;min-width:0}
@media (max-width:1100px){
  .tapp-wo-desk{grid-template-columns:minmax(0,1fr)}
}

/* Kalem tablosunun altındaki özet — tablonun devamı, ayrı bir kutu değil:
   2px çizgiyle ayrılır ama boşluk yoktur. İki sütuna dizilerek yer kaplamaz. */
.tapp-wo-sum{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  background:var(--thead);
  border-top:2px solid color-mix(in oklch, var(--border) 55%, var(--muted));
}
.tapp-wo-sum-row{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:12px;
  padding:6px 16px;
  border-bottom:1px solid var(--border);
}
.tapp-wo-sum-row:nth-child(odd){border-right:1px solid var(--border)}
.tapp-wo-sum-k{font-size:var(--t-12);color:var(--muted)}
.tapp-wo-sum-v{font-size:var(--t-12-5);color:var(--body);font-variant-numeric:tabular-nums}
.tapp-wo-sum-row.is-muted .tapp-wo-sum-v{color:var(--muted)}
.tapp-wo-sum-row.is-pos .tapp-wo-sum-v{color:var(--ok)}
/* Genel toplam iki sütunu birden kaplar, alt çizgisi olmaz. */
.tapp-wo-sum-row.is-grand{
  grid-column:1 / -1;
  border-bottom:none;
  border-right:none;
  padding:10px 16px;
}
.tapp-wo-sum-row.is-grand .tapp-wo-sum-k{font-size:var(--t-12-5);font-weight:700;color:var(--head)}
.tapp-wo-sum-row.is-grand .tapp-wo-sum-v{font-size:17px;font-weight:700;color:var(--head);letter-spacing:-.3px}

/* Kalem tablosunda her kalem kendi tbody'sinde (satır + açılan detay).
   Gruplar arasına tek bir saç teli çizgi girer; ilkinin üstünde çizgi olmaz. */
.tapp-wo-rows tbody > tr:first-child > td{border-top:1px solid color-mix(in oklch, var(--border) 55%, var(--muted))}
.tapp-wo-rows tbody:first-of-type > tr:first-child > td{border-top:none}

/* Bir iş emrinde birden çok usta çalışır. Künyede isimler yan yana
   yazılınca satır şişiyordu; baş harf rozetleri dizilir, tam ad title'da.
   Dörtten fazlası "+N" olur — yükseklik hiç değişmez. */
.tapp-wo-people{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.tapp-wo-person{width:26px;height:26px;font-size:10.5px}
/* "+3 kişi daha" — üstüne gelince ya da odaklanınca tam listeyi açar.
   Panel tapp-notif-panel ile aynı dili konuşur: kart zemini, saç teli
   kenarlık, gölge yok. */

.tapp-wo-more-label{
  font-size:var(--t-12);
  color:var(--muted);
  border-bottom:1px dashed var(--border);
  cursor:default;
  transition:color var(--t-fast),border-color var(--t-fast);
}
.tapp-wo-more:hover .tapp-wo-more-label,
.tapp-wo-more:focus-visible .tapp-wo-more-label{color:var(--head);border-color:var(--acc-text,var(--brand-indigo))}
.tapp-wo-pop{
  position:absolute;
  top:calc(100% + 8px);
  left:0;
  z-index:40;
  display:none;
  flex-direction:column;
  gap:10px;
  min-width:246px;
  padding:12px 14px;
  border:1px solid var(--border);
  border-radius:var(--r-card);
  background:var(--card);
}
.tapp-wo-more:hover .tapp-wo-pop,
.tapp-wo-more:focus-within .tapp-wo-pop{display:flex}
.tapp-wo-pop-cap{
  font-size:var(--t-10);
  font-weight:700;
  letter-spacing:1.2px;
  text-transform:uppercase;
  color:var(--muted);
}
.tapp-wo-pop-row{display:flex;align-items:center;gap:10px}
.tapp-wo-pop-text,
.tapp-yn-group-text {display:flex;flex-direction:column;gap:2px;min-width:0}
.tapp-wo-pop-name{font-size:var(--t-12-5);font-weight:600;color:var(--head)}
.tapp-wo-pop-sub{font-size:var(--t-11-5);color:var(--muted);line-height:1.4}

/* Durum şeridi elle ilerletilir: adımlar tıklanabilir.
   ARCP-142: `container-type` makes this row the query container `.tapp-steps` and its
   children scale against with `cqi` (see that selector's own remarks) - the shrink tracks
   this row's own rendered width, which is narrower than the viewport on anything but a
   phone, not the viewport itself. `flex-wrap` is gone for the same reason it is gone from
   `.tapp-steps`: the row must stay one line, and wrapping was the actual defect. */
.tapp-wo-steps-row{display:flex;align-items:center;gap:12px;container-type:inline-size}
/* Adımlar tıklanabilir: çip gibi kenarlık taşırlar, üstlerine gelince
   yüzey ve kenarlık renk değiştirir — düğme oldukları okunur. */
.tapp-wo-step{
  cursor:pointer;
  padding:clamp(3px, 0.7cqi, 5px) clamp(6px, 1.4cqi, 11px);
  border:1px solid var(--border);
  border-radius:var(--r-ctl);
  background:var(--card);
  font-family:inherit;
  transition:background-color var(--t-fast),border-color var(--t-fast),color var(--t-fast);
}
.tapp-wo-step:hover{background:var(--hover);border-color:var(--acc-solid,var(--brand-indigo));color:var(--head)}
.tapp-wo-step.is-now{border-color:var(--acc-solid,var(--brand-indigo))}
.tapp-wo-step:focus-visible{outline:none;border-color:var(--acc-solid,var(--brand-indigo))}

/* Six steps still do not fit on one line at a legible size once a phone gets this narrow -
   `clamp()` above has already reached its floor by then. The strip used to scroll sideways
   here, which hid the steps either side of the current one and broke the panel's one rule on
   a phone: it scrolls down, never across. So on a phone the steps become a grid of chips,
   every one visible and tappable, and the connectors go - a line between two chips that sit
   one above the other joins nothing. The grid fills by column count, not by a fixed six, so a
   vertical with more or fewer stages still lays out. */
@media (max-width: 767.98px) {
  .tapp-wo-steps-row .tapp-steps{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(132px,1fr));
    gap:8px;
    padding:12px;
  }
  .tapp-wo-steps-row .tapp-step-line{display:none}
  .tapp-wo-steps-row .tapp-wo-step{
    padding:8px 10px;
    font-size:var(--t-12-5);
  }
  .tapp-wo-steps-row .tapp-step-no{
    width:22px;
    height:22px;
    flex-basis:22px;
  }
}

/* Künyedeki kayıt bağlantısı: değer gibi okunur, ikon yalnızca üstüne
   gelince belirir — künye satırı bağlantı çöplüğüne dönmesin. */
.tapp-wo-link{
  display:inline-flex;
  align-items:center;
  gap:7px;
  font-size:var(--t-13-5);
  font-weight:600;
  color:var(--head);
  text-decoration:none;
  transition:color var(--t-fast);
}
/* Ad rengini değiştirmez; ikon her zaman görünür ve aksan renginde durur. */
.tapp-wo-link i{font-size:var(--t-10);color:var(--acc-text,var(--brand-indigo));transition:color var(--t-fast)}
.tapp-wo-link:hover i,
.tapp-wo-link:focus-visible i{color:var(--head)}

/* Her notun fotoğraf şeridinin başında sabit ekleme kutusu. */
.tapp-wo-shot-add{
  border:1px solid var(--acc-solid,var(--brand-indigo));
  background:var(--acc-soft,var(--hover));
  color:var(--acc-text,var(--brand-indigo));
  cursor:pointer;
  padding:0;
  font-size:14px;
  flex:0 0 auto;
}
.tapp-wo-shot-add:hover{background:var(--acc-solid,var(--brand-indigo));color:var(--on-accent);border-color:var(--acc-solid,var(--brand-indigo))}

/* Şeride sığmayan fotoğraflar tek kutuda toplanır; şerit hiç sarmaz. */
.tapp-wo-shot-more{
  cursor:pointer;
  font-size:var(--t-12-5);
  font-weight:600;
  color:var(--muted);
  background:var(--hover);
  flex:0 0 auto;
}
.tapp-wo-shot-more:hover{color:var(--head);border-color:var(--acc-solid,var(--brand-indigo))}

/* KDV anahtarı — varsayılan kapalı; açılınca oran alanı belirir. */
.tapp-wo-kdv{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.tapp-wo-switch{display:inline-flex;align-items:center;gap:9px;background:none;border:none;padding:0;cursor:pointer}
.tapp-wo-switch-track{
  width:34px;height:20px;flex:0 0 34px;
  border-radius:var(--r-pill);
  background:var(--hover);
  border:1px solid var(--border);
  position:relative;
  transition:background-color var(--t-fast),border-color var(--t-fast);
}
.tapp-wo-switch-knob{
  position:absolute;top:3px;left:3px;
  width:12px;height:12px;
  border-radius:var(--r-pill);
  background:var(--muted);
  transition:transform var(--t-fast),background-color var(--t-fast);
}
.tapp-wo-switch.is-on .tapp-wo-switch-track{background:var(--acc-soft);border-color:var(--acc-solid)}
.tapp-wo-switch.is-on .tapp-wo-switch-knob{transform:translateX(14px);background:var(--acc-solid)}
.tapp-wo-switch-label{font-size:var(--t-13);color:var(--body)}
.tapp-wo-switch.is-on .tapp-wo-switch-label{color:var(--head);font-weight:600}

/* Diyalog ölçüleri tek yerde. */
.tapp-wo-modal{width:520px;max-width:calc(100vw - 32px);max-height:calc(100vh - 48px)}
/* Fotoğraf görüntüleyici — iş emrindeki bir küçük resme tıklayınca açılan pencere.
   Resim pencerenin değil, ekranın ölçüsüne göre büyür: bir hasar fotoğrafı bakılmak
   için çekilmiştir, 78 piksellik bir kare olarak değil. */
.tapp-wo-photo-view{width:min(92vw,1040px);max-width:none}
.tapp-wo-photo-stage{position:relative;display:flex;align-items:center;justify-content:center;
  gap:8px;padding:4px 12px 12px;background:var(--thead);border-radius:var(--r-ctl);margin:0 4px}
.tapp-wo-photo-stage img{max-width:100%;max-height:min(72vh,720px);object-fit:contain;
  display:block;border-radius:var(--r-xs);background:var(--input)}
.tapp-wo-photo-step{flex:0 0 36px;height:36px;border-radius:var(--r-pill);border:1px solid var(--border);
  background:var(--card);color:var(--head);cursor:pointer;display:flex;align-items:center;
  justify-content:center}
.tapp-wo-photo-step:hover{border-color:var(--acc-solid,var(--brand-indigo))}
/* ARCP-141: the row under the big picture that reaches every photograph in the strip the
   viewer opened on, without walking the arrows one at a time. A dialog control benefits from
   showing it can scroll rather than hiding it - `.tapp-wo-board`-style thin bar, not the
   hidden one `.tapp-wo-gal` uses on the page itself. */
.tapp-wo-photo-thumbs{
  display:flex;
  gap:6px;
  overflow-x:auto;
  padding:2px 4px 4px;
  margin:0 4px;
  scrollbar-width:thin;
  scrollbar-color:var(--border) var(--bg);
}
.tapp-wo-photo-thumbs::-webkit-scrollbar{height:6px}
.tapp-wo-photo-thumbs::-webkit-scrollbar-track{background:var(--bg);border-radius:var(--r-pill)}
.tapp-wo-photo-thumbs::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--r-pill)}
.tapp-wo-photo-thumbs[hidden]{display:none}
.tapp-wo-photo-thumb{
  flex:0 0 56px;
  width:56px;
  height:42px;
  padding:0;
  border-radius:var(--r-xs);
  border:2px solid transparent;
  background:var(--input);
  cursor:pointer;
  overflow:hidden;
}

.tapp-wo-photo-thumb.is-active{border-color:var(--acc-solid,var(--brand-indigo))}
.tapp-wo-photo-view .tapp-dialog-foot{display:flex;align-items:center;gap:10px}
.tapp-wo-photo-view .tapp-dialog-foot .tapp-hint{margin-right:auto}

.tapp-wo-modal-wide{width:760px}
/* Başlık solda, kapatma düğmesi panelin sağ üstünde — ikisi aynı hizada. */
.tapp-wo-modal .tapp-dialog-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
.tapp-wo-modal .tapp-dialog-head .tapp-iconbtn{flex:0 0 32px;margin-left:auto}

/* Parça arama sonuçları — seçili satır aksan kenarlığı alır,
   stokta olmayan satır tıklanamaz (o parça kaleme eklenemez). */
.tapp-wo-results{display:flex;flex-direction:column;gap:6px;max-height:196px;overflow-y:auto;padding:2px}
.tapp-wo-res{
  display:flex;
  align-items:center;
  gap:12px;
  width:100%;
  padding:10px 12px;
  border:1px solid var(--border);
  border-radius:var(--r-ctl);
  background:var(--card);
  text-align:left;
  cursor:pointer;
  transition:background-color var(--t-fast),border-color var(--t-fast);
}
.tapp-wo-res:hover{background:var(--hover)}
.tapp-wo-res.is-active{border-color:var(--acc-solid,var(--brand-indigo));background:var(--hover)}
.tapp-wo-res.is-off{opacity:.5;cursor:not-allowed}
.tapp-wo-res.is-off:hover{background:var(--card)}
.tapp-wo-res-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.tapp-wo-res-name{font-size:var(--t-13);font-weight:600;color:var(--head)}
.tapp-wo-res-meta{font-size:var(--t-11-5);color:var(--muted)}
.tapp-wo-res-price{font-size:var(--t-12-5);color:var(--body);font-variant-numeric:tabular-nums;white-space:nowrap}

/* Tüm fotoğraflar ızgarası — diyalog içinde kayar, sayfayı uzatmaz. */
.tapp-wo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:10px;max-height:56vh;overflow-y:auto}
.tapp-wo-tile{aspect-ratio:4 / 3;border-radius:var(--r-ctl);border:1px solid var(--border);background:var(--input);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:16px;cursor:pointer;overflow:hidden;padding:0}

/* Fotoğraf ekleme: telefonda kamera birincil yol, dosya seçme ikincil.
   Sürükle-bırak alanı yalnızca masaüstünde işe yaradığı için alta iner. */
.tapp-wo-capture{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tapp-wo-capture-note{flex:1 1 100%;font-size:var(--t-12);color:var(--muted);line-height:1.45}

.tapp-wo-pick-x{
  position:absolute;
  top:3px;
  right:3px;
  width:18px;
  height:18px;
  display:flex;
  align-items:center;
  justify-content:center;
  border:1px solid var(--border);
  border-radius:var(--r-pill);
  background:var(--card);
  color:var(--muted);
  font-size:9px;
  cursor:pointer;
  transition:color var(--t-fast),border-color var(--t-fast);
}
.tapp-wo-pick-x:hover{color:var(--bad);border-color:var(--bad)}

/* .tapp-toolbar-search yatay toolbar için yazılmış ve flex:1 1 220px taşıyor;
   sütun yönlü diyalog gövdesinde bu basis YÜKSEKLİK olarak uygulanıp kutuyu
   220px yapıyor, mutlak konumlu büyüteç de inputtan kopuyor. Diyalogda sıfırlanır. */
.tapp-dialog .tapp-toolbar-search{flex:0 0 auto}

/* Özet içindeki KDV satırı: anahtar + oran, etiketin yerinde durur. */
/* Anahtar açılınca oran kutusu yan tarafta belirir; satır sarmaz,
   yüksekliği de değişmez — altındaki toplamlar yerinden oynamaz. */
.tapp-wo-sum-row .tapp-wo-kdv{gap:8px;flex-wrap:nowrap}
.tapp-wo-sum-row{min-height:34px}
.tapp-wo-kdv-sel{height:26px;padding:0 6px;font-size:var(--t-12);width:auto;min-width:66px}

/* Liste sayfalama — seçili sayfa aksan renginde dolu. */
.tapp-pager-btn.is-active{
  background:var(--acc-solid,var(--brand-indigo));
  border-color:var(--acc-solid,var(--brand-indigo));
  color:var(--on-accent);
  font-weight:700;
}
.tapp-pager-btn.is-active:hover{background:var(--acc-solid,var(--brand-indigo))}
.tapp-wo-perpage{display:inline-flex;align-items:center;gap:8px;font-size:var(--t-12-5);color:var(--muted)}

/* Tıklama işareti: ok yeri hep ayrılır, yalnızca üstüne gelince görünür —
   çip genişliği değişmediği için şerit oynamaz. */
.tapp-wo-step-go{
  margin-left:clamp(0px, 0.8cqi, 7px);
  font-size:9px;
  color:var(--acc-text,var(--brand-indigo));
}
.tapp-wo-step.is-now .tapp-wo-step-go{display:none}
.tapp-wo-step.is-now{padding-right:11px}
/* Purely a hover affordance, not information - the first thing to give back its width once
   the strip (see .tapp-wo-steps-row's own container query) is this tight. */
@container (max-width: 480px) {
  .tapp-wo-step-go{display:none}
}

/* Kategori çipleri arasındaki ekleme çipi — kesik kenarlıkla ayrışır. */
.tapp-wo-chip-add{border-style:dashed;color:var(--acc-text,var(--brand-indigo));gap:7px}

.tapp-wo-addrow{display:flex;gap:8px;align-items:center}
.tapp-wo-addrow .tapp-input{flex:1}
.tapp-rowact.is-off{opacity:.45;pointer-events:none}

/* Sıralanabilir tablo başlığı: ok normalde soluk, sıralanan sütunda
   aksan renginde ve yön gösterir. */
.tapp-wo-th{
  display:inline-flex;
  align-items:center;
  gap:7px;
  background:none;
  border:none;
  padding:0;
  font:inherit;
  color:inherit;
  letter-spacing:inherit;
  text-transform:inherit;
  text-decoration:none;
  cursor:pointer;
  transition:color var(--t-fast);
}
.tapp-wo-th.is-right{justify-content:flex-end;width:100%}
.tapp-wo-th:hover{color:var(--head)}
.tapp-wo-th-i{font-size:9px;opacity:.45}
/* The sorted column is marked, not shouted. This was var(--head) - near-black against the
   muted grey every other heading wears - and the owner read it as a typo rather than a state
   ("bakiye yazısı diğer yazılardan farklı", 7 September 2026). var(--body) is one step darker
   than its neighbours, and the coloured arrow beside it already says which column and which
   way. */
.tapp-wo-th.is-active{color:var(--body)}
.tapp-wo-th.is-active .tapp-wo-th-i{opacity:1;color:var(--acc-text,var(--brand-indigo))}

/* Aracın sahibi (cari) — özet satırı; değiştir / düzenle yanında durur. */
.tapp-wo-owner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:12px 14px;border:1px solid var(--border);border-radius:var(--r-card);background:var(--thead)}
.tapp-wo-owner-main{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
.tapp-wo-owner-name{font-size:var(--t-13-5);font-weight:700;color:var(--head)}
.tapp-wo-owner-meta{font-size:var(--t-12);color:var(--muted)}
.tapp-wo-owner-act{display:flex;gap:8px}

/* A photograph and the one action it has - removing it. The strip looks exactly as the
   design draws it at rest; the button appears on hover and on keyboard focus, the same
   idiom `.tapp-rowact` uses for a table row. A mis-taken photograph has to be removable,
   and this is the least the screen can change to allow it. */
.tapp-wo-shot-wrap{position:relative;display:inline-flex;flex:0 0 auto}
.tapp-wo-shot-wrap .tapp-wo-pick-x{opacity:0;transition:opacity var(--t-fast),color var(--t-fast),border-color var(--t-fast)}
.tapp-wo-shot-wrap:hover .tapp-wo-pick-x,
.tapp-wo-shot-wrap:focus-within .tapp-wo-pick-x{opacity:1}
@media (max-width:767.98px){
  .tapp-wo-shot-wrap .tapp-wo-pick-x{opacity:1}
}

/* A list row that opens the job it names. The row already lights up on hover - that is
   `.tapp-table tbody tr:hover`, which every table here has - so all this adds is the
   pointer, and a number that reads as text rather than as a blue underlined link. The
   anchor stays an anchor underneath: it is what the keyboard tabs to and what works with
   no JavaScript at all. */
.tapp-wo-row{cursor:pointer}
.tapp-wo-rowlink{color:var(--head);font-weight:600;text-decoration:none}
.tapp-wo-rowlink:hover{color:var(--head);text-decoration:none}

/* ================================================================= yönetim (1a)
   The approved "Yönetim" hub (Claude Design "S - Yonetim", option 1a - the spec and the
   class file live at docs/design/import/). Four blocks the design adds and this stylesheet
   did not carry: a status band of figures, an alert list of what is waiting, the group cards
   the links sit in, and the destructive band at the foot of the page. Taken from
   `yeni-siniflar-yonetim.css` as written, and only the rules for classes not already here.

   What was deliberately NOT taken: the design's `--gutter-page` (defined only on the Design
   side - `.tapp-main`'s own padding is this shell's page gutter), its mock-up scaffolding
   (`.tapp-opt*`, `.tapp-yn-frame`, `.tapp-opt-size`), its option-C narrow menu (`.tapp-yn-c*`)
   and its `.tapp-yn-skel` loading block. That last one is not an omission of style but of
   behaviour: this page is rendered whole on the server, so there is no moment at which a
   skeleton would ever be on screen, and adding one would mean adding a fetch. Its `--yn-max`
   and `--yn-nav` measures go with the scaffolding they sized. */

/* Screen-specific measures, over the token set the shell already defines - the same shape
   the design writes them in, on the same `.cr` root. */
.cr {
    --yn-gap: 14px;
    --yn-gap-s: 10px;
    --yn-pad: 18px;
    --yn-pad-s: 12px;
    --yn-r-card: var(--r-card);
    --yn-r-ctl: var(--r-ctl);
    --yn-tile: 30px;
    --yn-t-lbl: 10.5px; /* deliberate: no shared step lands on 10.5px */
    --yn-t-note: var(--t-12);
    --yn-t-row: var(--t-13);
    --yn-t-name: var(--t-13-5);
    --yn-t-card: 17px; /* deliberate: no shared step lands on 17px */
    --yn-t-stat: 24px; /* deliberate: no shared step lands on 24px */
}

/* The query container every `@container` rule below measures. The design assumes one and
   names it but leaves the repo to provide it: the breakpoints are the content column's own
   width, so the same page reads correctly in a wide pane and beside an open drawer, which a
   viewport media query cannot tell apart. */
.tapp-yn-wrap {
    display: flex;
    flex-direction: column;
    gap: 22px;
    container-type: inline-size;
}

/* ---------------------------------------------------------------- durum bandı */

.tapp-yn-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: var(--yn-gap);
}

.tapp-yn-stat {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: var(--yn-pad);
    border: 1px solid var(--border);
    border-radius: var(--yn-r-card);
    background: var(--card);
    min-width: 0;
}

.tapp-yn-stat-k {
    font-size: var(--yn-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
}

.tapp-yn-stat-v {
    font-size: var(--yn-t-stat);
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.5px;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}

.tapp-yn-stat.is-bad .tapp-yn-stat-v {
    color: var(--bad);
}

.tapp-yn-stat.is-warn .tapp-yn-stat-v {
    color: var(--warn);
}

.tapp-yn-stat.is-ok .tapp-yn-stat-v {
    color: var(--ok);
}

.tapp-yn-stat-note {
    font-size: var(--yn-t-note);
    color: var(--muted);
    line-height: 1.4;
}

/* ---------------------------------------------------------------- uyarı satırı */

.tapp-yn-alerts {
    display: flex;
    flex-direction: column;
    gap: var(--yn-gap-s);
}

.tapp-yn-alert {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: var(--yn-pad-s) var(--yn-pad);
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: var(--yn-r-card);
    background: var(--card);
}

.tapp-yn-alert.is-bad {
    border-left-color: var(--bad);
}

.tapp-yn-alert.is-warn {
    border-left-color: var(--warn);
}

.tapp-yn-alert-ico {
    width: 18px;
    flex: 0 0 18px;
    text-align: center;
    font-size: var(--t-13);
    margin-top: 2px;
}

.tapp-yn-alert.is-bad .tapp-yn-alert-ico {
    color: var(--bad);
}

.tapp-yn-alert.is-warn .tapp-yn-alert-ico {
    color: var(--warn);
}

.tapp-yn-alert-body,
.tapp-tdo-h,
.tapp-rl-perm-body,
.tapp-ku-rol-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    flex: 1 1 auto;
}

.tapp-yn-alert-title {
    font-size: var(--yn-t-name);
    font-weight: 700;
    color: var(--head);
}

.tapp-yn-alert-text {
    font-size: var(--yn-t-note);
    color: var(--body);
    line-height: 1.45;
}

.tapp-yn-alert-act {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Nothing waiting: one quiet row where the list would have been. */
.tapp-yn-quiet {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--yn-pad-s) var(--yn-pad);
    border: 1px solid var(--border);
    border-radius: var(--yn-r-card);
    background: var(--card);
    font-size: var(--yn-t-row);
    color: var(--body);
}

.tapp-yn-quiet i {
    color: var(--ok);
}

.tapp-yn-quiet span {
    color: var(--muted);
}

/* ---------------------------------------------------------------- grup kartı */

/* Columns rather than a grid: the groups are wildly different heights (five links against
   one), and a grid row is as tall as its tallest cell, so a one-link card left a column-high
   hole beside it and the next card started a new row under the tallest one. Columns let a
   short card sit directly under the card above it, which is where the owner asked for
   "Kurulum" on 20 September 2026 - under "Modüller", the short one. `columns` keeps the same
   responsive behaviour the auto-fit track had: as many 300px columns as the container fits. */
.tapp-yn-groups {
    columns: 300px;
    column-gap: var(--yn-gap);
}

.tapp-yn-group {
    break-inside: avoid;
    margin-bottom: var(--yn-gap);
    border: 1px solid var(--border);
    border-radius: var(--yn-r-card);
    background: var(--card);
    overflow: hidden;
}

.tapp-yn-group-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--yn-pad-s) var(--yn-pad);
    border-bottom: 1px solid var(--border);
}

/* The tile's own background is written inline by the page and is always a `--brand-*`
   token - the glyph is drawn in var(--bg), which is what those five hues are paired with
   in both themes (see this file's own `--brand-*` remarks). */
.tapp-yn-tile {
    width: var(--yn-tile);
    height: var(--yn-tile);
    flex: 0 0 var(--yn-tile);
    border-radius: var(--r-xs);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bg);
    font-size: var(--t-12-5);
}

.tapp-yn-group-name {
    font-size: var(--yn-t-card);
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.2px;
}

.tapp-yn-link {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 11px var(--yn-pad);
    border: none;
    border-top: 1px solid var(--border);
    background: none;
    text-align: left;
    color: var(--body);
    cursor: pointer;
    text-decoration: none;
    transition: background var(--t-fast), color var(--t-fast);
}

.tapp-yn-group .tapp-yn-link:first-child {
    border-top: none;
}

/* The rule above is the design's own and never matches its own markup - the head is the
   group's first child, so the first link is second and keeps a top border directly under the
   head's bottom one, drawing the card's one divider twice. This is the same rule against the
   element that is actually first in the list, which is what it was written to say. */
.tapp-yn-group-head + .tapp-yn-link {
    border-top: none;
}

.tapp-yn-link:hover {
    background: var(--hover);
    color: var(--head);
}

.tapp-yn-link-text,
.tapp-tdo-b {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

.tapp-yn-link-name {
    font-size: var(--yn-t-name);
    font-weight: 600;
    color: var(--head);
}

.tapp-yn-link-note {
    font-size: var(--yn-t-note);
    color: var(--muted);
    line-height: 1.4;
}

.tapp-yn-link-end {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
}

.tapp-yn-chev {
    color: var(--muted);
    font-size: var(--t-11);
}

/* ---------------------------------------------------------------- yıkıcı bölge */

.tapp-yn-danger {
    display: flex;
    align-items: center;
    gap: var(--yn-gap);
    flex-wrap: wrap;
    padding-top: var(--yn-pad);
    border-top: 1px solid var(--border);
}

.tapp-yn-danger-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 220px;
    flex: 1 1 320px;
}

.tapp-yn-danger-name {
    font-size: var(--yn-t-name);
    font-weight: 700;
    color: var(--head);
}

.tapp-yn-danger-note {
    font-size: var(--yn-t-note);
    color: var(--muted);
    line-height: 1.45;
}

/* The design draws this as a `<button>`; the page keeps the anchor it already had, so that
   the same click still reaches the same page with JavaScript off (tenant-app.js's own
   dialog-trigger remarks). The three declarations after `height` are what an anchor needs
   and a button does not - everything else is the design's own rule. */
.tapp-yn-danger-btn {
    border: 1px solid var(--border);
    background: none;
    color: var(--muted);
    border-radius: var(--yn-r-ctl);
    padding: 0 14px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    font: inherit;
    font-size: var(--yn-t-row);
    font-weight: 600;
    cursor: pointer;
    transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}

.tapp-yn-danger-btn:hover {
    color: var(--bad);
    border-color: var(--bad);
    background: var(--badbg);
}

/* ---------------------------------------------------------------- dar ekran */

@container (max-width: 860px) {
    .tapp-yn-groups {
        columns: 1;
    }

    .tapp-yn-stats {
        grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    }
}

@container (max-width: 520px) {
    .tapp-yn-wrap {
        gap: 16px;
    }

    .tapp-yn-stats {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--yn-gap-s);
    }

    .tapp-yn-stat {
        padding: var(--yn-pad-s) var(--yn-pad);
    }

    .tapp-yn-stat-v {
        font-size: 20px;
    }

    .tapp-yn-alert {
        flex-wrap: wrap;
    }

    .tapp-yn-alert-act {
        width: 100%;
        padding-left: 30px;
    }

    .tapp-yn-alert-act .tapp-btn,
    .tapp-yn-alert-act form,
    .tapp-yn-alert-act form .tapp-btn {
        width: 100%;
        justify-content: center;
    }

    .tapp-yn-danger-btn {
        width: 100%;
        justify-content: center;
    }
}

/* ================================================================ iş emri fotoğrafları — öncesi / sonrası (ARCP-116) ====
   Design'dan taşındı; kaynak ve gerekçe docs/design/import/ altında. */

/* ARCP-116 - "öncesi / sonrası" on the work order gallery.
 *
 * Parked here rather than in tenant-app.css because that file is being worked on elsewhere
 * right now. Everything is prefixed arcp116- and nothing overrides an existing tapp- rule, so
 * folding it back into the panel stylesheet later is a move rather than a merge.
 *
 * The thumbnails themselves are still .tapp-wo-shot: the bands are a grouping, not a new
 * look, and a gallery that changed size the day it gained labels would read as a redesign.
 */

.arcp116-band {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Same weight and colour as .tapp-frame-cap, which captions the card above it - this is the
 * second level of the same heading, so it is a step quieter rather than a different voice. */
.arcp116-band-cap {
    font-size: var(--t-11-5);
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--muted);
}

.arcp116-shot {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    gap: 4px;
}

/* The relabel control sits under its own thumbnail and is only there for somebody who may
 * write. Kept to the thumbnail's width so a band of five stays a band of five. */
.arcp116-restage {
    display: flex;
    align-items: center;
    gap: 3px;
    max-width: 72px;
}

.arcp116-restage-pick {
    flex: 1 1 auto;
    min-width: 0;
    height: 20px;
    padding: 0 2px;
    font-size: 10.5px;
    line-height: 1;
    border: 1px solid var(--border);
    border-radius: var(--r-2xs);
    background: var(--card);
    color: inherit;
}

.arcp116-restage-go {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    font-size: 9.5px;
    border: 1px solid var(--border);
    border-radius: var(--r-2xs);
    background: var(--card);
    color: var(--muted);
    cursor: pointer;
}

.arcp116-restage-go:hover,
.arcp116-restage-go:focus-visible {
    color: var(--head);
}

/* No .tapp- equivalent exists, and the relabel select needs a label that is read but not
 * drawn - the thumbnail beside it is what says which photograph this is. */
.arcp116-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The to-do card's rows and close cross answer the pointer with the panel's hover fill. */
.tapp-tdo-x:hover,
.tapp-tdo-i:hover {
    background: var(--hover);
    color: var(--head);
}

/* ================================================================= dashboard kurulum kutusu (1h/1i/1j)
   The dashboard's "kurulumu tamamla" box (Claude Design "Y - Kurulum sihirbazi", ARCP-93,
   states 1h/1i/1j). Taken from `docs/design/import/yeni-siniflar-kurulum.css` verbatim -
   only the `.tapp-tdo*` rules the box itself draws.

   What was deliberately NOT taken: the `.tapp-kp*` panel mock-up those states are drawn
   inside of (`.tapp-kp`, `.tapp-kp-side`, `.tapp-kp-nav*`, `.tapp-kp-main`, `.tapp-kp-top*`,
   `.tapp-kp-body`, `.tapp-kp-trio`, `.tapp-kp-stat*`) - that is the design's own stand-in
   for the tenant shell this box is actually placed into (this shell's own `.tapp-band`,
   `.tapp-card`), not a class this box renders itself. Nor the wizard screens above it in
   the same file (`.tapp-ks-*`) - a different screen entirely, reached from this box's own
   rows rather than drawn by them. */

/* --kt-r-card, --kt-r-ctl, --kt-t-lbl, --kt-t-note and --kt-t-body exist today only on the
   bare onboarding pages (wwwroot/tenant-app/onboarding.css), at these same values. Scoped to
   `.tapp-tdo` alone rather than `.cr`, so this box reads exactly as designed without handing
   every other class in the panel a token it never asked for. Four of the five are written as
   the shared step they already landed on rather than as their own literal, the same way the
   `--yn-`, `--rp-` and `--rl-` blocks are written: the computed value is identical either way,
   but a later change to the shared radius or type step no longer leaves this one box behind
   at the old number. */
.tapp-tdo {
    --kt-r-card: var(--r-card);
    --kt-r-ctl: var(--r-ctl);
    --kt-t-lbl: 10.5px; /* deliberate: no shared step lands on 10.5px */
    --kt-t-note: var(--t-12);
    --kt-t-body: var(--t-13-5);
}

.tapp-tdo {
    border: 1px solid var(--border);
    border-radius: var(--kt-r-card);
    background: var(--card);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}

.tapp-tdo-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-width: 0;
}

/* The design leads at 1.55 (the panel shell at 1.5), and draws the dismiss button as a
   direct flex item of the head; here it sits inside the form that posts the dismissal, so the
   form steps out of the layout and the button lines up exactly where the design has it. */
.tapp-tdo {
    line-height: 1.55;
}

.tapp-tdo-head > form {
    display: contents;
}

.tapp-tdo-t { font-size: var(--t-15); font-weight: 700; color: var(--head); }
.tapp-tdo-n { font-size: var(--kt-t-note); color: var(--muted); line-height: 1.5; text-wrap: pretty; }

.tapp-tdo-x {
    flex: 0 0 auto;
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--kt-r-ctl);
    color: var(--muted);
    font: inherit;
    font-size: var(--kt-t-note);
    padding: 4px 9px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background var(--t-fast), color var(--t-fast);
}

.tapp-tdo-meter { display: flex; flex-direction: column; gap: 6px; }

.tapp-tdo-meter-k {
    font-size: var(--kt-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-tdo-bar {
    height: 3px;
    border-radius: var(--r-pill);
    background: var(--hover);
    border: 1px solid var(--border);
    overflow: hidden;
}

.tapp-tdo-bar-f { display: block; height: 100%; background: var(--ok); }

.tapp-tdo-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--kt-r-ctl);
    overflow: hidden;
}

.tapp-tdo-i {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    box-sizing: border-box;
    padding: 10px 11px;
    border: 0;
    border-bottom: 1px solid var(--border);
    background: none;
    font: inherit;
    text-align: left;
    color: var(--body);
    cursor: pointer;
    min-width: 0;
    transition: background var(--t-fast), color var(--t-fast);
}

.tapp-tdo-i:last-child { border-bottom: 0; }
.tapp-tdo-i.is-done { cursor: default; color: var(--muted); }
.tapp-tdo-i.is-done:hover { background: none; color: var(--muted); }

.tapp-tdo-mark {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border-radius: var(--r-pill);
    border: 1px solid var(--border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--t-10);
    color: var(--muted);
}

.tapp-tdo-i.is-done .tapp-tdo-mark { border-color: color-mix(in oklab, var(--ok) 45%, transparent); color: var(--ok); }
.tapp-tdo-b b { font-size: var(--kt-t-body); font-weight: 600; color: var(--head); }
.tapp-tdo-i.is-done .tapp-tdo-b b { color: var(--muted); font-weight: 500; text-decoration: line-through; }
.tapp-tdo-b span { font-size: var(--kt-t-note); color: var(--muted); line-height: 1.5; text-wrap: pretty; }
.tapp-tdo-go { flex: 0 0 auto; font-size: var(--t-11); color: var(--muted); }
.tapp-tdo-i.is-done .tapp-tdo-go { display: none; }

.tapp-tdo-trial {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 10px 11px;
    border: 1px solid var(--border);
    border-radius: var(--kt-r-ctl);
    background: var(--hover);
    font-size: var(--kt-t-note);
    color: var(--muted);
    line-height: 1.55;
    text-wrap: pretty;
    min-width: 0;
}

.tapp-tdo-trial i { margin-top: 2px; flex: 0 0 auto; }
.tapp-tdo-trial b { color: var(--head); font-weight: 600; }
.tapp-tdo-trial a { font-weight: 600; }
.tapp-tdo-foot { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.tapp-tdo-foot .tapp-tdo-hint { font-size: var(--kt-t-note); color: var(--muted); }

/* Tamamlanmış kutu: tek satır kapanış */
.tapp-tdo.is-complete .tapp-tdo-t { color: var(--head); }

.tapp-tdo-ok {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: var(--kt-t-body);
    color: var(--body);
    line-height: 1.55;
    text-wrap: pretty;
}

.tapp-tdo-ok i { color: var(--ok); margin-top: 3px; flex: 0 0 auto; }

/* ---------------------------------------------------------------- personel box (ARCP-179) */

/* Three totals, a share bar and one block per member of staff, each with a pay button. It is
   a card of its own rather than three more tiles in the row above because the rows below only
   mean anything read against those totals. */
.tapp-staff-figures {
    display: flex;
    gap: 10px;
    margin-bottom: 14px;
    text-align: center;
}

/* --input rather than --card: the card is already --card, and a panel painted on itself has
   no edge. This is the same recessed surface the rest of the panel uses for a figure that
   sits inside something else. */
.tapp-staff-figure {
    flex: 1;
    min-width: 0;
    background: var(--input);
    border-radius: var(--r-card);
    padding: 10px 6px;
}

.tapp-staff-figure span {
    display: block;
    font-size: var(--t-11);
    color: var(--muted);
}

.tapp-staff-figure strong {
    font-size: var(--t-15);
    font-weight: 600;
    color: var(--head);
    font-variant-numeric: tabular-nums;
}

.tapp-staff-figure strong.is-ok {
    color: var(--ok);
}

.tapp-staff-figure strong.is-warn {
    color: var(--warn);
}

/* Who earned what share of the period. One bar rather than a percentage per row: a share is a
   comparison, and comparing four numbers written in four places is work the reader should not
   have to do. */
.tapp-staff-share {
    display: flex;
    height: 10px;
    margin-bottom: 12px;
    border-radius: var(--r-2xs);
    overflow: hidden;
    background: var(--input);
}

.tapp-staff-share span {
    display: block;
}

.tapp-staff-rows {
    display: grid;
    gap: 8px;
}

/* Each person in their own block, with their own colour from the bar above down the left
   edge - the same colour twice is what ties a row to its segment without a legend. */
.tapp-staff-row {
    background: var(--input);
    border-left: 3px solid var(--tapp-staff-colour, var(--border));
    border-radius: var(--r-card);
    padding: 11px 12px;
}

/* The rows past the third, revealed by the box's own button (dashboard-staff.js). Hidden with
   a class rather than the hidden attribute so the button can toggle one thing. */
.tapp-staff-row.is-extra {
    display: none;
}

.tapp-staffbox.is-open .tapp-staff-row.is-extra {
    display: block;
}

.tapp-staff-row-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 8px;
    font-size: var(--t-13);
}

.tapp-staff-name {
    flex: 1;
    min-width: 0;
    color: var(--head);
}

.tapp-staff-earned {
    color: var(--muted);
}

/* The one control on this panel that is filled rather than outlined: every other button here
   navigates, and this one moves money. */
.tapp-staff-pay {
    flex: 0 0 auto;
    border: none;
    border-radius: var(--r-ctl);
    background: var(--ok);
    color: var(--bg);
    font: inherit;
    font-size: var(--t-12);
    font-weight: 600;
    padding: 6px 12px;
    cursor: pointer;
}

.tapp-staff-pay:hover {
    filter: brightness(1.08);
}

/* How much of what this person earned has been paid. The two ends are written underneath, so
   the bar is a shape over a sentence rather than the only place the figures live. */
.tapp-staff-bar {
    height: 6px;
    border-radius: var(--r-3);
    background: var(--border);
    margin-bottom: 6px;
    overflow: hidden;
}

.tapp-staff-bar span {
    display: block;
    height: 6px;
    border-radius: var(--r-3);
    background: var(--ok);
}

.tapp-staff-ends {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: var(--t-12);
    font-variant-numeric: tabular-nums;
}

.tapp-staff-ok {
    color: var(--ok);
}

.tapp-staff-left {
    color: var(--warn);
}

/* An empty bar and "0,00 ödendi" read as a rendering fault; the row says the fact instead. */
.tapp-staff-none {
    color: var(--muted);
}

/* Dashed, because it is not a destination - it opens the rest of this same list. */
.tapp-staff-more {
    width: 100%;
    margin-top: 8px;
    border: 1px dashed var(--border);
    border-radius: var(--r-card);
    background: transparent;
    color: var(--head);
    font: inherit;
    font-size: var(--t-13);
    padding: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    cursor: pointer;
}

.tapp-staff-more:hover {
    background: var(--hover);
}

.tapp-staffbox.is-open .tapp-staff-more i {
    transform: rotate(180deg);
}

.tapp-staff-dialog-who {
    margin: 0;
    font-size: var(--t-15);
    font-weight: 600;
    color: var(--head);
}

/* On a phone the three totals stay on one line - they are three short figures and stacking
   them would push the first row of people off the screen - but the type gives way instead. */
@media (max-width: 480px) {
    .tapp-staff-figure strong {
        font-size: var(--t-13);
    }

    .tapp-staff-figures {
        gap: 6px;
    }
}

/* Gelir/Gider kırılımı (ARCP-180). One stacked bar and a legend row per wedge, inside the
   money tile itself: the owner's own question - "kaporta şu, parça şu, ekspertiz şu" - is a
   reading of the figure above, not a second card somewhere else on the panel. */
.tapp-slices {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}

.tapp-slice-bar {
    display: flex;
    height: 8px;
    border-radius: var(--r-4);
    overflow: hidden;
    background: var(--border);
    margin-bottom: 4px;
}

.tapp-slice-bar span {
    display: block;
    height: 8px;

    /* A hairline between the wedges, so two adjacent colours of similar weight still read as
       two - the alternative is a rounded corner per wedge, which at 8px eats the sliver ones. */
    box-shadow: inset -1px 0 0 var(--card);
}

.tapp-slice-bar span:last-child {
    box-shadow: none;
}

.tapp-slice-row {
    display: grid;
    grid-template-columns: 8px 1fr auto auto;
    align-items: center;
    gap: 6px;
    font-size: var(--t-11-5);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-slice-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.tapp-slice-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tapp-slice-share {
    min-width: 34px;
    text-align: right;
}

.tapp-slice-amount {
    color: var(--head);
    font-weight: 600;
}

/* ── Roller ve izin penceresi ─────────────────────────────────────────────────
   Design turu 8 (`AC - Roller ve izinler`, `AC-Roller-ve-izinler-SPEC.md`). The
   design ships these as their own sheet, `yeni-siniflar-roller.css`; they live
   here instead because this panel loads one stylesheet and a second file would
   be a second bundle entry for two screens.

   Two deliberate departures from that sheet, both forced by this stack rather
   than by taste:

   - The design's query container is the mock's own frame (`.tapp-yn-frame`).
     There is no frame in the running panel, so the two roots below declare
     themselves the container - the same move `.tapp-wo-steps-row` already makes
     further up. Measuring the content column rather than the viewport is also
     the more correct question: the sidebar takes 236px of a 1024px screen, and
     it is the column that has to fit the dialog.
   - The design's "yükleniyor" frame is not ported. These are Razor Pages: the
     page arrives rendered, so a skeleton would be markup that can never appear.
     The other three states (normal, empty, error) are all here.

   The scale is scoped to the screens that measure in it rather than added to
   `:root`, because nothing outside them does.

   The two selector lists below are deliberately not the same list. Declaring the
   scale is cheap and inherits; declaring `container-type` is not - it creates a
   containment context, so it goes only on the roots that are actually the thing
   being measured. The topbar therefore gets the scale (the account menu that
   lives in it is built from `--rl-tap`, `--rl-r-card` and the `--rl-t-*` sizes)
   without becoming a query container and changing how the shell's own bar lays
   out.

   Every screen that uses this family has to be in the scale list. The user
   screen was not, once, and the result was not a subtle drift: `--rl-pad`,
   `--rl-gap`, `--rl-tap` and the type scale all resolved to nothing at the same
   time and the whole screen rendered as unstyled text. Each family's own sizes
   (`--ku-*`, `--pr-*`) stay declared beside the family that uses them. */

.tapp-rl-page,
.tapp-ay-section,
.tapp-rl-scrim,
.tapp-ku-page,
.tapp-ku-overlay,
.tapp-pr-page,
.tapp-ay-page,
.tapp-sf-shell {
    container-type: inline-size;
}

/* The page roots among them need a width of their own. An inline-size container has no
   content width - that is what the containment means - and each of these is centred with
   auto margins inside .tapp-main's column flexbox, and auto margins switch off the stretch
   that would otherwise size a flex item. Without this they resolved to 0px, and ayarlar,
   kullanıcılar and the rest were laid out one word per line down the middle of the screen
   (reported 18-19 September 2026). max-width on each root still sets the measure. */
.tapp-rl-page,
.tapp-ku-page,
.tapp-pr-page,
.tapp-ay-page {
    width: 100%;
}

.tapp-rl-page,
.tapp-ay-section,
.tapp-rl-scrim,
.tapp-ku-page,
.tapp-ku-overlay,
.tapp-pr-page,
.tapp-ay-page,
.tapp-sf-shell,
.tapp-ss,
.tapp-topbar {
    --rl-max: 1180px;
    --rl-grup: 232px;        /* the group list down the left of the dialog */
    --rl-dlg: 980px;
    --rl-dlg-body: 520px;    /* the dialog body's cap - the one scroll */
    --rl-gap: 10px;
    --rl-pad: 18px;
    --rl-pad-s: 12px;
    --rl-r-card: var(--r-card);
    --rl-r-ctl: var(--r-ctl);
    --rl-tile: 34px;
    --rl-tap: 44px;          /* the smallest touch target, at every size */
    --rl-row: 56px;
    --rl-sw-w: 44px;
    --rl-sw-h: 26px;
    --rl-sw-in: 3px;         /* the knob's inset; its size derives from these three */
    --rl-ind: 44px;
    --rl-t-lbl: 10.5px; /* deliberate: no shared step lands on 10.5px */
    --rl-t-note: var(--t-12);
    --rl-t-row: var(--t-13);
    --rl-t-name: var(--t-13-5);
    --rl-t-card: 17px; /* deliberate: no shared step lands on 17px */
}

.tapp-rl-page {
    max-width: var(--rl-max);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.tapp-rl-count,
.tapp-ku-count {
    font-size: var(--rl-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* ── One role ─────────────────────────────────────────────────────────────── */

.tapp-rl-list,
.tapp-ku-list {
    display: flex;
    flex-direction: column;
    gap: var(--rl-gap);
}

.tapp-rl-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: var(--rl-pad-s) var(--rl-pad);
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
    transition: background var(--t-fast), border-color var(--t-fast);
}

/* A row lifts to the hover surface and says nothing else. The four list rows across roles and
   users each declared this one line for themselves; merged, because "a row under the pointer
   takes --hover" is a single decision. What differs between the four - their padding, border
   and avatar column - stays with each row. */
.tapp-rl-row:hover,
.tapp-rl-perm-row:hover,
.tapp-ku-row:hover,
.tapp-ku-rolrow:hover {
    background: var(--hover);
}

/* One neutral tile, no per-role colour: a role has no colour field and brand
   hues belong to modules. What tells two roles apart is the glyph. */
.tapp-rl-tile {
    width: var(--rl-tile);
    height: var(--rl-tile);
    flex: 0 0 var(--rl-tile);
    border-radius: var(--r-xs);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    background: var(--hover);
    color: var(--muted);
    font-size: var(--t-13);
}

.tapp-rl-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    flex: 1 1 260px;
}

.tapp-rl-name,
.tapp-ku-name {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: var(--rl-t-card);
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.2px;
}

.tapp-rl-sum,
.tapp-rl-pane-note,
.tapp-ay-limit-sub {
    font-size: var(--rl-t-note);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-rl-perm {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: flex-end;
    text-align: right;
}

.tapp-rl-perm-v {
    font-size: var(--rl-t-name);
    font-weight: 700;
    color: var(--head);
    font-variant-numeric: tabular-nums;
}

.tapp-rl-perm-k,
.tapp-rl-meter-k,
.tapp-ku-meter-k {
    font-size: var(--rl-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
}

.tapp-rl-acts,
.tapp-ku-acts {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    margin-left: auto;
}

/* Every control in a row is the same height at every width, so the destructive
   icon button never ends up the tallest thing on the line. */
/* One touch-target floor for every control the five screen families put in a bar, in a row's
   action cluster or in a form. It was written out seven times over, once per screen, the same
   single declaration each time - so it is collected here instead: one decision, not seven that
   happen to agree. Only the min-height moved; each family's own sizing, spacing and colour
   stays in its own section below. */
.tapp-rl-acts .tapp-btn,
.tapp-rl-bulk .tapp-btn,
.tapp-rl-foot-end .tapp-btn,
.tapp-ku-bar .tapp-chip,
.tapp-ku-bar .tapp-btn,
.tapp-ku-acts .tapp-btn,
.tapp-ku-form .tapp-input,
.tapp-pr-form .tapp-input,
.tapp-ay-logo-acts .tapp-btn,
.tapp-sf-form .tapp-input {
    min-height: var(--rl-tap);
}

.tapp-rl-icon {
    width: var(--rl-tap);
    min-height: var(--rl-tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: none;
    color: var(--muted);
    font-size: var(--t-13);
    cursor: pointer;
    transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}

.tapp-rl-icon:hover,
.tapp-rl-search-clear:hover {
    color: var(--head);
    background: var(--hover);
}

.tapp-rl-icon.is-danger:hover {
    color: var(--bad);
    border-color: var(--bad);
    background: var(--badbg);
}

.tapp-rl-icon.is-off, .tapp-rl-row .tapp-btn.is-off,
.tapp-rl-perm-row.is-locked,
.tapp-ku-mitem.is-off {
    opacity: .45;
    cursor: not-allowed;
}

.tapp-rl-icon.is-off:hover {
    color: var(--muted);
    border-color: var(--border);
    background: none;
}

/* A disabled control is never left without the reason it is disabled. */
.tapp-rl-note {
    flex: 1 1 100%;
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
    padding-left: calc(var(--rl-tile) + 14px);
    display: flex;
    align-items: center;
    gap: 7px;
}

.tapp-rl-note i {
    color: var(--muted);
    font-size: var(--t-11);
}

.tapp-rl-rule {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: var(--rl-pad-s) var(--rl-pad);
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
    font-size: var(--rl-t-row);
    color: var(--body);
    line-height: 1.5;
}

.tapp-rl-rule i {
    color: var(--muted);
    font-size: var(--t-13);
    margin-top: 2px;
}

/* A word set in bold inside explanatory prose, on either screen that writes any. */
.tapp-rl-rule b,
.tapp-sf-text b {
    color: var(--head);
    font-weight: 700;
}

/* ── The permission dialog ────────────────────────────────────────────────── */

.tapp-rl-scrim {
    background: color-mix(in srgb, var(--scrim-tint) 66%, transparent);
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    padding: 24px;
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

/* Where the scrim is the whole screen - the permission window - it is simply the
   page and is never hidden. Where it covers a page instead (the account screen's
   unsaved-changes confirmation) the markup closes it with `hidden`, and
   `display: flex` above outranks the user-agent sheet's rule for the attribute. */
.tapp-rl-scrim[hidden] {
    display: none;
}

.tapp-rl-dlg {
    width: 100%;
    max-width: var(--rl-dlg);
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
    box-shadow: var(--shadow-dlg);
    overflow: hidden;
}

.tapp-rl-dlg-head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    flex-wrap: wrap;
    padding: 14px var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-rl-dlg-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1 1 320px;
}

.tapp-rl-dlg-title,
.tapp-rl-confirm-title,
.tapp-pr-title {
    font-size: var(--rl-t-card);
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.2px;
}

.tapp-rl-dlg-sub {
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.5;
    max-width: 620px;
    text-wrap: pretty;
}

.tapp-rl-meter {
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: flex-end;
    flex: 0 0 auto;
}

.tapp-rl-meter-v,
.tapp-ku-meter-v {
    font-size: var(--t-15);
    font-weight: 700;
    color: var(--head);
    font-variant-numeric: tabular-nums;
}

.tapp-rl-search {
    padding: var(--rl-pad-s) var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-rl-search-box {
    position: relative;
    display: block;
    margin: 0;
}

.tapp-rl-search-box .tapp-input {
    padding-left: 34px;
    height: var(--rl-tap);
}

.tapp-rl-search-ico {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--muted);
    font-size: var(--t-12);
    pointer-events: none;
}

.tapp-rl-search-clear {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 32px;
    height: 32px;
    border: none;
    background: none;
    border-radius: var(--rl-r-ctl);
    color: var(--muted);
    font-size: var(--t-12);
    cursor: pointer;
    transition: color var(--t-fast), background var(--t-fast);
}

.tapp-rl-body {
    display: grid;
    grid-template-columns: var(--rl-grup) minmax(0, 1fr);
    min-width: 0;
}

.tapp-rl-groups {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--rl-gap);
    border-right: 1px solid var(--border);
    max-height: var(--rl-dlg-body);
    overflow: auto;
}

.tapp-rl-gitem {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
    padding: 8px 10px;
    border: none;
    border-radius: var(--rl-r-ctl);
    background: none;
    color: var(--body);
    font: inherit;
    font-size: var(--rl-t-name);
    text-align: left;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast);
}

/* Every pressable list entry in the five screen families - a role group, a row menu item, the
   password reveal, the account button, a settings jump link, a module link, a control on the
   password screen - lights up the same way: the hover surface under it, the heading ink on it.
   Seven rules carried those two declarations apart from each other; this is the one place they
   are written now. Settings' module link folds its :focus-visible in here, which is what that
   rule already did.

   What deliberately did not move: .tapp-ku-mitem.is-danger:hover and .tapp-ku-mitem.is-off:hover
   (a destructive or a switched-off item answers the pointer differently, and both out-specify
   this rule), .tapp-ay-nitem.is-active below, and every family's own border and transition. */
.tapp-rl-gitem:hover,
.tapp-ku-mitem:hover,
.tapp-ku-pw-btn:hover,
.tapp-pr-ubtn:hover,
.tapp-ay-nitem:hover,
.tapp-ay-mod-item:hover,
.tapp-ay-mod-item:focus-visible,
.tapp-sf-ctl:hover {
    background: var(--hover);
    color: var(--head);
}

/* The glyph in front of such an entry comes up with it, from --muted to the heading ink. Four
   identical rules, one per screen that draws an icon there. Roles' group item has no glyph,
   which is why no .tapp-rl-* selector is in this list. */
.tapp-ku-mitem:hover i,
.tapp-ay-nitem:hover i,
.tapp-ay-mod-item:hover i,
.tapp-sf-ctl:hover i {
    color: var(--head);
}

/* The entry you are on, in either jump list (roles' group column, settings' section nav): it
   keeps the hover surface and goes half a weight heavier rather than taking a fill of its own.
   One decision, so one rule; each list's own :focus-visible and its narrow-container border
   stay where they are. */
.tapp-rl-gitem.is-active,
.tapp-ay-nitem.is-active {
    background: var(--hover);
    color: var(--head);
    font-weight: 600;
}

.tapp-rl-gcount {
    margin-left: auto;
    font-size: var(--rl-t-note);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    flex: 0 0 auto;
}

.tapp-rl-gitem.is-some .tapp-rl-gcount {
    color: var(--acc-text);
}

.tapp-rl-pane {
    display: flex;
    flex-direction: column;
    min-width: 0;
    max-height: var(--rl-dlg-body);
    overflow: auto;
}

.tapp-rl-pane-head {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: var(--rl-pad-s) var(--rl-pad);
    border-bottom: 1px solid var(--border);
    background: var(--card);
}

.tapp-rl-pane-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 200px;
}

.tapp-rl-pane-title {
    font-size: var(--t-15);
    font-weight: 700;
    color: var(--head);
}

.tapp-rl-bulk,
.tapp-rl-foot-end {
    display: flex;
    gap: 8px;
    margin-left: auto;
    flex: 0 0 auto;
}

.tapp-rl-sub {
    padding: 16px var(--rl-pad) 6px;
    font-size: var(--rl-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
}

.tapp-rl-perms {
    display: flex;
    flex-direction: column;
}

.tapp-rl-perm-row {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    /* Stated rather than inherited from Bootstrap's reset: `width: 100%` plus the row's own
       padding is 36px of horizontal overflow without it, and the dialog is the one place on
       this screen that must never scroll sideways. */
    box-sizing: border-box;
    min-height: var(--rl-row);
    padding: var(--rl-pad-s) var(--rl-pad);
    border-top: 1px solid var(--border);
    border-left: none;
    border-right: none;
    border-bottom: none;
    background: none;
    width: 100%;
    text-align: left;
    font: inherit;
    cursor: pointer;
    transition: background var(--t-fast);
}

/* The switch is a real checkbox, hidden but not removed: the row has to work, and to say
   whether it is on, with no script running at all. `role="switch"` is what turns the reading
   from "onay kutusu, işaretli" into "anahtar, açık"; the drawn `.tapp-rl-sw` beside it is
   decoration and is hidden from the reading entirely. */
.tapp-rl-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

.tapp-rl-perm-row.is-child {
    padding-left: calc(var(--rl-pad) + var(--rl-ind));
}

.tapp-rl-perm-row.is-locked:hover {
    background: none;
}

.tapp-rl-perm-name,
.tapp-ku-rol-name {
    font-size: var(--rl-t-name);
    font-weight: 600;
    color: var(--head);
}

.tapp-rl-perm-desc,
.tapp-ku-rol-desc,
.tapp-pr-2fa-note,
.tapp-ay-logo-hint {
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
    text-wrap: pretty;
}

/* The switch does not slide: the knob's position changes, it does not travel.
   Its size and its open position both derive from the three switch tokens, so
   changing one of them cannot leave the knob sitting off the rail. */
.tapp-rl-sw {
    flex: 0 0 var(--rl-sw-w);
    width: var(--rl-sw-w);
    height: var(--rl-sw-h);
    margin-top: 2px;
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--input);
    transition: background var(--t-fast), border-color var(--t-fast);
}

.tapp-rl-sw::after {
    content: "";
    position: absolute;
    top: var(--rl-sw-in);
    left: var(--rl-sw-in);
    width: calc(var(--rl-sw-h) - 2 * var(--rl-sw-in) - 2px);
    height: calc(var(--rl-sw-h) - 2 * var(--rl-sw-in) - 2px);
    border-radius: var(--r-pill);
    background: var(--muted);
}

.tapp-rl-sw.is-on {
    background: var(--acc-soft);
    border-color: var(--acc-solid);
}

.tapp-rl-sw.is-on::after {
    left: calc(var(--rl-sw-w) - var(--rl-sw-h) + var(--rl-sw-in));
    background: var(--acc-solid);
}

.tapp-rl-foot {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: var(--rl-pad-s) var(--rl-pad);
    border-top: 1px solid var(--border);
}

.tapp-rl-dirty {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--rl-t-row);
    color: var(--warn);
    font-variant-numeric: tabular-nums;
}

.tapp-rl-dirty.is-clean {
    color: var(--muted);
}

.tapp-rl-confirm {
    width: 100%;
    max-width: 460px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
    box-shadow: var(--shadow-dlg);
    overflow: hidden;
}

.tapp-rl-confirm-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: var(--rl-pad);
}

.tapp-rl-confirm-text {
    font-size: var(--rl-t-row);
    color: var(--body);
    line-height: 1.5;
    text-wrap: pretty;
}

.tapp-rl-confirm-foot {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    flex-wrap: wrap;
    padding: var(--rl-pad-s) var(--rl-pad);
    border-top: 1px solid var(--border);
}

.tapp-rl-alert-pad {
    padding: var(--rl-pad);
}

/* Focus: the border takes the accent, with no ring and no glow. `outline: none`
   is only ever written together with the rule that replaces it. */
/* Focus is the accent taken by the border, no outline and no glow - turu 8's one rule. Roles'
   three controls and the profile account button said it identically. Users' and settings' own
   controls are not in this list: theirs add an inset box-shadow because they have no border of
   their own to colour, and that rule stays beside them. */
.tapp-rl-icon:focus-visible,
.tapp-rl-gitem:focus-visible,
.tapp-rl-search-clear:focus-visible,
.tapp-pr-ubtn:focus-visible {
    outline: none;
    border-color: var(--acc-solid);
    background: var(--hover);
}

.tapp-rl-gitem:focus-visible {
    box-shadow: inset 0 0 0 1px var(--acc-solid);
}

/* The row's focus is the hidden input's focus - it is the thing that actually takes the
   keyboard - so the ring is drawn on the row around it. */
.tapp-rl-perm-row:has(.tapp-rl-input:focus-visible) {
    background: var(--hover);
    box-shadow: inset 0 0 0 1px var(--acc-solid);
}

.tapp-rl-perm-row:has(.tapp-rl-input:focus-visible) .tapp-rl-sw {
    border-color: var(--acc-solid);
}

.tapp-rl-search-box .tapp-input:focus-visible,
.tapp-ku-bar-search .tapp-input:focus-visible {
    outline: none;
    border-color: var(--acc-solid);
}

@container (max-width: 860px) {
    .tapp-rl-body {
        grid-template-columns: minmax(0, 1fr);
    }

    .tapp-rl-groups {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 6px;
        border-right: none;
        border-bottom: 1px solid var(--border);
        max-height: none;
        overflow: visible;
    }

    .tapp-rl-gitem {
        border: 1px solid var(--border);
        border-radius: var(--r-pill);
        min-height: var(--rl-tap);
        padding: 6px 12px;
        font-size: var(--rl-t-note);
    }

    .tapp-rl-gitem.is-active {
        border-color: var(--acc-solid);
    }

    .tapp-rl-gcount {
        margin-left: 0;
    }

    .tapp-rl-pane {
        max-height: none;
        overflow: visible;
    }
}

@container (max-width: 520px) {
    .tapp-rl-perm {
        align-items: flex-start;
        text-align: left;
    }

    /* Below 520px every action cluster in these two screens gives up its auto margin and
       takes the whole row, and the buttons in it share that row equally. Five rules said
       this in three places (roles' bar, its dialog foot, its confirm foot, and the users
       row's own cluster); it is one decision about a narrow column, so it is one pair of
       rules now. Settings' limits foot is not in the second list: it adds a min-height of
       its own, so it stays its own rule further down. */
    .tapp-rl-acts,
    .tapp-rl-foot-end,
    .tapp-ku-acts {
        width: 100%;
        margin-left: 0;
    }

    .tapp-rl-acts .tapp-btn,
    .tapp-rl-foot-end .tapp-btn,
    .tapp-rl-confirm-foot .tapp-btn,
    .tapp-ku-acts .tapp-btn {
        flex: 1 1 auto;
        justify-content: center;
    }

    .tapp-rl-note {
        padding-left: 0;
    }

    /* Full screen on a phone: no scrim, no border, no radius. */
    .tapp-rl-dlg {
        max-width: none;
        border: none;
        border-radius: 0;
        box-shadow: none;
        min-height: 660px;
    }

    .tapp-rl-perm-row {
        min-height: 60px;
    }

    .tapp-rl-perm-row.is-child {
        padding-left: calc(var(--rl-pad) + 24px);
    }
}

/* ── Kullanıcılar ve pencereleri ──────────────────────────────────────────────
   Design turu 9 (`AD - Kullanicilar`, `AD-Kullanicilar-SPEC.md`). Sits on top of
   the `tapp-rl-*` family above rather than beside it: the dialog shell, the
   switch, the row note, the confirmation panel and the focus rules all come
   from there. Only the user row, the action menu, the form dialog and the
   two-counter header are new. No new colour token.

   Three deliberate departures from the design's own sheet:

   - Its `.tapp-ku-rolrow .tapp-check` block is not ported. `.tapp-check` above
     already is that control - `appearance: none`, 16x16, accent on `:checked` -
     and re-declaring it here would give the same checkbox a different corner
     and a different tick inside this one row. What is kept is the one rule the
     row actually needs: the box must not eat the click.
   - The query container is declared on the two roots below, the same move the
     roles screen makes, because the mock's own frame does not exist here.
   - No "yükleniyor" frame: these are Razor Pages, so a skeleton is markup that
     can never appear. Normal, empty and error are all here. */

/* Only the sizes this screen adds; the shared `--rl-*` scale and the query
   container come from the block those two roots are named in, further up. */
.tapp-ku-page,
.tapp-ku-overlay {
    --ku-max: 1180px;
    --ku-av: 38px;           /* the initials disc on a row */
    --ku-menu: 252px;
    --ku-dlg: 620px;         /* the form dialog: new user, roles, password */
}

.tapp-ku-page {
    max-width: var(--ku-max);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* The one positioned ancestor the confirmation's scrim measures itself against,
   so a confirmation covers the list it is about and not the whole shell. */
.tapp-ku-stage {
    position: relative;
}

.tapp-ku-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.tapp-ku-bar-search {
    flex: 1 1 280px;
    min-width: 0;
}

.tapp-ku-bar-search .tapp-input {
    height: var(--rl-tap);
}

/* ── One person ───────────────────────────────────────────────────────────── */

.tapp-ku-row {
    /* The row is what the menu hangs off. The menu is a direct child of the row
       rather than of the button's wrapper (so it can run full width under the
       row on a phone), which means the row - not the wrapper, and not the stage
       further out - has to be the positioned ancestor. Without this every row's
       menu opens in the same place: wherever `.tapp-ku-stage` happens to end. */
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: var(--rl-pad-s) var(--rl-pad);
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
    transition: background var(--t-fast), border-color var(--t-fast);
}

/* Somebody whose access is off is not drawn as though they were deleted: the
   row stays readable and the badge says it. The name drops one tone, no more. */
.tapp-ku-row.is-suspended .tapp-ku-name {
    color: var(--body);
}

.tapp-ku-av {
    width: var(--ku-av);
    height: var(--ku-av);
    flex: 0 0 var(--ku-av);
    font-size: var(--t-12-5);
    letter-spacing: .3px;
}

.tapp-ku-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1 1 300px;
}

.tapp-ku-sum {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    font-size: var(--rl-t-note);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-ku-dot {
    color: var(--muted);
    opacity: .55;
}

/* A role on a row is a label, not a control - its own class rather than
   `tapp-chip`, because a filter chip is pressed and this one is not. */
.tapp-ku-role {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 0 9px;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--input);
    color: var(--body);
    font-size: var(--t-11-5);
    font-weight: 600;
    white-space: nowrap;
}

.tapp-ku-row .tapp-rl-note {
    padding-left: calc(var(--ku-av) + 14px);
}

/* ── The action menu ──────────────────────────────────────────────────────── */
/* No shadow: in this system only a dialog casts one. A filled surface and a
   hairline are what separate the menu from the row under it. Shared with
   .tapp-pr-umenu below - only the stacking order and the width (each set by
   its own --ku-menu / --pr-umenu) tell the two menus apart. */

.tapp-ku-menu,
.tapp-pr-umenu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
}

.tapp-ku-menu {
    z-index: 6;
    width: var(--ku-menu);
}

/* `hidden` is how the markup closes a menu, and the browser implements it as a
   `display: none` in the user-agent sheet - which the `display: flex` above
   outranks. Restated here so the attribute keeps meaning what it says; a menu
   that ignores it is painted open on a screen nobody has clicked. */
.tapp-ku-menu[hidden],
.tapp-pr-umenu[hidden] {
    display: none;
}

.tapp-ku-mitem {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--rl-tap);
    padding: 8px 10px;
    border: none;
    border-radius: var(--rl-r-ctl);
    background: none;
    color: var(--body);
    font: inherit;
    font-size: var(--rl-t-row);
    text-align: left;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast);
}

.tapp-ku-mitem i,
.tapp-ay-nitem i,
.tapp-ay-mod-item i {
    width: 14px;
    text-align: center;
    font-size: var(--t-12);
    color: var(--muted);
}

.tapp-ku-mitem.is-danger:hover,
.tapp-ku-mitem.is-danger:hover i {
    background: var(--badbg);
    color: var(--bad);
}

.tapp-ku-mitem.is-off:hover {
    background: none;
    color: var(--body);
}

.tapp-ku-mitem.is-off:hover i {
    color: var(--muted);
}

.tapp-ku-msep {
    display: block;
    height: 1px;
    background: var(--border);
    margin: 4px 2px;
}

.tapp-ku-mnote {
    display: block;
    padding: 4px 10px 6px;
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
    text-wrap: pretty;
}

/* ── The form dialog: new user, roles, password ───────────────────────────── */

.tapp-ku-dlg {
    width: 100%;
    max-width: var(--ku-dlg);
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
    box-shadow: var(--shadow-dlg);
    overflow: hidden;
}

.tapp-ku-body {
    max-height: var(--rl-dlg-body);
    overflow: auto;
}

.tapp-ku-form,
.tapp-pr-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    padding: var(--rl-pad);
}

/* A field wide enough to need both columns - the two-column form above is the same rule for
   users and for profile, and so is this. */
.tapp-ku-form .is-full,
.tapp-pr-form .is-full {
    grid-column: 1 / -1;
}

.tapp-ku-sub {
    padding: 2px var(--rl-pad) 0;
    font-size: var(--rl-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
}

/* The operator types the password. Nothing generates, defaults or suggests one;
   the only thing offered is being able to see what was typed. */
.tapp-ku-pw {
    display: flex;
    gap: 8px;
}

.tapp-ku-pw .tapp-input {
    flex: 1 1 auto;
    min-width: 0;
}

.tapp-ku-pw-btn {
    flex: 0 0 auto;
    min-height: var(--rl-tap);
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: none;
    color: var(--body);
    font: inherit;
    font-size: var(--rl-t-row);
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}

.tapp-ku-rules {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-top: 2px;
}

.tapp-ku-rules span {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: var(--rl-t-note);
    color: var(--muted);
}

.tapp-ku-rules i {
    font-size: var(--t-10);
    width: 11px;
    text-align: center;
    color: var(--muted);
}

.tapp-ku-rules span.is-ok {
    color: var(--body);
}

.tapp-ku-rules span.is-ok i {
    color: var(--ok);
}

/* Picking roles: a 56px row the whole width of which is the target. */
.tapp-ku-rollist {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--border);
}

.tapp-ku-rolrow {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-height: var(--rl-row);
    padding: var(--rl-pad-s) var(--rl-pad);
    border: none;
    border-bottom: 1px solid var(--border);
    background: none;
    box-sizing: border-box;
    width: 100%;
    text-align: left;
    font: inherit;
    cursor: pointer;
    transition: background var(--t-fast);
}

/* The box is drawn by `.tapp-check` above; all this row adds is that clicking
   anywhere on it counts, including on the box itself. */
.tapp-ku-rolrow .tapp-check {
    pointer-events: none;
    margin-top: 3px;
}

/* ── Two counters: from a role, and this person's own ─────────────────────── */

.tapp-ku-meters {
    display: flex;
    gap: 20px;
    flex: 0 0 auto;
}

.tapp-ku-meter {
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: flex-end;
}

.tapp-ku-meter.is-personal .tapp-ku-meter-v {
    color: var(--acc-text);
}

.tapp-ku-lock {
    align-self: center;
    margin-left: auto;
    flex: 0 0 auto;
    color: var(--muted);
    font-size: var(--t-11);
}

.tapp-ku-tag {
    margin-left: 8px;
}

/* What a confirmation counts off - what will happen, in three lines. */
.tapp-ku-what {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 4px;
}

.tapp-ku-what span {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
}

.tapp-ku-what i {
    font-size: var(--t-10);
    margin-top: 4px;
    color: var(--muted);
}

.tapp-ku-overlay {
    position: absolute;
    inset: 0;
    z-index: 20;
    background: color-mix(in srgb, var(--scrim-tint) 66%, transparent);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 24px;
}

.tapp-ku-mitem:focus-visible, .tapp-ku-rolrow:focus-visible, .tapp-ku-pw-btn:focus-visible,
.tapp-ay-nitem:focus-visible {
    outline: none;
    background: var(--hover);
    box-shadow: inset 0 0 0 1px var(--acc-solid);
}

@container (max-width: 860px) {
    .tapp-ku-form {
        grid-template-columns: minmax(0, 1fr);
    }

    .tapp-ku-bar-search {
        flex: 1 1 100%;
    }
}

@container (max-width: 520px) {
    /* The menu runs full width under the row on a phone rather than floating
       over it, which is why the markup puts it outside `.tapp-ku-acts`. */
    .tapp-ku-menu {
        position: static;
        width: 100%;
        margin-top: 0;
    }

    .tapp-ku-row > .tapp-ku-menu {
        flex: 1 1 100%;
    }

    .tapp-ku-row .tapp-rl-note {
        padding-left: 0;
    }

    .tapp-ku-dlg {
        max-width: none;
        border: none;
        border-radius: 0;
        box-shadow: none;
        min-height: 620px;
    }

    .tapp-ku-rolrow {
        min-height: 60px;
    }

    .tapp-ku-meters {
        gap: 14px;
    }

    .tapp-ku-meter {
        align-items: flex-start;
    }
}

/* ── Hesabım: profile, password and the two-factor state ───────────────────── */
/* Design turu 10 ("AE - Profil ve sifre", AE-Profil-SPEC.md). Sits on top of the
   turu 8 `tapp-rl-*` and turu 9 `tapp-ku-*` families rather than beside them:
   the card foot (`.tapp-rl-foot`), the dirty counter (`.tapp-rl-dirty`), the
   rule card (`.tapp-rl-rule`), the confirmation (`.tapp-rl-confirm`), the
   password field (`.tapp-ku-pw`) and its rule list (`.tapp-ku-rules`), and the
   menu item (`.tapp-ku-mitem`) all come from there. No new colour token.

   Three departures from the design's own sheet, each for a reason this repo
   already had:

   - Its `--pr-*` sizes were declared on `.cr`. Here the page's two go on the
     page root, beside the family that uses them, and the menu's two go on the
     topbar - the menu lives in the shell, so a page-scoped token would not
     reach it.
   - The design measured the phone menu against `var(--topbar-height)`, which
     did not exist; the bar's own height is now that token (see `.tapp-topbar`).
   - The mock's `.tapp-yn-frame` block is not ported. It exists so the design's
     390 frame can fake a viewport, and the file says so itself. */

.tapp-pr-page {
    max-width: var(--pr-max);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 16px;

    --pr-max: 760px;    /* narrower than the list screens: the longest line here is a field */
    --pr-av: 56px;      /* the initials disc in the identity block */
}

/* ── One section, which saves itself ──────────────────────────────────────── */

.tapp-pr-card {
    display: flex;
    flex-direction: column;
}

.tapp-pr-head {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 14px var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-sf-sub {
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.5;
    text-wrap: pretty;
}

/* ── Who you are ──────────────────────────────────────────────────────────── */
/* No photograph: this system has no photographs and no illustrations, so the
   initials are the whole of it. */

.tapp-pr-ident {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-pr-av {
    width: var(--pr-av);
    height: var(--pr-av);
    flex: 0 0 var(--pr-av);
    font-size: 17px;
    letter-spacing: .3px;
}

.tapp-pr-ident-text {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
    flex: 1 1 240px;
}

.tapp-pr-ident-name {
    font-size: 19px;
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.3px;
}

.tapp-pr-ident-roles {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
}

/* ── The form ─────────────────────────────────────────────────────────────── */

/* A value that cannot be changed, which is not the same as a disabled one: it
   takes the surface one layer down and keeps its border and its full contrast.
   Dimming it would say "not now"; this says "not by you". The reason is in the
   hint under it, never in the styling alone. */
.tapp-pr-ro {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--rl-tap);
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: var(--bg);
    color: var(--body);
    font-size: var(--rl-t-row);
}

.tapp-pr-ro i {
    margin-left: auto;
    flex: 0 0 auto;
    color: var(--muted);
    font-size: var(--t-11);
}

/* The error goes under the field it is about, bound to it by aria-describedby. */
/* The sentence under a field, explaining it before it is filled in rather than after it is
   rejected. Turu 10 wrote the markup for it and no rule: it rendered at body size until the
   settings screen became its second caller. */
.tapp-field-hint {
    display: block;
    margin-top: 2px;
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
    text-wrap: pretty;
}

/* .field-validation-error is the class the validation tag helper writes itself. A
   <span asp-validation-for> must carry no class of its own - the helper overwrites the
   attribute with the literal text "ClassAttributeHtmlContent" at render time, destroying both
   the class written there and the one it was about to add - so the message is styled from the
   helper's own class instead, beside the hand-written one. */
.tapp-pr-err,
.field-validation-error {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    margin-top: 2px;
    font-size: var(--rl-t-note);
    color: var(--bad);
    line-height: 1.45;
    text-wrap: pretty;
}

.tapp-pr-err i,
.field-validation-error i {
    font-size: var(--t-11);
    margin-top: 2px;
}

.tapp-pr-field.is-bad .tapp-input {
    border-color: var(--bad);
}

.tapp-pr-alert-pad {
    padding: var(--rl-pad) var(--rl-pad) 0;
}

.tapp-pr-rule-pad {
    padding: 0 var(--rl-pad) var(--rl-pad);
}

/* ── Two-factor: a state, not a control ───────────────────────────────────── */
/* No button anywhere in this card. A tenant account's second factor is an
   e-mailed code, it is switched on for them when the tenant is created, and the
   only way off it is a time-limited exemption granted from the console. A
   "Kapat" here would offer a power that does not exist. */

.tapp-pr-2fa {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: var(--rl-pad);
}

.tapp-pr-2fa-text {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
    flex: 1 1 260px;
}

.tapp-pr-2fa-state {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: var(--rl-t-row);
    color: var(--head);
    font-weight: 600;
}

/* ── The shell: the account menu at the top right ─────────────────────────── */
/* No shadow (turu 9's rule): a filled surface and a hairline separate it from
   what is behind. Deliberately outside `.tapp-shelf` - tenant-app.js moves the
   shelf bodily into the drawer on a phone, and signing out must not end up
   behind a drawer. */

.tapp-topbar {
    --pr-umenu: 268px;
}

.tapp-pr-bar-end {
    display: flex;
    align-items: center;
    gap: 10px;
}

.tapp-pr-ubtn {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--rl-tap);
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: none;
    color: var(--body);
    font: inherit;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}

.tapp-pr-ubtn .tapp-avatar {
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    font-size: var(--t-11-5);
}

.tapp-pr-ubtn-name {
    font-size: var(--rl-t-row);
    font-weight: 600;
    color: var(--head);
    white-space: nowrap;
}

.tapp-pr-ubtn i {
    font-size: var(--t-10);
    color: var(--muted);
}

.tapp-pr-umenu {
    z-index: 8;
    width: var(--pr-umenu);
}

.tapp-pr-uhead {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 8px 10px 10px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border);
}

.tapp-pr-uname {
    font-size: var(--rl-t-name);
    font-weight: 700;
    color: var(--head);
}

.tapp-pr-umail {
    font-size: var(--rl-t-note);
    color: var(--muted);
}

/* No scrim class of its own: these confirmations stand inside turu 8's
   `.tapp-rl-scrim`. On the role screen that scrim *is* a page section; on these
   two it covers the page, so the positioning is written here rather than given
   a second class - the colour, the padding and the centring still come from the
   shared rule.

   Turu 11 added the settings page to the selector, and it is not cosmetic there:
   `.tapp-ay-page` is a grid, so an in-flow scrim would take a grid cell of its
   own and paint a dark block into the layout rather than over it. */
.tapp-pr-page > .tapp-rl-scrim,
.tapp-ay-page > .tapp-rl-scrim {
    position: fixed;
    /* Restated rather than inherited: the phone block at the foot of this file
       takes the dim off a scrim that *is* a page, and this one is not - it is a
       window over one, and a window with nothing behind it is a page that has
       quietly replaced itself. */
    background: color-mix(in srgb, var(--scrim-tint) 66%, transparent);
    inset: 0;
    z-index: 30;
    border: none;
    border-radius: 0;
    align-items: center;
    overflow: auto;
}

/* ── Narrow ───────────────────────────────────────────────────────────────── */

/* 560px, not the design's 860px, and the difference is not taste. Its query
   container was the mock's own frame; here it is the page, and the page is
   capped at `--pr-max` (760px) - so an 860px threshold matches at every width
   there is and the two-column layout could never appear at all. The screen this
   replaces is the one the design drew at 1440: the content column is 760px wide
   there and about 530px at a 768px viewport, so the fold has to sit between
   them. */
@container (max-width: 560px) {
    .tapp-pr-form {
        grid-template-columns: minmax(0, 1fr);
    }
}

@container (max-width: 520px) {
    .tapp-pr-ident {
        align-items: flex-start;
    }
}

/* A media query, not a container query, and that distinction is the whole
   reason this block is separate: the menu is in the topbar, the topbar is the
   shell's, and `container-type` is on the page root - so a container query
   written for it would match nothing and fail silently. It positions itself
   against the viewport and writes nothing to `.tapp-topbar`. */
@media (max-width: 520px) {
    .tapp-pr-ubtn-name {
        display: none;
    }

    .tapp-pr-umenu {
        position: fixed;
        top: var(--topbar-height);
        left: 8px;
        right: 8px;
        width: auto;
    }
}

/* ── İşletme ayarları ──────────────────────────────────────────────────────── */
/* Design turu 11 ("AF - Ayarlar", AF-Ayarlar-SPEC.md). Sits on top of turu 8-10:
   the card (`tapp-pr-card` and its head), the form grid (`tapp-pr-form`), the
   read-only box (`tapp-pr-ro`), the field error (`tapp-pr-err`), the card foot
   (`tapp-rl-foot`) and its dirty counter, the rule card and the confirmation all
   come from there. No new colour token.

   Two departures from the design's own sheet, both the ones every round needs:
   its `--ay-*` sizes were on `.cr` and are here on the page root beside the
   family that uses them, and the query container is declared (the mock's frame
   was the container there; here it is the page). */

/* The page root establishes the query container and caps the width; the grid is
   one element in, deliberately. An element cannot query its own container, so a
   `@container` rule written against `.tapp-ay-page` - which is the container -
   would never match and would fail silently, taking the single-column collapse
   with it. `.tapp-ay-grid` is a descendant, so it can be queried. */
.tapp-ay-page {
    max-width: var(--ay-max);
    margin: 0 auto;

    --ay-max: 1060px;      /* a form page, not a list */
    --ay-nav: 212px;       /* the jump list down the left */
    --ay-logo-w: 168px;
    --ay-logo-h: 88px;
    --ay-sw: 44px;         /* a colour square is also a touch target */
    --ay-bar: 6px;
}

/* The same two columns around a screen that has its own page - kullanıcılar, roller,
   şubeler, alan adı, menü düzeni. It sets only what the grid needs and never the settings
   page's own 1060px cap: those screens are lists and are meant to use the width. */
.tapp-ay-section {
    --ay-nav: 212px;
    width: 100%;
}

.tapp-ay-grid {
    display: grid;
    grid-template-columns: var(--ay-nav) minmax(0, 1fr);
    gap: 20px;
    /* Not align-items:start. A sticky element can only travel inside its own grid area, and
       an area shrunk to the list's own height leaves it nowhere to travel - the list then
       scrolls away with the page, which is exactly what it must not do. The column stretches
       to the row and the list sticks inside it. */
    align-items: stretch;
}

.tapp-ay-navcol {
    min-width: 0;
}

/* ── The section list ─────────────────────────────────────────────────────── */
/* One group at a time, switched by settings.js, which adds is-tabbed to the page -
   so with script blocked every group is simply on the page, one after another, and
   the list is a set of anchors again. The dot still says a group is dirty whether
   that group is the one on screen or not, and the lock still says read-only. The
   screens with a page of their own (kullanıcılar, roller, şubeler, alan adı, menü)
   sit in the same list and carry the list with them. */

.tapp-ay-page.is-tabbed .tapp-ay-group {
    display: none;
}

.tapp-ay-page.is-tabbed .tapp-ay-group.is-active {
    display: flex;
}

.tapp-ay-nav {
    position: sticky;
    top: 12px;
    /* Its own scroller when the list outgrows the viewport, so a long list never pushes its
       last entry below the fold with no way back to it. */
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-card);
    background: var(--card);
}

.tapp-ay-nhead {
    padding: 8px 10px 6px;
    font-size: var(--rl-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
}

/* One title per screen.
   A module screen draws its own head - the brand tile, the name, a line of context and the
   screen's own controls (`.tapp-v3-head`) - and the shell was drawing the same name again right
   above it. Two <h1> elements with identical text, one over the other, on nearly every screen
   in the panel: "Giderler / Giderler", "Cari hesaplar / Cari hesaplar" (seen on the live panel,
   20 September 2026).
   The shell's copy goes and its neighbours in that block stay - a module's trial tag, a vendor
   page's own toolbar, a page subtitle - so nothing that lives up there is lost; the block itself
   is removed only when the title was all it held. The breadcrumb still names the screen once.
   A browser without :has() support simply keeps both, which is what it had before. */
.tapp-main:has(.tapp-v3-head) > .tapp-page-head > .tapp-page-head-row > .tapp-page-title {
    display: none;
}

.tapp-main:has(.tapp-v3-head) > .tapp-page-head:not(:has(.tapp-ro-tag, .tapp-page-head-toolbar, .tapp-page-head-sub)) {
    display: none;
}

/* A decision inside a grouped card. "Çalışma düzeni" holds three of them, each its own form
   with its own save - so each needs a name of its own and a line between it and the next, or
   the three read as one long form with three buttons. */
.tapp-ay-sub + .tapp-ay-sub {
    border-top: 1px solid var(--border);
}

.tapp-ay-sub-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px var(--rl-pad) 0;
}

.tapp-ay-sub-title {
    font-size: var(--rl-t-row);
    font-weight: 700;
    color: var(--head);
}

/* The section search. Sits under the heading and above the list it narrows, in the shape the
   sidebar's own menu filter already uses - the same gesture in the same place. */
.tapp-ay-nsearch {
    position: relative;
    margin: 0 4px 8px;
}

.tapp-ay-nsearch i {
    position: absolute;
    top: 50%;
    left: 10px;
    transform: translateY(-50%);
    font-size: var(--t-12);
    color: var(--muted);
    pointer-events: none;
}

.tapp-ay-nfind {
    width: 100%;
    padding: 8px 10px 8px 30px;
    border: 1px solid var(--border);
    border-radius: var(--r-card);
    background: var(--input);
    color: var(--body);
    font: inherit;
    font-size: var(--rl-t-row, var(--t-13));
}

.tapp-ay-nfind::placeholder {
    color: var(--muted);
}

.tapp-ay-nfind:focus {
    outline: none;
    border-color: var(--ring, var(--brand-indigo));
}

/* Chrome draws its own clear button on a search input; it lands on the border radius. */
.tapp-ay-nfind::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.tapp-ay-nempty {
    padding: 10px;
    font-size: var(--rl-t-row, var(--t-13));
    color: var(--muted);
}

.tapp-ay-nitem {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--rl-tap);
    padding: 8px 10px;
    border: none;
    border-radius: var(--rl-r-ctl);
    background: none;
    color: var(--body);
    font: inherit;
    font-size: var(--rl-t-row);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast);
}

/* A status colour, never the brand's: "you have not saved this" is not an accent. */
.tapp-ay-ndot {
    margin-left: auto;
    width: 7px;
    height: 7px;
    border-radius: var(--r-pill);
    background: var(--warn);
    flex: 0 0 auto;
}

.tapp-ay-nlock {
    margin-left: auto;
    font-size: var(--t-10);
    color: var(--muted);
}

.tapp-ay-main {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}

/* ── The logo, in four states ─────────────────────────────────────────────── */
/* The dashed border belongs to the empty box alone: that box is the file field.
   Once something is in it the border is solid, because it is no longer an
   invitation. */

.tapp-ay-logo {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
    padding: var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-ay-logo-box {
    flex: 0 0 auto;
    width: var(--ay-logo-w);
    height: var(--ay-logo-h);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px;
    border: 1px dashed var(--border);
    border-radius: var(--rl-r-ctl);
    background: var(--bg);
    color: var(--muted);
    font-size: var(--rl-t-note);
    text-align: center;
    line-height: 1.4;
}

.tapp-ay-logo-box i {
    font-size: var(--t-15);
    color: var(--muted);
}

.tapp-ay-logo-box.is-loaded,
.tapp-ay-logo-box.is-busy {
    border-style: solid;
}

.tapp-ay-logo-box.is-bad {
    border-style: solid;
    border-color: var(--bad);
}

.tapp-ay-logo-box.is-bad i {
    color: var(--bad);
}

.tapp-ay-logo-box img {
    max-width: 100%;
    max-height: 56px;
    display: block;
}

.tapp-ay-logo-side {
    flex: 1 1 260px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.tapp-ay-logo-acts {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Determinate. A spinner that turns forever says only "something is happening",
   which is what this system's animation rule exists to refuse; the proportion is
   written as a number beside it too. */
.tapp-ay-prog {
    width: 100%;
    height: var(--ay-bar);
    border-radius: var(--r-pill);
    background: var(--input);
    overflow: hidden;
}

.tapp-ay-prog-fill {
    height: 100%;
    background: var(--acc-solid);
}

/* ── The allowances - the whole group is read-only ────────────────────────── */
/* No dimming. 0.45 opacity belongs to a disabled button; this group is not
   switched off, it is simply not yours to change. The boxes take the surface one
   layer down, keep their border, and the figures stay at full contrast. */

/* ARCP-171: the set-once screens other modules own, listed here because they are no longer in
   the sidebar (ModuleMenuEntry.IsSettingsScreen). A list of doors, not a form - so it carries
   no save band and no dirty dot, and it is the one card on this page that can be absent
   entirely, for a tenant whose modules declare none. */
.tapp-ay-mods {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    padding: var(--rl-pad);
}

.tapp-ay-mod {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: var(--bg);
}

.tapp-ay-mod-head {
    font-size: var(--t-12);
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--muted);
}

.tapp-ay-mod-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--rl-tap);
    padding: 8px 10px;
    border-radius: var(--rl-r-ctl);
    color: var(--body);
    font-size: var(--rl-t-row);
    text-decoration: none;
}

.tapp-ay-mod-go {
    margin-inline-start: auto;
    font-size: var(--t-11);
}

.tapp-ay-limits {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    padding: var(--rl-pad);
}

.tapp-ay-limit {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: var(--bg);
}

.tapp-ay-limit-k {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--rl-t-lbl);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted);
}

.tapp-ay-limit-k i {
    font-size: var(--t-10);
    letter-spacing: 0;
}

.tapp-ay-limit-v {
    font-size: 16px;
    font-weight: 700;
    color: var(--head);
    font-variant-numeric: tabular-nums;
    letter-spacing: -.2px;
}

.tapp-ay-bar {
    height: var(--ay-bar);
    border-radius: var(--r-pill);
    background: var(--input);
    overflow: hidden;
}

.tapp-ay-bar-fill {
    height: 100%;
    background: var(--acc-solid);
}

.tapp-ay-bar-fill.is-warn {
    background: var(--warn);
}

.tapp-ay-limits-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: var(--rl-pad-s) var(--rl-pad);
    border-top: 1px solid var(--border);
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
}

.tapp-ay-form-note {
    grid-column: 1 / -1;
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.45;
    text-wrap: pretty;
}

/* ── Narrow ───────────────────────────────────────────────────────────────── */
/* Measured against the page, which `--ay-max` caps at 1060px: the jump list is a
   column on a wide screen and a row of chips below about a 1280px viewport. */

@container (max-width: 1000px) {
    .tapp-ay-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Still a jump list, just laid along the top. */
    .tapp-ay-nav {
        position: static;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 6px;
    }

    .tapp-ay-nhead {
        display: none;
    }

    .tapp-ay-nitem {
        border: 1px solid var(--border);
        border-radius: var(--r-pill);
        padding: 6px 12px;
        font-size: var(--rl-t-note);
    }

    .tapp-ay-nitem.is-active {
        border-color: var(--acc-solid);
    }

    .tapp-ay-ndot,
    .tapp-ay-nlock {
        margin-left: 0;
    }
}

@container (max-width: 860px) {
    .tapp-ay-limits,
    .tapp-ay-mods {
        grid-template-columns: minmax(0, 1fr);
    }
}

@container (max-width: 520px) {
    .tapp-ay-grid {
        gap: 12px;
    }

    .tapp-ay-main {
        gap: 12px;
    }

    .tapp-ay-logo {
        gap: 12px;
    }

    .tapp-ay-logo-box {
        width: 100%;
        flex: 1 1 100%;
    }

    .tapp-ay-limits-foot .tapp-btn {
        flex: 1 1 auto;
        justify-content: center;
        min-height: var(--rl-tap);
    }
}

/* The three page roots and the window page at phone width, as a media query
   rather than a container query - the distinction the account menu's own block
   above records. Each of these elements *is* its own query container, and an
   element cannot query the container it establishes: written inside `@container`
   these rules matched nothing and failed silently, leaving the permission
   windows their desktop padding and border on a phone. The viewport is the honest measure here anyway,
   because at this width the sidebar is a drawer and the page has the screen to
   itself. */
@media (max-width: 520px) {
    .tapp-rl-page,
    .tapp-ku-page,
    .tapp-pr-page {
        gap: 12px;
    }

    /* Edge to edge: a 24px inset and a border around a window that already fills
       the screen is a frame drawn around the frame. */
    .tapp-rl-scrim {
        padding: 0;
        background: none;
        border: none;
    }
}

/* ── Anonim kabuk ve şifre sıfırlama ───────────────────────────────────────── */
/* Design turu 12 ("AG - Sifre sifirlama", AG-Sifre-Sifirlama-SPEC.md). Sits on
   top of turu 8-11: the field (`tapp-field`, `tapp-input`), the field error
   (`tapp-pr-err`), the password field and its Göster button (`tapp-ku-pw`), the
   rule list (`tapp-ku-rules`) and the alert (`tapp-alert`) all come from there.
   No new colour token.

   The one new thing is the shell: no sidebar, no topbar, one centred card. The
   person who lands here cannot sign in, so there is nothing to navigate to.

   Three departures from the design's own sheet, the ones every round needs: its
   `--sf-*` sizes were on `.cr` and are here on the shell beside the family that
   uses them; the shell is declared as the query container (the mock's frame was
   the container there); and the mock scaffolding (`.tapp-yn-frame`) is dropped.
   The shell's own min-height is the viewport rather than the mock's 560px. */

.tapp-sf-shell {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
    background: var(--bg);
    color: var(--body);

    --sf-card: 420px;      /* one column of form, no table */
    --sf-bar: 64px;        /* the shell's own band, not the panel's 52px topbar */
    --sf-logo: 32px;
    --sf-gap: 14px;
}

.tapp-sf-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: var(--sf-bar);
    padding: 10px 20px;
    border-bottom: 1px solid var(--border);
}

/* The tenant's identity: its logo if it has one, its name if not. The accent is
   deliberately not applied here - see NOTLAR.md turu 12. The question this
   surface answers is "am I at the right address", which the logo answers and
   the accent does not; and on the host address there is no tenant to read one
   from, so the shell would live in two different skins. */
.tapp-sf-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.tapp-sf-brand img {
    height: var(--sf-logo);
    width: auto;
    max-width: 150px;
    object-fit: contain;
    display: block;
}

.tapp-sf-bname {
    font-size: var(--t-15);
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tapp-sf-bar-end {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    flex: 0 0 auto;
}

.tapp-sf-ctl {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: var(--rl-tap);
    min-width: var(--rl-tap);
    padding: 0 11px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: var(--card);
    color: var(--body);
    font: inherit;
    font-size: var(--rl-t-row);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}

.tapp-sf-ctl i {
    font-size: var(--t-12);
    color: var(--muted);
}

.tapp-sf-ctl:focus-visible {
    outline: none;
    background: var(--hover);
    border-color: var(--acc-solid);
    color: var(--head);
}

.tapp-sf-ctl.is-active {
    background: var(--hover);
    color: var(--head);
    border-color: var(--acc-solid);
}

.tapp-sf-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 40px 20px;
}

.tapp-sf-col {
    width: 100%;
    max-width: var(--sf-card);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Hairline border, no shadow: this round opens no confirmation window, and the
   system's only shadow belongs to one. */
.tapp-sf-card {
    overflow: hidden;
}

.tapp-sf-head {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-sf-title {
    font-size: var(--rl-t-card);
    font-weight: 700;
    color: var(--head);
    letter-spacing: -.2px;
    margin: 0;
}

.tapp-sf-form {
    display: flex;
    flex-direction: column;
    gap: var(--sf-gap);
    padding: var(--rl-pad);
}

/* One primary action, full width: there is no second decision on this screen. */
.tapp-sf-form .tapp-btn {
    min-height: var(--rl-tap);
    width: 100%;
    justify-content: center;
}

.tapp-sf-foot {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px var(--rl-pad);
    border-top: 1px solid var(--border);
    font-size: var(--rl-t-note);
    color: var(--muted);
}

/* The state heading: an icon and a title. The icon takes the status colour, the
   surface does not. */
.tapp-sf-state {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: var(--rl-pad);
    border-bottom: 1px solid var(--border);
}

.tapp-sf-state i {
    font-size: 16px;
    margin-top: 2px;
    flex: 0 0 auto;
    color: var(--muted);
}

.tapp-sf-state.is-ok i { color: var(--ok); }
.tapp-sf-state.is-warn i { color: var(--warn); }
.tapp-sf-state.is-bad i { color: var(--bad); }

.tapp-sf-text {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: var(--rl-pad);
    font-size: var(--rl-t-row);
    color: var(--body);
    line-height: 1.55;
    text-wrap: pretty;
}

/* The address it went to, read back. The one correction a person who mistyped
   it can make - which is what this screen owes them for never saying whether
   the address is registered. */
.tapp-sf-mailto {
    display: flex;
    align-items: center;
    gap: 9px;
    min-height: var(--rl-tap);
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--rl-r-ctl);
    background: var(--bg);
    color: var(--head);
    font-size: var(--rl-t-row);
    font-weight: 600;
    word-break: break-all;
}

.tapp-sf-mailto i {
    flex: 0 0 auto;
    color: var(--muted);
    font-size: var(--t-12);
    font-weight: 400;
}

.tapp-sf-steps {
    display: flex;
    flex-direction: column;
    gap: 7px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.tapp-sf-steps li {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-size: var(--rl-t-note);
    color: var(--muted);
    line-height: 1.5;
}

.tapp-sf-steps i {
    font-size: var(--t-10);
    width: 11px;
    text-align: center;
    margin-top: 4px;
    color: var(--muted);
    flex: 0 0 auto;
}

/* The lifespan line, written the same way on every screen that has one. */
.tapp-sf-ttl {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px var(--rl-pad);
    border-top: 1px solid var(--border);
    font-size: var(--rl-t-note);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-sf-ttl i {
    font-size: var(--t-11);
}

/* The host signpost's address field and its fixed suffix. There is no field
   here that takes an e-mail address - see NOTLAR.md turu 12. */
.tapp-sf-addr {
    display: flex;
    align-items: stretch;
    gap: 0;
}

.tapp-sf-addr .tapp-input {
    flex: 1 1 auto;
    min-width: 0;
    border-start-end-radius: 0;
    border-end-end-radius: 0;
}

.tapp-sf-suffix {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    min-height: var(--rl-tap);
    padding: 0 12px;
    border: 1px solid var(--border);
    border-inline-start: none;
    border-start-end-radius: var(--rl-r-ctl);
    border-end-end-radius: var(--rl-r-ctl);
    background: var(--bg);
    color: var(--muted);
    font-size: var(--rl-t-row);
    white-space: nowrap;
}

/* The page footer: who to ask. There is no support link on this surface -
   support is behind the sign-in, and showing a door that does not open is a
   dead end for somebody who is already at one. */
.tapp-sf-pagefoot {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 14px 20px 22px;
    font-size: var(--rl-t-note);
    color: var(--muted);
    text-align: center;
}

.tapp-sf-dot {
    color: var(--border);
}

/* The card's own links. Written out because Bootstrap is loaded on these pages and its
   `--bs-link-color` blue is not in this palette - the mock never had it, so this is one of
   the few rules that exists only in the ported sheet. */
.tapp-sf-foot a,
.tapp-sf-text a {
    color: var(--acc-text);
    text-decoration: none;
}

.tapp-sf-foot a:hover,
.tapp-sf-text a:hover {
    text-decoration: underline;
}

.tapp-sf-foot a:focus-visible,
.tapp-sf-text a:focus-visible {
    outline: none;
    text-decoration: underline;
    color: var(--head);
}

@container (max-width: 520px) {
    .tapp-sf-body {
        padding: 20px 12px 24px;
    }

    .tapp-sf-bar {
        padding: 10px 12px;
    }

    .tapp-sf-bar-end .tapp-sf-ctl span {
        display: none;
    }

    .tapp-sf-bar-end .tapp-sf-ctl {
        padding: 0;
    }

    .tapp-sf-foot {
        flex-direction: column;
        gap: 8px;
    }

    .tapp-sf-addr {
        flex-direction: column;
    }

    .tapp-sf-addr .tapp-input {
        border-radius: var(--rl-r-ctl);
    }

    .tapp-sf-suffix {
        border-inline-start: 1px solid var(--border);
        border-radius: var(--rl-r-ctl);
    }
}

/* ---------------------------------------------------------------- daily reminders */

/* The "günün hatırlatmaları" window (Components/DailyReminders), drawn after Isabet's own:
   a count beside the title, one line per thing waiting, and a single way to silence it for
   the day. Fixed to the viewport and outside every scrolling column, so opening it never
   changes the height of the page underneath - the lesson of the credit line. */
.tapp-dr-scrim {
    position: fixed;
    inset: 0;
    z-index: 1060;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 72px 16px 16px;
    background: var(--scrim);
}

.tapp-dr {
    width: 100%;
    max-width: 560px;
    max-height: calc(100vh - 96px);
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    background: var(--card);
    color: var(--body);
    box-shadow: var(--shadow-panel);
    overflow: hidden;
}

.tapp-dr:focus {
    outline: none;
}

.tapp-dr-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--border);
}

.tapp-dr-head-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1;
    min-width: 0;
}

.tapp-dr-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 17px;
    font-weight: 700;
    color: var(--head);
}

.tapp-dr-title > i {
    font-size: var(--t-15);
    color: var(--muted);
}

.tapp-dr-count {
    padding: 1px 9px;
    border-radius: var(--r-pill);
    background: var(--hover);
    font-size: var(--t-12);
    font-weight: 700;
    color: var(--head);
    font-variant-numeric: tabular-nums;
}

.tapp-dr-x {
    flex: none;
    width: 36px;
    height: 36px;
    border: none;
    border-radius: var(--r-ctl);
    background: none;
    color: var(--muted);
    cursor: pointer;
}

.tapp-dr-x:hover,
.tapp-dr-x:focus-visible {
    background: var(--hover);
    color: var(--head);
}

.tapp-dr-list {
    list-style: none;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    min-height: 0;
}

.tapp-dr-list > li + li {
    border-top: 1px solid var(--border);
}

.tapp-dr-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 20px;
    color: inherit;
    text-decoration: none;
}

.tapp-dr-row:hover,
.tapp-dr-row:focus-visible {
    background: var(--hover);
    outline: none;
}

.tapp-dr-ico {
    flex: none;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--t-15);
}

/* The tile carries the kind's own brand hue, never the status: what is late is said by the
   chip beside it, in red, and a row tinted red twice says one thing twice. */
.tapp-dr-ico.is-indigo {
    background: color-mix(in oklab, var(--brand-indigo) 18%, transparent);
    color: var(--brand-indigo);
}

.tapp-dr-ico.is-pink {
    background: color-mix(in oklab, var(--brand-pink) 18%, transparent);
    color: var(--brand-pink);
}

.tapp-dr-main {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
    min-width: 0;
}

.tapp-dr-text {
    font-size: 14px;
    font-weight: 600;
    color: var(--head);
    overflow-wrap: anywhere;
}

.tapp-dr-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    font-size: var(--t-12-5);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.tapp-dr-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border: 1px solid currentColor;
    border-radius: var(--r-pill);
    font-weight: 600;
}

.tapp-dr-chip.is-bad {
    color: var(--bad);
    background: var(--badbg);
    border-color: transparent;
}

.tapp-dr-chip.is-warn {
    color: var(--warn);
    background: var(--warnbg);
    border-color: transparent;
}

.tapp-dr-amt {
    font-weight: 700;
    color: var(--head);
}

.tapp-dr-go {
    flex: none;
    font-size: var(--t-12);
    color: var(--muted);
}

.tapp-dr-foot {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    padding: 12px 20px;
    border-top: 1px solid var(--border);
}

@media (max-width: 520px) {
    .tapp-dr-scrim {
        padding: 16px 12px;
    }

    .tapp-dr {
        max-height: calc(100vh - 32px);
    }

    .tapp-dr-row {
        padding: 12px 14px;
        gap: 12px;
    }
}

/* ---------------------------------------------------------------- work order close: payment */

/* The Peşin / Taksit / Peşinat choice in the close window (work-order-close.js). The chosen
   pill is found by :has() rather than a class a script has to keep in step, and a group of
   fields belonging to a mode not chosen is disabled - which is also what hides it here. */
.tapp-wo-pay {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.tapp-wo-pay-seg {
    display: flex;
    width: 100%;
}

.tapp-wo-pay-seg > .tapp-seg-item {
    flex: 1;
    justify-content: center;
    padding: 9px 10px;
    font-size: var(--t-13);
}

.tapp-wo-pay-seg > .tapp-seg-item:has(input:checked) {
    background: color-mix(in oklab, var(--brand-indigo) 18%, transparent);
    color: var(--brand-indigo);
}

.tapp-wo-pay-seg > .tapp-seg-item:has(input:focus-visible) {
    outline: 2px solid var(--brand-indigo);
    outline-offset: 1px;
}

.tapp-wo-pay-set {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 12px;
    margin: 0;
    padding: 0;
    border: 0;
    min-width: 0;
}

.tapp-wo-pay-set[disabled] {
    display: none;
}

.tapp-wo-pay-step {
    display: flex;
    align-items: center;
    gap: 6px;
}

.tapp-wo-pay-step > .tapp-input {
    flex: 1;
    min-width: 0;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.tapp-wo-pay-step > .tapp-btn {
    flex: none;
    width: 38px;
    height: 38px;
    justify-content: center;
    padding: 0;
}

/* ── Bootstrap inside the panel ──────────────────────────────────────────────
 * The account, billing, branch, domain, menu, export and notification screens were written
 * with Bootstrap's own classes (.card, .btn, .form-control, .table), and LeptonX Lite paints
 * those from its own light palette however this shell is set: a white card on the dark ground,
 * reported as "abonelik sayfası koyu moddan etkilenmiyor".
 *
 * Mapped here rather than rewritten on each of the twenty-odd pages: one place, no markup
 * touched, and a page converted to tapp-* later simply stops matching these rules. Scoped to
 * .cr.tapp-shell so nothing outside the panel - the login screen, the console - is affected.
 * These are the panel's own tokens, so both themes follow from the same declaration. */

.cr.tapp-shell .card,
.cr.tapp-shell .list-group,
.cr.tapp-shell .list-group-item,
.cr.tapp-shell .accordion-item,
.cr.tapp-shell .accordion-button,
.cr.tapp-shell .modal-content,
.cr.tapp-shell .dropdown-menu {
    background-color: var(--card);
    border-color: var(--border);
    color: var(--body);
}

.cr.tapp-shell .card-header,
.cr.tapp-shell .card-footer {
    background-color: var(--thead);
    border-color: var(--border);
    color: var(--head);
}

.cr.tapp-shell .card h1,
.cr.tapp-shell .card h2,
.cr.tapp-shell .card h3,
.cr.tapp-shell .card h4,
.cr.tapp-shell .card h5,
.cr.tapp-shell .card h6,
.cr.tapp-shell .card dt,
.cr.tapp-shell .card-title {
    color: var(--head);
}

.cr.tapp-shell .text-muted,
.cr.tapp-shell .form-text,
.cr.tapp-shell .card .text-secondary {
    color: var(--muted) !important;
}

.cr.tapp-shell .table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--body);
    --bs-table-border-color: var(--border);
    --bs-table-striped-bg: var(--zebra);
    --bs-table-striped-color: var(--body);
    --bs-table-hover-bg: var(--hover);
    --bs-table-hover-color: var(--head);
    color: var(--body);
}

.cr.tapp-shell .table > thead {
    background-color: var(--thead);
    color: var(--head);
}

.cr.tapp-shell .form-control,
.cr.tapp-shell .form-select,
.cr.tapp-shell .input-group-text {
    background-color: var(--input);
    border-color: var(--border);
    color: var(--head);
}

.cr.tapp-shell .form-control::placeholder {
    color: var(--muted);
}

.cr.tapp-shell .form-control:focus,
.cr.tapp-shell .form-select:focus {
    background-color: var(--input);
    border-color: var(--accent, var(--brand-indigo));
    color: var(--head);
}

.cr.tapp-shell .form-label,
.cr.tapp-shell .form-check-label,
.cr.tapp-shell legend {
    color: var(--body);
}

/* The two neutral buttons only: a coloured .btn-primary / .btn-danger already reads correctly
   on either ground, and repainting those would lose the meaning they carry. */
.cr.tapp-shell .btn-light,
.cr.tapp-shell .btn-outline-secondary,
.cr.tapp-shell .btn-secondary {
    background-color: var(--input);
    border-color: var(--border);
    color: var(--head);
}

.cr.tapp-shell .btn-light:hover,
.cr.tapp-shell .btn-outline-secondary:hover,
.cr.tapp-shell .btn-secondary:hover {
    background-color: var(--hover);
    border-color: var(--border);
    color: var(--head);
}

.cr.tapp-shell hr,
.cr.tapp-shell .dropdown-divider {
    border-color: var(--border);
    color: var(--border);
}

.cr.tapp-shell .badge.bg-light {
    background-color: var(--input) !important;
    color: var(--head);
}

/* The two-factor card's own switch (Pages/Account/Profile). The card was a state and a
   sentence; it carries the button that changes the state now, and the code field that
   confirms it. Its own column so it keeps its width beside the wrapping text. */

.tapp-pr-2fa-act {
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 0 1 260px;
}

.tapp-pr-2fa-form {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ------------------------------------------------------------------- malzeme
 *
 * Translucency, where it says something (Apple, §12 materials & depth). Not everywhere: this
 * panel's topbar and sidebar are structural walls with their own ground, nothing scrolls under
 * them, and frosting them would only blur the page's own edge.
 *
 * Three places earn it, and they are the three where a surface really is floating over content
 * the reader still needs to see the shape of:
 *   - the modal's dim, which now blurs what it covers instead of flattening it to grey;
 *   - the menus and the notification panel, which hang over the page for a moment;
 *   - a sticky table header or pane head, where rows should dissolve underneath rather than be
 *     cut off by a hard line.
 *
 * color-mix over the existing tokens, never a literal: the two themes keep their own grounds
 * and this stays one rule instead of two. And every one of them is switched back to solid for
 * a reader who has asked for less transparency - the query exists precisely because this
 * effect costs some people legibility. */
.tapp-dialog::backdrop {
    backdrop-filter: blur(6px) saturate(120%);
}

.tapp-notif-panel,
.tapp-ku-menu,
.tapp-pr-umenu {
    background: color-mix(in oklab, var(--card) 86%, transparent);
    backdrop-filter: blur(18px) saturate(160%);
}

.tapp-rl-pane-head {
    backdrop-filter: blur(12px) saturate(140%);
}

.tapp-rl-pane-head {
    background: color-mix(in oklab, var(--card) 88%, transparent);
}

@media (prefers-reduced-transparency: reduce) {
    .tapp-dialog::backdrop,
    .tapp-notif-panel,
    .tapp-ku-menu,
    .tapp-pr-umenu,
    .tapp-rl-pane-head {
        backdrop-filter: none;
    }

    .tapp-notif-panel,
    .tapp-ku-menu,
    .tapp-pr-umenu,
    .tapp-rl-pane-head {
        background: var(--card);
    }
}

/* ---------------------------------------------------------------- touch targets */

/* A finger is not a mouse pointer: Apple's floor for anything tappable is 44 by 44 points,
   and the panel's small controls - the topbar's icon buttons (32-34px), the ⓘ hint (16x13),
   small buttons, filter chips and period arrows (30px) - all sat under it. On a coarse
   pointer each one gets an invisible hit area centred on itself and at least 44px square,
   so what it looks like does not change, only how hard it is to miss. Nothing here applies
   to a mouse, where the drawn size is already the right one. Every `.tapp-btn` is listed,
   not only the small one: the regular button is 36px too. Inputs are the exception: there
   the field itself is what gets tapped, so it simply grows to 44px. */
@media (pointer: coarse) {
    .tapp-iconbtn,
    .tapp-burger,
    .tapp-hint-btn,
    .tapp-btn,
    .tapp-chip,
    .tapp-period-nav,
    .tapp-rowact,
    .tapp-pager-btn,
    .tapp-legal-tab {
        position: relative;
    }

    .tapp-iconbtn::after,
    .tapp-burger::after,
    .tapp-hint-btn::after,
    .tapp-btn::after,
    .tapp-chip::after,
    .tapp-period-nav::after,
    .tapp-rowact::after,
    .tapp-pager-btn::after,
    .tapp-legal-tab::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: max(100%, 44px);
        height: max(100%, 44px);
        transform: translate(-50%, -50%);
    }

    input.tapp-input,
    select.tapp-input {
        height: 44px;
    }
}
