/* Flashcord Beta (2024) -> Peakcord's 2026 client.
 *
 * Loaded after flashcord.css. Everything here is a fix for something the client
 * changed after Beta was written; nothing here is taste. Each block says what
 * broke and why.
 */

/* ---------------------------------------------------------------------------
 * 1. Restore the sidebar subgrid.
 *
 * The 2026 shell lays the whole app out on one grid: `base_` owns the tracks
 * ([start] 72px [guildsEnd] 303px [channelsEnd] ...) and `content_` and
 * `sidebar_` are `subgrid`, so the guild rail and channel list are placed by
 * named line rather than by source order.
 *
 * Beta's "ChannelNav_Compact Core" puts `container-type: inline-size` on
 * `content_ > sidebar_`. That applies layout containment, and a contained box
 * cannot be a subgrid — `grid-template-rows/columns` collapse from `subgrid` to
 * `none`, the named areas stop resolving, and the rail and channel list drop
 * into auto rows at the bottom of the sidebar. That is the whole "everything is
 * squashed into the bottom-left" failure.
 *
 * The query itself is still wanted, so it moves to `sidebarList_`, a plain flex
 * child that carries no grid placement. Every FC-ChannelNav_Compact rule targets
 * descendants of the channel list, so they all still match.
 * ------------------------------------------------------------------------- */
[class^="content_"] > [class^="sidebar_"] {
  container-type: normal;
  container-name: none;
}

[class*="sidebarList_"] {
  container-name: var(--FlashCore-ChannelNav_Compact, FC-ChannelNav_Compact);
  container-type: inline-size;
}

/* ---------------------------------------------------------------------------
 * 2. Un-pin the Chat Slide hover targets.
 *
 * Chat Slide is Beta's signature: the chat is translated left under the sidebar
 * and slides back when the sidebar or guild rail is hovered, so the chat gets
 * the full window. The slide-out rule is hash-agnostic, but the slide-back is
 * pinned to two 2024 build hashes — `.chat_a7d72e` and `.sidebar_a4d4d9`, both
 * marked with the author's own `[!]` — which no longer exist. The chat therefore
 * slid left and never came back, clipping every avatar and username behind the
 * sidebar.
 * ------------------------------------------------------------------------- */
@container FCM-Chat-Slide_SNDL (min-width: 0) {
  /* One variable drives the whole effect so the slide and the compensating
     padding can never disagree. */
  [class^="chat_"]:not(:has([class^="pageBody_"])) {
    --fc-slide: 198px;
    translate: calc(0px - var(--fc-slide));
    /* Beta slid the chat under the sidebar and let it eat the gutter, because
       2024's message list carried ~200px of empty margin on the left. The 2026
       list does not, so the same slide swallowed every avatar and username.
       Padding the chat by the slide distance keeps the effect — the chat surface
       still runs under the sidebar — while the content stays where it was. */
    padding-left: var(--fc-slide);
    transition-property: translate, padding-left;
  }

  :is([class^="container_"]:has([class*="sidebar_"]:hover, [data-list-id="guildsnav"]:hover)) [class^="chat_"] {
    --fc-slide: 0px;
  }
}

@container FCM-Chat-Slide_Legacy (min-width: 0) {
  :is([class*="baseLayer_"]:has([class*="guilds_"]:hover, [class^="sidebar_"]:hover)) [class^="sidebar_"] {
    width: 240px;
  }
}

/* ---------------------------------------------------------------------------
 * 3. Give the advanced themes' overlay a box to act on.
 *
 * Iridescent paints itself with `[theme-hooker="..."]::after`, setting only a
 * backdrop-filter and an animation. Everything that makes a pseudo-element
 * exist — content, position, size — came from the 2024 client's own root
 * decoration, which the 2026 shell does not have, so `content` stayed `none`
 * and the pseudo was never generated.
 *
 * z-index is the load-bearing part. The overlay sits BEHIND the app, not over
 * it: Iridescent makes every app background transparent and puts an animated
 * wave on <html>, so a backdrop-filter behind the content frosts that wave and
 * leaves text crisp. Painted on top it would blur the messages too, which is
 * not "eye candy", it is unreadable.
 * ------------------------------------------------------------------------- */
