/* Workspace dashboard shell plus the sliding "Sidefelt" (my-tasks) side-panel drawer.
   Split out of stomn_theme.css (original lines 1049-1521) — 2026-08-18,
   CSS @layer restructuring step 2 (Basecamp "Fra Fizzy-gjennomgang:
   CSS-arkitektur"). Numeric filename prefix controls load order (see
   app/helpers/application_helper.rb#stomn_theme_stylesheet_link_tag) —
   files are concatenated in this exact original order, so no cascade
   tie-break changes. */
@layer overrides {
.workspace-dashboard {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

/* Torleiv, 2026-08-19 ("rydde i ark-bredde... finn tre standardbredder"):
   every .workspace-dashboard consumer that ISN'T the narrower home page
   below (Binder, Mine dokumenter, module TOCs, Personer, Profil...) used
   to just inherit whatever .page-body's own 1040px cap left over — a
   different, accidental width from a document's own .document-focus
   (900px, --content-width), which is why Binder's ark measured visibly
   narrower than a document's despite both being "full width" pages. Same
   token as .document-focus now, :not()-scoped so this can't fight
   .workspace-home's own more specific 760px rule on cascade order. */
.workspace-dashboard:not(.workspace-home) {
    max-width: var(--content-width);
    margin: 0 auto;
    width: 100%;
}

/* A module-TOC-style front page (Mine dokumenter, any toc_roots-layout
   module) — .page-title-header already carries its own generous
   space-8 bottom padding (see its rule further down), so stacking the
   lead paragraph and the sheet below it with the SAME space-6 gap as
   every other .workspace-dashboard section compounds into much more
   dead air above the sheet than Visjon og verdier gets (single_document
   layout: .document-page-header sits directly above .document-sheet,
   no lead paragraph, no flex gap at all — just that one padding).
   Only targets pages with a .toc-sheet descendant, not the workspace home
   dashboard or other .workspace-dashboard consumers. Descendant, not
   direct-child (Torleiv, 2026-08-20, #10224015214: "flytt ark oppover,
   samme mal som andre dokument") — Binder/Mine dokumenter wrap their
   button row + sheet together in an upload-dropzone div (see
   binder/index.html.erb's own comment on why), which put .toc-sheet one
   level deeper than the module TOC's own flat structure and silently
   missed this :has() match, leaving their ark sitting lower than every
   other toc-sheet page's. %>
.workspace-dashboard:has(.toc-sheet) {
    gap: var(--space-2);
}

/* The front-page dashboard specifically (not /people, /profile, etc, which
   also use .workspace-dashboard) — narrower than the general page column,
   matching Basecamp's home. Leaves room on the sides for notifications/
   activity content later, rather than stretching the module cards edge to
   edge of the reading column. */
.workspace-home {
    max-width: 760px;
    margin: 0 auto;
    width: 100%;
}

/* "Sidefelt" (renamed from "Mine oppgaver", Torleiv 2026-08-15: "det vil
   etter hvert få annet innhold også") — a small rollup of tasks/
   compliance-checks/document approvals attached to Current.person (see
   WaitingForYouPanel), rendered once from the main layout so it's
   available on every page, not the home page alone.

   Third design for this feature, each fixing a different failure mode of
   the last:
   1. A vertically-centered floating card with a push-margin rule trying
      to keep page content out of its way — broke in a new way on every
      attempt (transform/containing-block bug, wrong reserved width, then
      a background that leaked clicks through to the page underneath).
   2. An overlay drawer covering the page instead of resizing it — no
      page-content footprint to keep in sync with, so that whole class of
      bug was gone... but it also covered the header's own search/avatar/
      toggle icons whenever open, and blocked working in the main content
      at the same time (Torleiv, 2026-08-15, screenshot: "sørg for at
      ikonene øverst... ikke skjules" / "en kan jobbe i BÅDE hovedfeltet
      og mine oppgaver-feltet").
   3. This one: .my-tasks-panel is now a plain flex item (a "spacer") in
      the new .app-shell row below, animating WIDTH (0 → 360px) instead
      of position — flexbox recalculates how much room .ui-page-layout
      gets on every frame, so there's no manual margin/width arithmetic
      to get wrong the way attempt 1's did. .my-tasks-panel__content
      itself stays position: fixed (completely unchanged from attempt 2)
      so this reuses proven, working positioning rather than risking a
      new position: sticky/relative scheme in an app with its own history
      of sticky-positioning bugs elsewhere.

   The toggle and this drawer are no longer DOM siblings under one
   wrapper — the toggle now renders inline in the page's own header
   (see that partial's own comment for why: a fixed top-right toggle
   collided with the header's existing search/user-menu icons). Their
   shared disclosure-controller instance lives on <body>
   (layouts/application.html.erb), so every :has()/state selector below
   is scoped from body rather than from a shared local wrapper. */
/* Tracks the sidefelt drawer's current reserved width purely so
   .page-header's own margin-left formula (above) can still compute the
   right offset to reach the true viewport edge — the actual push/narrow
   layout below is driven by real flexbox + .my-tasks-panel's own
   hardcoded 360px width, NOT by this variable; CSS just has no way to
   feed a computed flex width back into another element's calc(). */
:root {
    --sidebar-width: 0px;
}

body:has(.my-tasks-panel__toggle[aria-expanded="true"]) {
    --sidebar-width: 360px;
}

/* Wraps .ui-page-layout + the sidebar spacer so opening the sidebar
   narrows/shifts the main content instead of covering it. min-width: 0
   on .ui-page-layout is load-bearing — a flex item's default min-width
   is `auto` (its content's own intrinsic width), which would silently
   refuse to shrink below that and defeat this whole mechanism. */
.app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

.app-shell > .ui-page-layout {
    flex: 1 1 auto;
    min-width: 0;
}

.my-tasks-panel {
    flex-shrink: 0;
    width: 0;
    overflow: hidden;
    transition: width 0.2s ease;
    pointer-events: none;
}

body:has(.my-tasks-panel__toggle[aria-expanded="true"]) .my-tasks-panel {
    width: 360px;
}

/* disclosure_controller.js's own connect(): re-applying a REMEMBERED open
   state on every Turbo full-page visit (body is destroyed/recreated each
   time) shouldn't visibly replay the open animation — only a real user
   click (toggle()) should glide. See its own comment for why this fires
   every navigation, not just the first one. */
body.disclosure-restoring .my-tasks-panel,
body.disclosure-restoring .my-tasks-panel__content {
    transition: none;
}

/* Torleiv, 2026-08-15 ("tung og dyster... litt mer oppmuntrende og
   'lystig'"): was a solid near-black pill (--text-900) — read as a warning
   or an error count rather than an invitation. A light tint of the app's
   own accent (--signal-color-tint, already used elsewhere for the same
   "soft accent surface" role, e.g. active nav states) reads as a friendly
   nudge instead; hover inverts to the solid accent so the button still
   has a clear "pressed/active" state. */
.my-tasks-panel__toggle {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--signal-color-tint);
    color: var(--signal-color);
    border: none;
    border-radius: var(--radius-full, 999px);
    cursor: pointer;
    font-size: var(--text-size-sm);
    font-weight: 600;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
    /* Torleiv, 2026-08-18 ("Plasser Sidefelt-knappen på samme høyde som
       sidefeltet starter"): fixed at the exact same top offset
       .my-tasks-panel__content itself opens at (same two variables, same
       fallback) — not the header's own icon row (search/user menu) this
       used to sit inline among, which is a separate vertical band higher
       up. Being position: fixed takes it out of .header-actions' flex
       flow entirely, so those icons simply close the gap; nothing else
       moves to compensate. */
    position: fixed;
    top: calc(var(--page-header-height, 60px) + var(--document-header-height, 0px) + var(--space-3));
    right: var(--space-4);
    z-index: 110;
}

.my-tasks-panel__toggle:hover {
    background: var(--signal-color);
    color: #fff;
}

/* Torleiv, 2026-08-21 (#10225619214, "flytt support-ikon til nedre høyre
   hjørne") — a plain .ui-button.solid.circle already looks right, this
   only needs to pin it to the corner. Rendered from layouts/application.html.erb
   as a sibling of .ui-page-layout, same reasoning as .my-tasks-panel__toggle
   above (a real position: fixed viewport corner, not one of the
   transformed ancestors further up the tree). z-index above the
   my-tasks-panel toggle/drawer (110) since both can be visible on screen
   at once and this one sits physically underneath it on desktop widths. */
.support-button {
    position: fixed;
    bottom: var(--space-4);
    right: var(--space-4);
    z-index: 120;
}

/* Torleiv, same message ("knappen skjules når sidefelt åpnes -- erstattes
   av X"): the drawer's own close button (.my-tasks-panel__close, in its
   content-header) takes over once open — showing both at once reads as
   two separate controls for the same thing sitting right next to each
   other. */
.my-tasks-panel__toggle[aria-expanded="true"] {
    display: none;
}

/* Torleiv's overnight design-refresh pass, 2026-08-19: on a narrow phone
   viewport, page content runs edge-to-edge (no wide margin for this fixed
   top-right button to float into the way it does on desktop — see the
   button's own position: fixed comment above), so its full "N oppgaver
   til deg" / "Sidefelt" label sat directly on top of page titles like
   /people's "Personer" heading, right where a reader's eye lands first.
   Below the same 640px breakpoint the sidebar-push logic already uses,
   drop to an icon-only circle — small enough that even a long page title
   only grazes its far corner instead of disappearing under it.

   Torleiv, 2026-08-20 (#10224391544, "Oppgaver til deg må ikke legge seg
   oppå arket"): the same collision also happens well above phone width —
   confirmed live that .page-frame's centered content (max-width: 1300px)
   and this fixed-right toggle have no reserved gap between them, so on a
   medium desktop viewport (measured: overlap by ~1250px wide, clear by
   ~1620px) the toggle sits directly on top of a scrolled-up card's own
   top-right corner ("arket") the moment the two cross paths vertically.
   1400px is comfortably above the measured collision range with margin
   to spare — raised straight to that instead of adding a second,
   separate breakpoint with the exact same rules underneath it. */
@media (max-width: 1400px) {
    .my-tasks-panel__toggle {
        padding: var(--space-2);
        border-radius: 50%;
    }

    .my-tasks-panel__toggle-label,
    .my-tasks-panel__toggle .header-shortcut-hint {
        display: none;
    }
}

/* Torleiv, 2026-08-19 ("sidefelt-knapp... må tydelig vise når det er noe
   som må følges opp"): the icon-only mobile toggle above reads identically
   whether there's something pending or not, once its text label is gone —
   this small dot is the pending-count signal that survives at every
   width. Anchored to the icon wrapper, not the button itself, so it stays
   glued to the icon's own corner regardless of how much label text sits
   next to it above 640px. */
.my-tasks-panel__toggle-icon {
    position: relative;
    display: inline-flex;
}

.my-tasks-panel__toggle-badge {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--signal-color);
    border: 1.5px solid var(--card-bg, #fff);
}

/* A full-height drawer sliding in from the right edge, always occupying
   the exact same viewport-relative position regardless of scroll —
   position: fixed here is unchanged from the earlier overlay design (see
   the big comment above); only .my-tasks-panel's own width, and thus how
   much room .ui-page-layout has left, is new. translateX (not
   display:none) so the slide transition actually has something to
   animate; [hidden] from disclosure_controller.js still fully removes it
   from the a11y tree and click-through when collapsed. No backdrop
   anymore — the main content stays visible and interactive while this is
   open (that's the whole point of pushing instead of overlaying), so
   there's no "outside" left to catch a close-click on; closing happens
   via the toggle or the X button only. */
.my-tasks-panel__content {
    display: flex;
    flex-direction: column;
    position: fixed;
    /* top: the header's own REAL measured height (--page-header-height,
       set live by sticky_offset_controller.js — same variable the
       document TOC sidebar and others already position against), not 0 —
       the header is "frozen" and always paints above this drawer (see
       its own z-index comment), so starting this drawer at the true
       viewport top would just hide its own title/close-button row
       underneath the header. Falls back to 60px (sand_ui's own
       .page-header min-height) if the controller hasn't measured yet.
       Torleiv, 2026-08-17 ("Begrens sidefelt til samme høyde som
       dokument", screenshot): on a document page there's a second sticky
       bar below the global header (.document-page-actions), so the
       drawer's own close button sat visibly higher than where the
       document's real content actually starts. --document-header-height
       is already published for exactly that bar (document_header_height_
       controller.js) and correctly falls back to 0px on any page that
       never sets it — a genuinely optional second offset, not a
       document-specific special case bolted on here. */
    inset: calc(var(--page-header-height, 60px) + var(--document-header-height, 0px)) 0 0 auto;
    width: 360px;
    max-width: 100vw;
    pointer-events: auto;
    background: var(--card-bg, #fff);
    border-left: var(--card-border);
    box-shadow: -8px 0 24px rgba(28, 25, 20, 0.12);
    padding: var(--space-4);
    overflow-y: auto;
    /* Without this, wheel-scrolling to the top/bottom of the drawer's own
       list chains straight through to the page behind it (the browser's
       default scroll-chaining) — the page then visibly scrolls even
       though the mouse never left the drawer. */
    overscroll-behavior: contain;
    transform: translateX(100%);
    transition: transform 0.2s ease;
    /* Below .page-header's own z-index: 120 — the header is deliberately
       "frozen" (see .page-header's own comment: always full viewport
       width, never shrinks for this drawer), so it overlaps this drawer's
       top edge whenever the drawer is open. The header needs to win that
       overlap, not this. */
    z-index: 110;
}

body:has(.my-tasks-panel__toggle[aria-expanded="true"]) .my-tasks-panel__content {
    transform: translateX(0);
}

/* Push-to-narrow only makes sense where there's room to narrow into — a
   360px sidebar on a 375px phone leaves a near-invisible sliver of main
   content (the exact "mobile crash" class of bug this feature already
   had once, see WaitingForYouPanel's own mobile fix). Below this
   breakpoint, the spacer simply never grows past 0, so .app-shell's flex
   math has nothing to react to, and the drawer instead covers the full
   screen as a plain overlay — same as it always has on mobile. */
@media (max-width: 640px) {
    body:has(.my-tasks-panel__toggle[aria-expanded="true"]) {
        --sidebar-width: 0px;
    }

    body:has(.my-tasks-panel__toggle[aria-expanded="true"]) .my-tasks-panel {
        width: 0;
    }

    .my-tasks-panel__content {
        width: 100vw;
    }
}

.my-tasks-panel__content-header {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
}

.my-tasks-panel__close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    color: inherit;
    cursor: pointer;
}

.my-tasks-panel__close:hover {
    background: rgba(28, 25, 20, 0.06);
}

.my-tasks__list {
    list-style: none;
    margin: var(--space-3) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* /waiting-for-you groups each module's rows in a card, same shape as
   .people-list's single-box/bottom-border-per-row pattern — the list
   itself is also used bare (no box) inside the global panel above, so
   the box lives on this wrapper instead of on .my-tasks__list. */
.my-tasks-overview__box {
    padding: var(--space-3);
}

.my-tasks-overview__box .my-tasks__list {
    margin-top: 0;
}

/* Torleiv, 2026-08-14 ("Mine oppgaver" redesign): "Nokså ren tekst" — one
   plain-text line per row (see waiting_for_you_label) instead of the old
   icon + title + separate action-badge, plus a real inline checkbox
   ("mulighet for å fullføre på direkten") wherever a row can actually be
   finished without the read+confirm approval dialog (see
   waiting_for_you_directly_completable? — a :document item, or an
   approval-gated :task, always link through to their own page instead). */
.my-tasks__row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) 0;
    margin: 0 calc(var(--space-2) * -1);
    padding-left: var(--space-2);
    padding-right: var(--space-2);
    border-radius: var(--radius-md);
    transition: background 0.15s ease;
}

