/* Work Tracking — Shared/_PbLayout
   Extracted from Areas/ProductivityBooster/Views/Shared/_PbLayout.cshtml (page-scoped styles). */

/* ── Design tokens ─────────────────────────────── */
.pb-shell {
    --bg:#f7f8fa; --surface:#ffffff; --surface-2:#f2f4f8; --surface-3:#e8ebf1;
    --border:#e5e7eb; --border-2:#d4d9e3;
    --text:#12151c; --text-2:#525a68; --text-3:#8a91a0;
    --accent:#4361ee; --accent-2:#3a54d4; --accent-soft:#eceffe; --accent-on:#ffffff;
    --success:#0e9f6e; --success-soft:#e7f7f0; --success-text:#0a7d56;
    --warning:#d97706; --warning-soft:#fcf2e3; --warning-text:#a85d04;
    --danger:#dc2626;  --danger-soft:#fdebea;  --danger-text:#b91c1c;
    --info:#2563eb;    --info-soft:#e8efff;    --info-text:#1d4ed8;
    --sidebar:#f9fafb; --sidebar-border:#eaecf2; --topbar:#ffffff;
    --shadow:0 1px 2px rgba(16,20,30,.04), 0 1px 3px rgba(16,20,30,.05);
    --shadow-lg:0 24px 60px -16px rgba(16,20,30,.24);
    --overlay:rgba(18,21,28,.40);
}
.pb-shell.pb-dark {
    --bg:#090b10; --surface:#13161e; --surface-2:#1a1e28; --surface-3:#232834;
    --border:#242a35; --border-2:#333a48;
    --text:#eef1f6; --text-2:#a6aebd; --text-3:#6c7484;
    --accent:#7d7bff; --accent-2:#9b99ff; --accent-soft:rgba(125,123,255,.12); --accent-on:#ffffff;
    --success:#2dd4a4; --success-soft:rgba(45,212,164,.14); --success-text:#3ce0b2;
    --warning:#f0a83a; --warning-soft:rgba(240,168,58,.15); --warning-text:#f6bb5d;
    --danger:#f1675c;  --danger-soft:rgba(241,103,92,.16); --danger-text:#ff8479;
    --info:#5d8cff;    --info-soft:rgba(93,140,255,.16); --info-text:#86a8ff;
    --sidebar:#0c0e14; --sidebar-border:#1c212b; --topbar:#0f121a;
    --shadow:0 1px 2px rgba(0,0,0,.5);
    --shadow-lg:0 28px 64px -16px rgba(0,0,0,.7);
    --overlay:rgba(2,4,8,.62);
}

/* ── Reset ─────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }

/* ── Shell ─────────────────────────────────────── */
.pb-shell {
    display: flex;
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    font-family: Inter, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 13px;
}