html[theme-hooker^="theme-"]::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* The wave is `background-repeat: repeat-x` on <html>, which scrolls with the
   root box; fixed attachment keeps it still under a scrolling message list. */
html[theme-hooker^="theme-"] {
  background-attachment: fixed;
}

/* ---------------------------------------------------------------------------
 * 4. Extend the advanced themes' transparency to the 2026 colour tokens.
 *
 * Every advanced theme works by blanking Discord's background variables so the
 * theme's own image shows through. Beta blanks the 2024 family — the twenty-odd
 * `--background-primary/secondary/tertiary` and `--bg-overlay-*` names. The 2026
 * client no longer paints from any of them: the app frame, the chat and every
 * panel come from `--background-base-*` and `--background-surface-*`, which Beta
 * has never heard of.
 *
 * So the themes were doing their job perfectly and blanking variables nothing
 * reads, while the real surfaces stayed opaque and covered the wave. Both
 * families are set here, from the same selectors, to the same values Beta chose.
 * ------------------------------------------------------------------------- */

/* See-through themes: Iridescent, Transparent, and both Custom Background modes.
   `--background-floating` stays opaque — it is the popout and context-menu
   surface, and a transparent menu over a moving background is unreadable. */
[theme-hooker="theme-citrus-sherbert"],
[theme-hooker="theme-chroma-glow"],
[theme-hooker="theme-sepia"],
[theme-hooker="theme-mint-apple"],
[theme-hooker="theme-sunset"],
.theme-dark.custom-theme-background,
.theme-light.custom-theme-background {
  --background-base-low: transparent;
  --background-base-lower: transparent;
  --background-base-lowest: transparent;
  --background-surface-high: transparent;
  --background-surface-higher: transparent;
  --background-surface-highest: transparent;
  --bg-surface-raised: transparent;
  --background-modifier-hover: rgba(255, 255, 255, 0.06);
  --background-modifier-selected: rgba(255, 255, 255, 0.1);
}

/* Terminal is the opposite case: it sets the 2024 family to `black`, not to
   transparent, and wants a hard black CRT. */
[theme-hooker="theme-aurora"] {
  --background-base-low: #000;
  --background-base-lower: #000;
  --background-base-lowest: #000;
  --background-surface-high: #000;
  --background-surface-higher: #000;
  --background-surface-highest: #000;
  --bg-surface-raised: #000;
  --background-floating: #000;
}

/* `#app-mount` paints `--background-base-lowest` directly on its own box rather
   than through a token the theme can reach, so it stays opaque even once every
   variable above is blank, and it covers the whole window. */
html[theme-hooker^="theme-"] #app-mount,
html.custom-theme-background #app-mount {
  background: transparent;
}
html[theme-hooker="theme-aurora"] #app-mount {
  background: #000;
}

/* ---------------------------------------------------------------------------
 * 5. The app's background is its own element now.
 *
 * 2024 painted the window from a variable on a real content box, which is why
 * blanking `--background-primary` was enough to see through the whole client.
 * 2026 paints it from a dedicated sibling of the layer stack — `app_ > bg_` —
 * whose colour is set on the element, not through any token a theme can reach.
 *
 * With every variable in section 4 already blank, this one div was the entire
 * remaining reason Iridescent, Transparent and Custom Background looked like
 * stock dark mode: the wave rendered correctly and was covered by one opaque
 * rectangle spanning the window.
 *
 * (Its computed value reads as `oklab(...)`, not `rgb(...)`, which is worth
 * knowing when hunting the next one of these.)
 * ------------------------------------------------------------------------- */
html[theme-hooker^="theme-"] [class^="app_"] > [class^="bg_"],
html.custom-theme-background [class^="app_"] > [class^="bg_"] {
  background: transparent !important;
}
html[theme-hooker="theme-aurora"] [class^="app_"] > [class^="bg_"] {
  background: #000 !important;
}

