/* ============================================================
   shell_softserve.css — th11 (#521)
   ============================================================
   The "softserve" shell. Every rule in this file is scoped under
   [data-shell="softserve"] and is purely additive: the "terminal"
   shell (the default, and every anonymous render) never matches a
   single selector here.

   Load order: LAST, after CSS_CORE and the route's CSS_MANIFEST
   files. See SHELL_CSS in app/common/css_manifest.py. Source order
   only breaks ties at EQUAL specificity though, so loading last is
   necessary and not sufficient — every rule below restates the FULL
   ancestor chain of the base rule it overrides and prefixes the
   shell attribute onto it, which buys exactly one extra class of
   specificity over that base. Where a base rule is a group of three
   or six selectors, the group is mirrored selector-for-selector; a
   single collapsed `.card:hover` would lose to dashboard.css's
   `.dashboard-grid .dashboard-column-body .card.panel-clickable:hover`
   no matter how late this file loads.

   Design premise: nothing is deleted, everything is melted. Where
   nightswim removes edges and rebuilds them out of depth, softserve
   keeps the terminal identity — VT323 wordmark, phosphor accent,
   mono column labels, the blinking cursor — and softens each hard
   edge into one of
     - a wash (var(--softserve-wash)),
     - a gradient hairline (var(--softserve-hairline)),
     - a pool of light (var(--softserve-pool)),
     - or a fill that stands in for a border (var(--softserve-fill)).
   If you find yourself reaching for a 1px ring in this file, the
   answer is a pool or a hairline instead.

   Values live in tokens.css (the single-token-source rule owns
   that); this file only consumes them via var(). Note that softserve
   reassigns the base --radius-* tokens rather than declaring its own
   parallel set — see the inversion note in tokens.css for why. That
   is why there are no --softserve-radius-* references below.

   Performance note: there is no backdrop-filter and no animation in
   this shell at all. Every surface is a flat rgba fill or a static
   gradient, which is what makes it cheap enough to sit on a
   3-column dashboard without touching scroll performance.
   ============================================================ */

/* ============================================================
   Navbar
   ============================================================ */

/* The wash pools at the top edge and falls to nothing before the
   navbar's bottom, so the chrome fades into the page rather than
   ending on a line. Applied as background-image so navbar.css's
   `background: var(--color-bg-navbar)` shorthand still paints the
   base color underneath — including the two pride palettes where
   that token holds a gradient of its own.

   The navbar's edge is base.html's `border-bottom` Bootstrap
   utility, which Bootstrap compiles with !important; no rule here
   can outrank it, so --bs-border-color: transparent in tokens.css
   is what actually removes it. Same story as the post action row
   below. */
[data-shell="softserve"] .navbar {
    background-image: var(--softserve-wash);
    background-repeat: no-repeat;
}

/* ============================================================
   Dashboard columns
   ============================================================ */

/* dashboard.css draws the column frame as `2px solid
   var(--color-accent)`, straight from the accent rather than
   through a border token, so the kill-switch in tokens.css can't
   reach it. Neutralised rather than set to `none` so the 2px of
   inset geometry is preserved and nothing reflows between shells.
   The wash replaces it as the separation cue: light pools at the
   top of each column and falls away, which reads as a boundary
   without drawing one. */
[data-shell="softserve"] .dashboard-column {
    border-color: transparent;
    background-image: var(--softserve-wash);
    background-repeat: no-repeat;
}

/* ============================================================
   Dividers — gradient hairlines
   ============================================================ */

/* Every hard rule in the app becomes a 1px gradient that's solid
   across the middle and fades out at both ends, so a divider never
   terminates on a hard stop against its container's edge. The
   border itself is nulled and the line is redrawn as an absolutely
   positioned ::after — a border can only be a solid color, a
   background can be a gradient.

   Both hosts are flex/grid containers, so the ::after MUST stay
   absolutely positioned: an in-flow pseudo-element would become a
   real flex/grid item and shift the header's layout.

   The post action row is NOT in this list. It's Bootstrap's
   .border-top utility, compiled with !important, and is already
   handled by --bs-border-color: transparent in tokens.css. */
[data-shell="softserve"] .dashboard-column-header,
[data-shell="softserve"] .editorial-split {
    position: relative;
    border-bottom-color: transparent;
}

[data-shell="softserve"] .dashboard-column-header::after,
[data-shell="softserve"] .editorial-split::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: var(--softserve-hairline);
    pointer-events: none;
}

/* ============================================================
   Cards and tiles — hover becomes a pool
   ============================================================ */

/* dashboard.css's card hover is a 1px violet ring plus a 16px
   outer glow — two stacked hard-ish edges. Softserve replaces both
   with a single downward pool of light and a fill change, so the
   hovered card lifts off the column instead of being outlined on
   it. The three selectors mirror the base group exactly; the
   .drafts-list arm is the loosest at (0,3,0) and still needs the
   prefix to win. */
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .card.panel-clickable:hover,
[data-shell="softserve"] .profile-feed .card.panel-clickable:hover,
[data-shell="softserve"] .drafts-list .card:hover {
    background-color: var(--color-bg-subtle);
    border-color: transparent;
    box-shadow: var(--softserve-pool);
}

/* The Links and Media tiles carry the heavier three-layer halo
   (ring + 12px + 28px) rather than the card's two-layer one. Same
   substitution, same pool. :focus-visible is mirrored alongside
   :hover from the base groups so keyboard users don't get left on
   the old halo. */
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .links-column-tile:hover,
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .links-column-tile:focus-visible,
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .media-column-tile:hover,
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .media-column-tile:focus-visible {
    background-color: var(--color-bg-subtle);
    border-color: transparent;
    box-shadow: var(--softserve-pool);
}