/* ══════════════════════════════════════════════
   SIDEBAR
   Design pass ("tinted tiles"): every screen wears a 30px icon tile in its own hue, so
   the twelve marks are told apart by colour before they are read. Group labels rule out
   to the rail's edge; the current screen takes an accent wash, accent type and a bar at
   the rail edge, and its tile lifts to plain surface. The footer is a card, not a strip.
   Class names, markup order and every behaviour are unchanged — the one markup addition
   is data-key on each row, a styling hook that carries the tint.
══════════════════════════════════════════════ */
.pb-side {
    width: 252px;
    flex-shrink: 0;
    background: var(--sidebar);
    /* A whisper of top-light so the brand end of the rail lifts off the nav rows.
       Painted over --sidebar, so each theme keeps its own ground colour. */
    background-image: linear-gradient(180deg, rgba(255,255,255,.85), rgba(255,255,255,0) 180px);
    border-right: 1px solid var(--sidebar-border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden; /* outer aside NEVER scrolls — only .pb-nav-body scrolls */
    /* The old 8px blur read as a drop shadow under a floating panel. The rail is not
       floating: a hairline plus a very soft falloff is all the separation it needs. */
    box-shadow: 6px 0 22px -18px rgba(16, 20, 30, .55);
}
.pb-shell.pb-dark .pb-side {
    background-image: linear-gradient(180deg, rgba(255,255,255,.045), rgba(255,255,255,0) 180px);
    box-shadow: 6px 0 22px -16px rgba(0, 0, 0, .8);
}

/* Brand header — pinned, never scrolls. 53px so it sits on the topbar baseline. */
.pb-brand {
    height: 53px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 16px;
    /* The header no longer cuts the rail with a hard rule — it fades out, so the eye
       runs from the lockup into the first group label without a speed bump. */
    border-bottom: 1px solid transparent;
    border-image: linear-gradient(90deg, var(--sidebar-border) 55%, transparent) 1;
}

/* The lockup sits on the sidebar bare — no gradient tile, no glow. Those existed to
   give the old generic squiggle a shape to live in; the artwork carries its own.
   Width-driven: the lockup is ~3.95:1, so 180px lands at ~46px inside the 53px bar.
   Two files rather than one tinted image because the artwork is two-tone (blue ring
   and dot, navy wordmark) and only the navy half needs to flip — on the near-black
   dark sidebar the navy would vanish. */
.pb-brand-logo {
    width: 180px;
    max-width: 100%;
    line-height: 0;
    flex-shrink: 0;
}

.pb-brand-logo img {
    width: 100%;
    height: auto;
    display: block;
}

.pb-brand-logo .pb-mark-dark { display: none; }
.pb-shell.pb-dark .pb-brand-logo .pb-mark-light { display: none; }
.pb-shell.pb-dark .pb-brand-logo .pb-mark-dark { display: block; }

/* Nav scroll body — ONLY this element scrolls */
.pb-nav-body {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 8px 0 14px;
    overscroll-behavior: contain;

    /* The thumb only takes ink while the pointer is on the rail: a rail that fits shows
       no scrollbar at all, one that overflows says so the moment you go near it.
       STATED TWICE ON PURPOSE. Chrome 121+ and Firefox honour the standard properties
       below and IGNORE every ::-webkit-scrollbar rule the moment scrollbar-width is
       set — so the hover reveal has to live here, in scrollbar-color, or it silently
       does nothing on the browsers most of this app runs in. The -webkit- block after
       it is for Safari and older Chrome, which have it the other way round. */
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
}
.pb-side:hover .pb-nav-body { scrollbar-color: var(--border-2) transparent; }

.pb-nav-body::-webkit-scrollbar { width: 6px; }
.pb-nav-body::-webkit-scrollbar-track { background: transparent; }
.pb-nav-body::-webkit-scrollbar-thumb { background: transparent; border-radius: 99px; }
.pb-side:hover .pb-nav-body::-webkit-scrollbar-thumb { background: var(--border-2); }
.pb-nav-body::-webkit-scrollbar-thumb:hover { background: var(--text-3); }

/* Section group label — the words with a hairline running out to the rail's edge. It is
   the only rule left in the nav, and it does two jobs at once: it says a group starts
   here, and the same stroke says how wide the rail is. */
.pb-grp {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 18px 16px 8px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.11em;
    color: var(--text-3);
    user-select: none;
}
.pb-grp::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--sidebar-border);
}
.pb-nav-body > .pb-grp:first-child { padding-top: 8px; }

/* The rule between sections is gone — the group labels carry the separation now. The
   element stays, because the markup emits it, and becomes the space itself: no row has
   to know it is first of its group, and a group the master adds tomorrow is spaced like
   the rest without this file hearing about it. */
.pb-divider {
    height: 0;
    background: none;
    margin: 7px 0 0;
}
.pb-divider + .pb-grp { padding-top: 12px; } /* the label already carries its own space */
.pb-divider + .pb-nav  { margin-top: 8px; }  /* the untitled groups: agent, settings */

/* Nav row — a pill built around a tinted icon tile, at reading size. The label sits at
   full text colour rather than the old grey: with the tiles carrying the hierarchy, a
   dimmed label only made the rail harder to read. */