/* ---------------------------------------------------------------------------
 * 6. The Beta notice, back beside the channel name.
 *
 * Flashcord prints its version warning from
 * `chat_ title_ children_::after`. In 2024 `children_` was a small box holding
 * the channel name, so the notice sat right after it. 2026 makes `children_`
 * the whole flexible span between the name and the toolbar, so the generated
 * box is free to centre itself in ~850px of empty header — which is why the
 * notice floated into the middle of the toolbar and covered the buttons.
 *
 * `margin-right: auto` gives the ::after the leftover space instead of letting
 * it share it, which packs it against the channel name.
 * ------------------------------------------------------------------------- */
[class^="chat_"] [class^="title_"] [class^="children_"]::after {
  margin-right: auto;
  flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
 * 7. Horizontal guild rail: put it back at the top of the window.
 *
 * The horizontal rail — Terminal Mode's default, and a choice in the panel —
 * rotates the server nav 90° and absolutely positions it, relying on its
 * containing block being the app root. 2026 makes `content_ > sidebar_`
 * `position: relative`, so the rail is now positioned against the sidebar and
 * lands 48px down, on top of the server-name header instead of above it.
 *
 * The module already reserves the space it needs (`base_` gets `margin-top:
 * 48px`); the rail just has to be lifted into it, so the offset is written as
 * the same 48px rather than as a measured constant.
 * ------------------------------------------------------------------------- */
@container FC-GuildNav_Compact-Horizontal (min-width: 0px) {
  /* Fixed, not absolute — the only change this variant actually needed.
   *
   * Beta lays the rail down by rotating the whole scroller -90° about its
   * right-top corner, which is what keeps Discord's virtualised list working:
   * the items are still positioned along one axis by transform, and the axis
   * is simply turned. Laying them out as a real flex row instead does not work
   * here, because the list is virtualised — every item is absolutely placed and
   * a row direction leaves them stacked off-screen.
   *
   * What broke in 2026 is only where the rotated box lands. `position:
   * absolute` resolves against `content_ > sidebar_`, which is now
   * `position: relative` and clips its overflow, as does `base_` — so the strip
   * was positioned 48px too low and then cut away entirely. Fixed positioning
   * resolves against the viewport, and no ancestor carries a transform, filter
   * or containment, so nothing captures it and nothing clips it.
   *
   * `top` is the 32px title bar; the 48px the strip occupies is the same 48px
   * the module already reserves with `margin-top` on `base_`.
   */
  nav[class^="wrapper_"] {
    position: fixed;
    top: 32px;
    left: -48px;
    width: 48px;
    height: auto;
  }
  /* Rotated, the scroller's height becomes the strip's length. */
  nav[class^="wrapper_"] [class^="scroller_"],
  nav[class^="wrapper_"] [class^="tree_"] {
    height: 100vw !important;
    width: 48px;
    overflow: visible;
  }
  /* Discord draws the selected-server pill on the left edge, which is the top
     edge once the rail is turned. */
  [class^="listItem_"] [class^="pill_"] { display: none; }
}

/* The notice is also absolutely positioned by the client's own header rules,
   so it parks at its static position — several hundred pixels into the
   flexible span — regardless of margins. Putting it back in flow is what makes
   `margin-right: auto` above mean anything. */
[class^="chat_"] [class^="title_"] [class^="children_"]::after {
  position: static;
  margin: auto auto auto 8px;
}

/* ---------------------------------------------------------------------------
 * 8. Transparent Mode needs something to be transparent to.
 *
 * Transparent Mode blanks every surface and puts
 * `backdrop-filter: blur(16px) brightness(0.5)` on #app-mount. On the desktop
 * client that samples the window behind Discord, which is the whole idea. In a
 * browser tab there is nothing behind the page, so the filter samples an empty
 * backdrop and resolves to flat mid-grey — the entire client rendered as one
 * grey rectangle.
 *
 * Giving the root a dark base makes the same filter produce frosted dark glass,
 * which is the closest honest reading of the mode in a tab. A custom background
 * image set in the Flashcord panel shows through it, so the mode still does
 * what it says when there is something to see.
 * ------------------------------------------------------------------------- */
html[theme-hooker="theme-sepia"] {
  background-color: #0d0d10;
  background-image: var(--Flashcord-CBM_Dark-Image, none);
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
}