.my-tasks__row:hover {
    background: rgba(28, 25, 20, 0.05);
}

.my-tasks__checkbox-form {
    display: flex;
    flex-shrink: 0;
}

/* Keeps every row's text aligned to the same left edge whether or not it
   has a real checkbox (a :document item never does — see above) — an
   empty same-sized box instead of the text simply shifting left. */
.my-tasks__checkbox-placeholder {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
}

.my-tasks__link {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
    color: inherit;
    text-decoration: none;
}

.my-tasks__label {
    font-size: var(--text-size-sm);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.my-tasks__link:hover .my-tasks__label {
    text-decoration: underline;
}

.my-tasks__meta {
    font-size: var(--text-size-xs);
    color: rgba(28, 25, 20, 0.5);
}

/* Same signal as .compliance-overview's own overdue styling — a positive
   urgency_days (waiting_for_you_overdue?) means the date shown is in the
   past, not upcoming. */
.my-tasks__meta--overdue {
    color: var(--danger-color);
    font-weight: 500;
}

/* Torleiv, 2026-08-16 ("Ikke vis Alle oppgaver når det ikke finnes noen...
   Finn noen festlige sitater om compliance-arbeid... og tegn en enkel
   strektegning"): fills the same vertical space the list+links would
   have taken (flex: 1 on .my-tasks-panel__content's own column), rather
   than sitting as a short line under the header — one of a rotating
   pool of real, credited quotes (see WaitingForYouEmptyState) picked
   fresh each render, not a single fixed message. */
.my-tasks-panel__empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    padding: var(--space-4);
    text-align: center;
}