.pb-nav {
    --h: 226;         /* tile hue — every screen sets its own at the foot of this block */
    --tile-sat: 62%;
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 1px 10px;
    padding: 6px 10px;   /* 30px tile + 6 + 6 = a 42px row */
    border-radius: 12px;
    color: var(--text);
    text-decoration: none;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.3;
    transition: background .14s ease, color .14s ease;
}
/* Twelve rows of full-strength white would glare on the near-black rail. */
.pb-shell.pb-dark .pb-nav { color: var(--text-2); }

.pb-nav:hover { background: var(--surface-2); }
.pb-shell.pb-dark .pb-nav:hover { color: var(--text); }

.pb-nav:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

/* The current screen: an accent wash and accent type, plus a bar at the RAIL's edge
   rather than the pill's — it marks the row against the whole sidebar, not inside it. */
.pb-nav.on {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
}
/* The dark accent is a mid violet, and on its own 12% wash it reads dimmer than the
   plain rows it is meant to lead. The lighter step is the legible one there. */
.pb-shell.pb-dark .pb-nav.on { color: var(--accent-2); }
.pb-nav.on::before {
    content: "";
    position: absolute;
    left: -10px;
    top: 50%;
    width: 3px;
    height: 22px;
    margin-top: -11px;
    border-radius: 0 3px 3px 0;
    background: var(--accent);
}

/* ICON TILES, TINTED PER SCREEN.
   Each screen carries its own hue, so the twelve marks are told apart by colour before
   they are read — much the faster thing to aim at in a rail this long. One hue per
   screen, set as --h on the row; the tile derives both its wash and its ink from that
   single number, so adding a screen is one line and both themes follow from it. */
.pb-nico {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: hsl(var(--h) 78% 94%);
    color: hsl(var(--h) var(--tile-sat) 42%);
    transition: background .14s ease, color .14s ease, box-shadow .14s ease;
}
.pb-shell.pb-dark .pb-nico {
    background: hsl(var(--h) 55% 62% / .16);
    color: hsl(var(--h) 70% 70%);
}

.pb-nav:hover .pb-nico { box-shadow: 0 0 0 1px hsl(var(--h) 60% 84%); }
.pb-shell.pb-dark .pb-nav:hover .pb-nico { box-shadow: 0 0 0 1px hsl(var(--h) 45% 45% / .55); }

/* On the current row the tile lifts to plain surface and keeps only its ink: the row is
   already washed in accent, and two tints on one row is one too many. */
.pb-nav.on .pb-nico {
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(16, 20, 30, .10);
}
.pb-shell.pb-dark .pb-nav.on .pb-nico {
    background: var(--surface-2);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .45);
}

/* One hue per screen, keyed off data-key — which the component writes straight from the
   menu master's screenkey, so the tint is the only thing this stylesheet knows about a
   screen. Rename Tickets to Helpdesk on Settings > Menus and it stays orange. A screen
   this list has never heard of keeps the neutral indigo set above. */
.pb-nav[data-key="home/index"]           { --h: 244; }  /* console — the product accent */
.pb-nav[data-key="screenshots/index"]    { --h: 276; }  /* violet */
.pb-nav[data-key="timeattendance/index"] { --h: 196; }  /* clock blue */
.pb-nav[data-key="projects/index"]       { --h: 152; }  /* green */
.pb-nav[data-key="mywork/index"]         { --h: 38;  }  /* amber */
.pb-nav[data-key="issues/index"]         { --h: 352; }  /* rose — bugs read red everywhere else */
.pb-nav[data-key="tickets/index"]        { --h: 22;  }  /* orange */
.pb-nav[data-key="knowledge/index"]      { --h: 210; }  /* blue */
.pb-nav[data-key="desktopagent/index"]   { --h: 288; }  /* purple */
.pb-nav[data-key="teamreports/index"]    { --h: 168; }  /* teal */
.pb-nav[data-key="teamreports/myreport"] { --h: 186; }  /* cyan */
.pb-nav[data-key="settings/index"]       { --h: 220; --tile-sat: 18%; } /* deliberately grey */