/* ============================================================
   Shared post — the quoted card becomes a left rule
   ============================================================ */

/* The quoted/reposted embed keeps its "this is someone else's"
   signal, but as a single left rule rather than a filled, bordered
   inset box. The rule is an inset box-shadow, not a border, so the
   kill-switch in tokens.css can't erase it. The radius is squared
   off on the left so the rule reads as a margin bar rather than as
   the edge of a pill.

   This treatment has to be written three times because
   .shared-post-card is styled in three places:
     1. feed.css's base rule                       (0,1,0)
     2. dashboard.css's six-selector group    (0,3,0)–(0,5,0)
     3. feed.css's .compose-page-standalone variant (0,2,0)
   Collapsing them into one selector would leave 2 and 3 standing. */
[data-shell="softserve"] .shared-post-card {
    background-color: transparent;
    border-color: transparent;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    box-shadow: inset 3px 0 0 var(--softserve-rule);
}

/* dashboard.css's group also sets --bs-card-bg on these elements;
   this file can't touch custom properties, so background-color is
   asserted directly instead — it out-specifies Bootstrap's own
   `.card { background-color: var(--bs-card-bg) }` at (0,1,0)
   regardless of what the variable resolves to. */
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .card.shared-post-card,
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .shared-post-card,
[data-shell="softserve"] .profile-feed .card.shared-post-card,
[data-shell="softserve"] .profile-feed .shared-post-card,
[data-shell="softserve"] .drafts-list .card.shared-post-card,
[data-shell="softserve"] .drafts-list .shared-post-card {
    background-color: transparent;
    border-color: transparent;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    box-shadow: inset 3px 0 0 var(--softserve-rule);
}

/* share_post.html's copy is the only one that draws a real
   `border:` shorthand rather than relying on Bootstrap's, so
   border-color has to be nulled here specifically. */
[data-shell="softserve"] .compose-page-standalone .shared-post-card {
    background-color: transparent;
    border-color: transparent;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    box-shadow: inset 3px 0 0 var(--softserve-rule);
}

/* ============================================================
   Border-only containers
   ============================================================ */

/* Containers whose ONLY visual boundary was a border. With the
   token kill-switch in tokens.css a transparent background plus a
   transparent border is nothing at all — a poll option would read
   as loose text, a linktree row as a floating label, a pill as a
   bare icon. Each trades the border for the fill it used to imply.
   If you add another border-only container, it belongs in this
   list. */
[data-shell="softserve"] .profile-pill-btn,
[data-shell="softserve"] .freespace-linktree-link,
[data-shell="softserve"] .link-preview,
[data-shell="softserve"] .poll-card-option,
[data-shell="softserve"] .links-column-tile,
[data-shell="softserve"] .freespace-link-card {
    background-color: var(--softserve-fill);
}

/* Inside a dashboard column the Links tile is repainted transparent
   by dashboard.css at (0,3,0), which outranks the (0,2,0) group
   above — so the fill has to be restated on the scoped selector or
   the tile stays invisible exactly where it's actually rendered. */
[data-shell="softserve"] .dashboard-grid .dashboard-column-body .links-column-tile {
    background-color: var(--softserve-fill);
}

/* Hover on a filled container is the same fill at a higher alpha
   rather than a new edge. .freespace-link-card is in this group
   because its base hover tint sits at (0,2,0), the same specificity
   as the rest-state rule above — without a hover rule of its own
   the later-loading rest state would flatten it. */
[data-shell="softserve"] .profile-pill-btn:hover,
[data-shell="softserve"] .profile-pill-btn:focus-visible,
[data-shell="softserve"] .freespace-linktree-link:hover,
[data-shell="softserve"] .freespace-linktree-link:focus-visible,
[data-shell="softserve"] .freespace-link-card:hover,
[data-shell="softserve"] .freespace-link-card:focus-visible {
    background-color: rgba(var(--color-halo-rgb), 0.18);
}

/* The primary pill keeps its solid accent fill — it's the one place
   in the shell where a loud, opaque surface is the point, and
   .profile-pill-btn--primary sits at (0,1,0) in profile.css, so the
   (0,2,0) group above would otherwise swallow it and leave
   --color-text-on-accent stranded on a near-transparent chip. Equal
   specificity, later in the cascade, so this wins. */
[data-shell="softserve"] .profile-pill-btn--primary {
    background-color: var(--color-accent);
}

/* ============================================================
   Free-space cell
   ============================================================ */

/* Same story as .dashboard-column: profile.css draws this border
   from color-mix() on the accent rather than through a border
   token, so the token kill-switch misses it. Nulled explicitly; the
   cell's own background-color still separates it from the page. */
[data-shell="softserve"] .freespace-cell {
    border-color: transparent;
}

/* ============================================================
   Accessibility guards
   ============================================================ */

/* There is deliberately no prefers-reduced-motion block here —
   softserve declares no animation, no transition and no transform,
   so there is nothing for one to turn off. */

/* Users who've asked the OS to reduce transparency get a flat
   low-alpha fill instead of a gradient that fades to nothing. The
   fill is layered as a background-image rather than a
   background-color so the navbar's own --color-bg-navbar (which is
   a gradient on the pride palettes) still paints underneath. */
@media (prefers-reduced-transparency: reduce) {
    [data-shell="softserve"] .navbar,
    [data-shell="softserve"] .dashboard-column {
        background-image: linear-gradient(var(--softserve-fill), var(--softserve-fill));
    }
}