.my-tasks-panel__empty-icon {
    width: 64px;
    height: 64px;
    color: rgba(28, 25, 20, 0.35);
}

/* QuotesController#index — the same single-stroke icons as the Sidefelt
   empty state, shown much smaller in a settings list row. */
.quotes-list__icon {
    flex: 0 0 auto;
    display: flex;
}

.quotes-list__icon svg {
    width: 32px;
    height: 32px;
    color: rgba(28, 25, 20, 0.45);
}

.my-tasks-panel__empty-quote {
    margin: 0;
    font-size: var(--text-size-base);
    line-height: 1.5;
    color: rgba(28, 25, 20, 0.7);
    max-width: 26ch;
}

.my-tasks-panel__empty-author {
    margin: 0;
    font-size: var(--text-size-sm);
    font-style: normal;
    color: rgba(28, 25, 20, 0.45);
}

/* Torleiv, 2026-08-16 ("Sidefeltet (generelt)"): the quote text and the
   author's name link out to Wikipedia — underline only appears on
   hover, so the panel reads as plain text at rest rather than looking
   like a form full of links. */
.my-tasks-panel__empty-quote a,
.my-tasks-panel__empty-author a {
    color: inherit;
    text-decoration: none;
}

.my-tasks-panel__empty-quote a:hover,
.my-tasks-panel__empty-author a:hover {
    text-decoration: underline;
}

.my-tasks-panel__links {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--card-border);
}

/* Hidden until the row is hovered/focused, same hover-only editing-affordance
   convention as the other corner gears/menus in the app (see
   .workspace-shortcut__menu, people-role-menu) — a postpone control on every
   row all the time would be more visual noise than the highlight it's
   attached to. */
.my-tasks__postpone {
    position: relative;
    flex-shrink: 0;
}

.my-tasks__postpone-trigger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: rgba(28, 25, 20, 0.4);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s ease, background 0.15s ease;
}

.my-tasks__row:hover .my-tasks__postpone-trigger,
.my-tasks__postpone-trigger:focus-visible {
    opacity: 1;
}

.my-tasks__postpone-trigger:hover {
    background: rgba(28, 25, 20, 0.08);
}

.my-tasks__postpone-panel {
    min-width: 140px;
}

/* Oppgaver's "Modulvis"/"Etter dato" toggle (task_lists/index.html.erb,
   2026-08-20) — two plain ui-button links, just needs a gap between them. */
.task-lists-view-toggle {
    display: flex;
    gap: var(--space-2, 0.5rem);
}


} /* @layer overrides */