/* A long label from the menu master truncates rather than wrapping to two lines and
   breaking the rail's rhythm. */
.pb-nav-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    letter-spacing: -0.005em;
}

/* Optional badge */
.pb-badge {
    margin-left: auto;
    background: var(--danger);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    border-radius: 99px;
    padding: 1px 6px;
    line-height: 1.5;
}

/* User footer — pinned, never scrolls. A card sitting on the rail rather than a strip
   ruled off it, so the identity block reads as an object like everything above it. */
.pb-side-foot {
    flex-shrink: 0;
    margin: 10px;
    padding: 8px 9px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(16, 20, 30, .05);
    display: flex;
    align-items: center;
    gap: 10px;
}
.pb-shell.pb-dark .pb-side-foot { box-shadow: 0 1px 2px rgba(0, 0, 0, .4); }

/* Round, against a rail of rounded squares — the one circle in the sidebar is a person,
   not a screen. */
.pb-side-av {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: -0.02em;
    color: var(--accent-on);
    /* The same two-stop accent the content-area .pb-av uses, so one person's initial
       is the same object wherever it is drawn. */
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    box-shadow: 0 1px 2px rgba(16, 20, 30, .16);
    flex-shrink: 0;
}

/* Keep .pb-av for compatibility with _PbStyles content-area usage */
.pb-av {
    width: 34px; height: 34px; border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: var(--accent-on);
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
}

.pb-side-info { flex: 1; min-width: 0; }

.pb-side-uname {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.35;
    letter-spacing: -0.01em;
}

.pb-side-cname {
    font-size: 11px;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.35;
}

/* Sign out — the shell had no logout control at all (BUG-2971). Icon-only at rail
   width: the word cost about sixty pixels that the company name needed, and the
   control keeps its name for screen readers and as its tooltip. */
.pb-side-out {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    padding: 0;
    border-radius: 8px;
    /* Borderless inside the footer card — a second border 9px in from the first only
       drew attention to a control that should sit quietly until wanted. */
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-3);
    text-decoration: none;
    transition: background .14s ease, color .14s ease, border-color .14s ease;
}

.pb-side-out:hover { background: var(--danger-soft); color: var(--danger-text); border-color: var(--danger); }
.pb-side-out:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Visually hidden, still read aloud — the sign-out label, and anything else the rail
   must say to a screen reader without drawing it. */
.pb-sr {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ══════════════════════════════════════════════
   TOPBAR + MAIN
══════════════════════════════════════════════ */
.pb-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.pb-head {            
    flex-shrink: 0;
    background: var(--topbar);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 15px;
    position: sticky;
    top: 0;
    z-index: 555;
    box-shadow: 0 1px 2px rgba(14,17,23,.05);
}

.pb-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-2);
    text-decoration: none;
    padding: 5px 10px;
    border-radius: 8px;
    border: 1px solid var(--border);
    transition: background 0.12s ease, color 0.12s ease;
    white-space: nowrap;
    flex-shrink: 0;
}

.pb-back:hover { background: var(--surface-2); color: var(--text); }

.pb-online {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--success-text);
    background: var(--success-soft);
    padding: 4px 10px;
    border-radius: 99px;
}

.pb-online .d {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--success);
    animation: pb-pulse 2.4s ease infinite;
}

@keyframes pb-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.4; }
}

.pb-head-sp { flex: 1; }

.pb-iconbtn {
    width: 32px; height: 32px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-2);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.12s ease, color 0.12s ease;
    flex-shrink: 0;
}

.pb-iconbtn:hover { background: var(--surface-2); color: var(--text); }
.pb-iconbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Sign out in the topbar — same red-on-hover reading as the rail's .pb-side-out,
   so the destructive control looks the same wherever it appears. */
a.pb-iconbtn { text-decoration: none; }
.pb-iconbtn.danger:hover { background: var(--danger-soft); color: var(--danger-text); border-color: var(--danger); }

/* ══════════════════════════════════════════════
   NOTIFICATION BELL
   Design pass, same rules as the rail's tinted tiles: one hue number per row carries
   both the wash and the ink of its icon tile, and the hue is the DESTINATION SCREEN's
   — a row that opens Bug Tracking wears Bug Tracking's rose, the same rose the rail
   gives it. So the panel teaches no second colour language. What separates two rows
   that open the same screen is the glyph; what overrides both is urgency, which
   repaints the tile amber or red and is the only thing allowed to.

   Unread is stated twice — a filled dot AND a heavier title on a lifted ground — so it
   survives greyscale and colour blindness. Read rows are not hidden and not struck
   through; they simply stop asking, which is what "read" means.

   The button itself stays a plain .pb-iconbtn. A bell that looked like a different KIND
   of control from the theme toggle beside it would be a worse header, not a better one.
══════════════════════════════════════════════ */
.pb-bell-wrap { position: relative; display: inline-flex; flex-shrink: 0; }

.pb-bell-btn.on {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: var(--accent-soft);
}

/* The count rides the button's top-right corner, half outside it, cut out of the
   button beneath by a ring in the topbar's own colour. It is the one thing in this
   header allowed to be loud: an unread count nobody notices is a bell that does not
   work. Tabular figures so 1 → 2 → 3 does not shuffle the badge's width. */
.pb-bell-badge {
    position: absolute;
    top: -5px; right: -5px;
    min-width: 17px; height: 17px;
    padding: 0 4px;
    border-radius: 99px;
    background: var(--danger);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 17px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--topbar);
    pointer-events: none;
}

/* Transparent, not dimmed: this is a dropdown, not a modal. It exists to catch the click
   that closes the panel, and z-index puts it under the panel and over the page. */
.pb-bell-scrim { position: fixed; inset: 0; z-index: 60; }

.pb-bell-panel {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 61;
    width: 400px;
    max-width: calc(100vw - 24px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--shadow-lg);
    display: flex;
    flex-direction: column;
    overflow: hidden;        /* clips the list's own corners to the panel's radius */
    transform-origin: top right;
    animation: pb-bell-in .14s cubic-bezier(.2, .8, .3, 1);
}

@keyframes pb-bell-in {
    from { opacity: 0; transform: translateY(-6px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

/* A 9px square rotated 45° with only its two top edges stroked, so it reads as the panel's
   own corner pulled up to a point rather than a diamond stuck on top. It is a SIBLING of
   the panel — inside it, the panel's overflow:hidden would clip away the half that sticks
   out — so it is positioned against .pb-bell-wrap and offset to the panel's top edge. */
.pb-bell-caret {
    position: absolute;
    top: calc(100% + 6px);
    right: 13px;
    z-index: 62;
    width: 9px; height: 9px;
    background: var(--surface);
    border-left: 1px solid var(--border);
    border-top: 1px solid var(--border);
    border-radius: 2px 0 0 0;
    transform: rotate(45deg);
}

.pb-bell-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
}

.pb-bell-title {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -.01em;
}

/* Just the number. "6 new" beside a title that already says Notifications was two words
   doing one word's work. */
.pb-bell-count {
    min-width: 18px;
    padding: 1px 6px;
    border-radius: 99px;
    background: var(--danger-soft);
    color: var(--danger-text);
    font-size: 10.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

/* Pushed to the far edge so it can never be hit on the way to the first row. */
.pb-bell-mark {
    margin-left: auto;
    border: 0;
    background: none;
    padding: 3px 7px;
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-2);
    cursor: pointer;
    border-radius: 7px;
    transition: background .12s ease, color .12s ease;
}
.pb-bell-mark:hover:not(:disabled) { background: var(--accent-soft); color: var(--accent); }
.pb-bell-mark:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pb-bell-mark:disabled { color: var(--text-3); cursor: default; }

/* ~5 rows before it scrolls. A panel taller than that has stopped being a glance. */
.pb-bell-list {
    max-height: min(58vh, 460px);
    overflow-y: auto;
    overscroll-behavior: contain;   /* the page beneath must not scroll at the ends */
    scrollbar-width: thin;
    scrollbar-color: var(--border-2) transparent;
}
.pb-bell-list::-webkit-scrollbar { width: 8px; }
.pb-bell-list::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; border: 2px solid var(--surface); }
.pb-bell-list::-webkit-scrollbar-track { background: transparent; }

/* Coming up · Today · Yesterday · Earlier. Sticky, so the heading for the rows you are
   looking at is always the heading on screen. */
.pb-bell-group {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 7px 14px 5px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--text-3);
}

/* ── A row ────────────────────────────────────────────────────────────────────
   Grid, not flex: the tile, the text and the dot are three columns, and the text
   column is the only one that may shrink — which is what keeps a 400-character
   comment body from pushing the timestamp off the end. */
.pb-bell-item {
    --h: 226;                    /* neutral indigo; each kind overrides at the foot */
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) 8px;
    align-items: start;
    gap: 11px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
    color: var(--text);
    background: var(--surface);
    transition: background .12s ease;
}
.pb-bell-item:last-child { border-bottom: 0; }
.pb-bell-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Unread rows sit on a faint accent wash — enough to group them at a glance, not
   enough to make the read ones look broken. */
.pb-bell-item.unread { background: var(--accent-soft); }

/* Hover DARKENS the ground the row already has, rather than replacing it with a fixed
   colour. Swapping in --surface-2 was the obvious version and it was wrong both ways
   round: it stripped an unread row of its tint, so pointing at the thing you care about
   made it look less important than its neighbours. A translucent overlay is the same
   gesture on both states, and on the red and amber ones the tone rules paint. */
.pb-bell-item:hover { background-image: linear-gradient(rgba(18, 21, 28, .045), rgba(18, 21, 28, .045)); }
.pb-shell.pb-dark .pb-bell-item:hover { background-image: linear-gradient(rgba(255, 255, 255, .055), rgba(255, 255, 255, .055)); }

/* The tile. Wash and ink both derived from --h, exactly as .pb-nico does it. */
.pb-bell-ico {
    width: 30px; height: 30px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 9px;
    background: hsl(var(--h) 78% 94%);
    color: hsl(var(--h) 55% 42%);
}
.pb-shell.pb-dark .pb-bell-ico {
    background: hsl(var(--h) 55% 62% / .16);
    color: hsl(var(--h) 70% 70%);
}

/* Urgency outranks provenance: an overdue row is red wherever it came from. These are
   named colours rather than a hue, because they are the same red and amber the toasts,
   the SLA chips and the overdue counts already use. */
.pb-bell-item.warn .pb-bell-ico { background: var(--warning-soft); color: var(--warning-text); }
.pb-bell-item.bad  .pb-bell-ico { background: var(--danger-soft);  color: var(--danger-text); }

.pb-bell-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* Title and time share a line: the time is metadata about the title, not about the row,
   and putting it on the title's baseline stops it floating beside two lines of body. */
.pb-bell-row1 { display: flex; align-items: baseline; gap: 8px; min-width: 0; }

.pb-bell-t {
    flex: 1;
    min-width: 0;
    font-size: 12.5px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--text);
    letter-spacing: -.005em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pb-bell-when {
    flex-shrink: 0;
    font-size: 10.5px;
    font-weight: 500;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

/* Two lines of detail, then clipped. The row is a pointer to the thing, not the thing. */
.pb-bell-d {
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--text-2);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* The unread dot. Its column is reserved on every row, read or not, so marking one read
   cannot re-wrap the text beside it. */
.pb-bell-dot {
    width: 7px; height: 7px;
    margin-top: 11px;
    border-radius: 50%;
    background: var(--accent);
}
.pb-bell-item.warn .pb-bell-dot { background: var(--warning); }
.pb-bell-item.bad  .pb-bell-dot { background: var(--danger); }

/* Read: the dot goes, the title stops shouting, the tile desaturates. Nothing is hidden
   and nothing is struck out — it simply stops asking. */
.pb-bell-item.read .pb-bell-dot { background: none; }
.pb-bell-item.read .pb-bell-t { font-weight: 500; color: var(--text-2); }
.pb-bell-item.read .pb-bell-d { color: var(--text-3); }
.pb-bell-item.read .pb-bell-ico { opacity: .55; }

/* Hue per kind — the DESTINATION screen's hue, matching .pb-nav[data-key] in the rail.
   Two kinds that open the same screen share a hue on purpose; their glyphs differ. */
.pb-bell-item[data-kind="issue_assigned"]  { --h: 352; }  /* Bug Tracking — rose */
.pb-bell-item[data-kind="issue_comment"]   { --h: 352; }
.pb-bell-item[data-kind="issue_due"]       { --h: 352; }
.pb-bell-item[data-kind="ticket_message"]  { --h: 22;  }  /* Tickets — orange */
.pb-bell-item[data-kind="ai_draft"]        { --h: 22;  }
.pb-bell-item[data-kind="deliverable_due"] { --h: 152; }  /* Projects — green */

/* ── Empty, error and loading ─────────────────────────────────────────────── */
.pb-bell-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 34px 26px 36px;
    text-align: center;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--text-3);
}
.pb-bell-empty strong { color: var(--text); font-size: 12.5px; font-weight: 650; }

.pb-bell-empty-ico {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px;
    margin-bottom: 2px;
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--text-3);
}
.pb-bell-empty.bad .pb-bell-empty-ico { background: var(--danger-soft); color: var(--danger-text); }
.pb-bell-empty.bad strong { color: var(--danger-text); }

/* Ghost rows in the shape of the real ones, so the panel opens at its final size and
   the rows land in place instead of a word that resizes the whole thing a moment later. */
.pb-bell-skel { padding: 4px 0; }
.pb-bell-skel-row {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 11px;
    padding: 11px 14px;
}
.pb-bell-skel-ico, .pb-bell-skel-lines > span {
    background: var(--surface-2);
    border-radius: 6px;
    animation: pb-bell-pulse 1.3s ease-in-out infinite;
}
.pb-bell-skel-ico { width: 30px; height: 30px; border-radius: 9px; }
.pb-bell-skel-lines { display: flex; flex-direction: column; gap: 7px; padding-top: 3px; }
.pb-bell-skel-lines .a { height: 9px; width: 62%; }
.pb-bell-skel-lines .b { height: 9px; width: 88%; animation-delay: .15s; }

@keyframes pb-bell-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.pb-bell-foot {
    padding: 9px 14px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 10.5px;
    color: var(--text-3);
    text-align: center;
}

/* Said to a screen reader, not shown: the unread state and the link target, which the
   dot and the status bar carry for everyone else. */
.pb-bell-sr {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    .pb-bell-panel { animation: none; }
    .pb-bell-item, .pb-bell-mark { transition: none; }
    .pb-bell-skel-ico, .pb-bell-skel-lines > span { animation: none; }
}

/* Primary CTA button */
.pb-btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 14px;
    background: #4361ee;
    color: #ffffff;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
    letter-spacing: -0.01em;
    transition: background 0.12s ease, box-shadow 0.12s ease;
    box-shadow: 0 1px 2px rgba(67,97,238,.30), 0 2px 8px rgba(67,97,238,.16);
}
.pb-btn-primary:hover {
    background: #3a54d4;
    box-shadow: 0 2px 4px rgba(58,84,212,.35), 0 4px 14px rgba(58,84,212,.22);
}

.pb-content { flex: 1; min-width: 0; }

@media (prefers-reduced-motion: reduce) {
    .pb-nav, .pb-back, .pb-iconbtn, .pb-nico, .pb-side-out, .pb-btn-primary { transition: none; }
    .pb-online .d { animation: none; }
}
