/* ==========================================================================
   IRONITT v2 — shell (v3 layout)
   --------------------------------------------------------------------------
   Desktop (>768px): four columns on one grid —
     [rail] [chats, collapsible] [main] [side: Home and Profile only]
   (Communication needs the width; Iron Center carries its own IRON/AURA
   strip and streak, so the side column would only repeat them.)
   The rail is .nav-island-wrapper: logo, the tabs, the user's nests, the
   chats toggle and the profile button. Phones: the tabs become a floating
   island at the bottom edge and every rail-only piece hides.

   JS contracts kept (do not rename):
   - .nav-indicator is sized once along the dock's axis and aimed with
     transform by nav-indicator.js (WAAPI for the liquid hop, so no CSS
     transform transition); .nav-pill-moving is set while it travels.
   - js/shell.js: #app[data-tab], #app[data-dir], #app.chats-collapsed.
   - .comm-sub-tabs.visible, .nav-tab.active.nav-tab--back, html.kb-open.
   ========================================================================== */

/* The column widths and the slide offsets change on every tab switch.
   Registered as non-inheriting, a change restyles only the element that
   uses them — as plain custom properties set on #app they were inherited by
   every element on the page, so each switch recalculated the style of the
   whole document (~45ms). */
@property --chats-w { syntax: '<length>'; inherits: false; initial-value: 280px; }
@property --side-w { syntax: '<length>'; inherits: false; initial-value: 300px; }
@property --view-x { syntax: '<length-percentage>'; inherits: false; initial-value: 0px; }
@property --view-y { syntax: '<length-percentage>'; inherits: false; initial-value: 0px; }

:root {
  --rail-w: 72px;
  --chats-col: 280px;      /* the columns' content widths (constant) */
  --side-col: 300px;
}

/* ---- Tabs (both layouts) ---------------------------------------------- */
.nav-tab,
.comm-sub-tab {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 38px;
  padding: 0 16px;
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  transition: color var(--transition-fast), background-color var(--transition-fast);
}
.nav-tab i, .comm-sub-tab i { font-size: var(--font-size-sub); }
.nav-tab .iron-diamond { width: 16px; height: 16px; vertical-align: 0; }

.nav-tab:not(.active):hover,
.comm-sub-tab:not(.active):hover {
  color: var(--text-primary);
  background-color: var(--border-color);
}
/* While the pill is travelling it is the only highlight on the dock. */
.ironhub-nav-layer.nav-pill-moving .nav-tab:not(.active):hover {
  background-color: transparent;
  transition: color var(--transition-fast);   /* cut, not faded, under the pill */
}

.nav-tab.active,
.comm-sub-tab.active {
  color: var(--text-primary);
  font-weight: var(--font-weight-semibold);
  cursor: default;
  pointer-events: none;
}
.nav-tab.active i,
.nav-tab.active .iron-diamond,
.comm-sub-tab.active i { color: var(--accent-color); }
.nav-tab:focus-visible { z-index: 3; }

.nav-tab .nav-tab-back { display: none; }
.nav-tab .nav-tab-badge { position: absolute; top: 2px; right: 2px; }

/* The dock is chrome: tapping or long-pressing a tab never selects its
   label or opens the touch callout. */
.nav-island-wrapper {
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.ironhub-nav-layer {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  touch-action: manipulation;
}

/* ---- The pill ---------------------------------------------------------- */
.nav-indicator {
  /* Three pieces, each moved by transform only (js/nav-indicator.js): two
     round caps and the straight middle between their centres, drawn as a
     ring layer behind and a fill layer 1px inside it. Opaque colours (the
     tint mixed into the surface behind) so overlaps never show as darker
     patches. */
  --pill-surface: var(--bg-primary);
  --pill-fill: color-mix(in srgb, var(--accent-color) 13%, var(--pill-surface));
  --pill-ring: color-mix(in srgb, var(--accent-color) 38%, var(--pill-surface));
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  transition: opacity var(--transition-fast);
}
.nav-pill-cap,
.nav-pill-mid {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  will-change: transform;
  backface-visibility: hidden;
}
.nav-pill-ring { background: var(--pill-ring); }
.nav-pill-fill { z-index: 1; background: var(--pill-fill); }
.nav-pill-cap {
  width: var(--pill-thick, 44px);
  height: var(--pill-thick, 44px);
  border-radius: 50%;
}
/* The fill layer sits 1px inside the ring layer; margins, not transforms,
   so both layers take the same keyframes. */
.nav-pill-cap.nav-pill-fill {
  width: calc(var(--pill-thick, 44px) - 2px);
  height: calc(var(--pill-thick, 44px) - 2px);
  margin: 1px;
}
.nav-pill-mid {
  /* Laid out 100px long (NavIndicator._MID_BASE) and scaled to fit. */
  width: var(--pill-thick, 44px);
  height: 100px;
}
.nav-pill-mid.nav-pill-fill { width: calc(var(--pill-thick, 44px) - 2px); margin-left: 1px; }

.comm-sub-indicator {
  position: absolute;
  top: 4px;
  left: 0;
  height: calc(100% - 8px);
  border-radius: var(--radius-pill);
  background: var(--bg-hover);
  will-change: transform, width;
  transition: transform var(--island-slide) var(--ease-glide),
              width var(--island-slide) var(--ease-glide),
              opacity var(--island-fade) var(--island-ease);
}

/* ---- View transition --------------------------------------------------- */
/* On a tab switch the two pages pass each other: the outgoing view slides
   out (app.js keeps it as .view-leaving, pinned where it was) while the new
   one slides in from the side its tab sits on — down the rail on desktop,
   across the island on phones — shrinking to 96% in flight. data-dir comes
   from the tab order (app.js). No fill on the incoming view: a transform
   left on it would become the containing block of every fixed panel inside.
   Without a direction (boot) the view only fades in. */
.view.active { animation: v2-view-fade-in var(--view-fade) ease; }
#app[data-dir] .view.active {
  animation: v2-view-in var(--view-move) var(--ease-glide),
             v2-view-fade-in var(--view-fade) ease;
}
#app[data-dir] .view.view-leaving {
  display: block;
  position: absolute;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  animation: v2-view-out var(--view-move) var(--ease-glide) forwards,
             v2-view-fade-out var(--view-fade) ease forwards;
}
#app[data-dir="fwd"] :is(.view, .comm-bar) { --view-x: 0px; --view-y: 100%; }
#app[data-dir="back"] :is(.view, .comm-bar) { --view-x: 0px; --view-y: -100%; }
@keyframes v2-view-in {
  from { transform: translate3d(var(--view-x), var(--view-y), 0) scale(0.96); }
}
@keyframes v2-view-out {
  to { transform: translate3d(calc(var(--view-x) * -1), calc(var(--view-y) * -1), 0) scale(0.96); }
}
@keyframes v2-view-fade-in { from { opacity: 0; } }
@keyframes v2-view-fade-out { to { opacity: 0; } }

/* ---- Communication sections (above the view on that tab) -------------- */
.comm-bar { display: none; }
.comm-sub-tabs {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  user-select: none;
  -webkit-user-select: none;
}

/* ---- Shared shell pieces ---------------------------------------------- */
/* Eyebrow: the small uppercase section title with a 3px colour mark.
   --mark: gold (earnings), accent (people), warning (streak). */
.v2-eyebrow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: var(--font-size-2xs);
  line-height: 16px;
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.v2-eyebrow::before {
  content: '';
  flex: none;
  width: 3px;
  height: 12px;
  border-radius: 2px;
  background: var(--mark, var(--accent-color));
}
.v2-eyebrow--earn { --mark: var(--iron-gold); }
.v2-eyebrow--social { --mark: var(--accent-color); }
.v2-eyebrow--streak { --mark: var(--color-warning); }
.v2-eyebrow--aura { --mark: var(--aura-core); }
.light-mode .v2-eyebrow--earn { --mark: var(--iron-gold-deep); }
.light-mode .v2-eyebrow--aura { --mark: var(--aura-deep); }

/* Person avatar: a pale identity tint and the initial in the hue. */
.v2-person {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-round);
  background: color-mix(in srgb, var(--hue, var(--person-1)) 14%, transparent);
  color: var(--hue, var(--person-1));
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
}
.v2-person img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.v2-person .status-dot {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 11px;
  height: 11px;
  border: 2px solid var(--bg-primary);
}
.v2-person--sm { width: 28px; height: 28px; font-size: var(--font-size-xs); }
.v2-person--sm .status-dot { width: 9px; height: 9px; }
.v2-hue-1 { --hue: var(--person-1); }
.v2-hue-2 { --hue: var(--person-2); }
.v2-hue-3 { --hue: var(--person-3); }
.v2-hue-4 { --hue: var(--person-4); }
.v2-hue-5 { --hue: var(--person-5); }
.v2-hue-6 { --hue: var(--person-6); }

/* Buttons: green with dark text, a quiet grey second option. No white. */
.v2-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 18px;
  border-radius: var(--radius-pill);
  background: var(--accent-color);
  color: var(--accent-text);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  transition: background-color var(--transition-fast), transform var(--transition-fast);
}
.v2-btn:hover { background: var(--accent-hover); }
.v2-btn:active { transform: scale(0.97); }
.v2-btn--quiet { background: var(--bg-tertiary); color: var(--text-primary); }
.v2-btn--quiet:hover { background: var(--bg-hover); }
.v2-btn--sm { height: 32px; padding: 0 14px; font-size: var(--font-size-sm); }


/* Settings that only mean something on one layout are not shown on the
   other (a control that does nothing there is removed, not disabled). */
@media (min-width: 769px) { .v2-phone-only { display: none !important; } }
@media (max-width: 768px) { .v2-desktop-only { display: none !important; } }

.v2-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 20px;
}

/* ---- Chats column ------------------------------------------------------ */
.chats-col { display: none; }
.chats-inner {
  width: var(--chats-col);
  height: 100%;
  display: flex;
  flex-direction: column;
  padding-top: 18px;
}
.chats-head {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 12px 12px 16px;
}
.chats-title {
  flex: 1;
  margin: 0;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: var(--font-size-md);
  line-height: 24px;
}
.chats-icon-btn {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-round);
  color: var(--text-muted);
  transition: color var(--transition-fast), background-color var(--transition-fast);
}
.chats-icon-btn:hover { color: var(--text-primary); background: var(--bg-hover); }
.chats-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 8px var(--space-md);
}
.chats-group { margin: 14px 8px 6px; }
.chats-group-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-right: 0;
}
.chats-group-row .chats-icon-btn { width: 28px; height: 28px; }
/* The nest's menu (a floating popover, so it carries the float shadow). */
.chats-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  padding: 6px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  animation: v2-view-fade-in var(--transition-fast);
}
.chats-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  text-align: left;
  transition: background-color var(--transition-fast);
}
.chats-menu-item i { width: 16px; color: var(--text-muted); }
.chats-menu-item:hover { background: var(--bg-hover); }
.chats-menu-item.is-danger, .chats-menu-item.is-danger i { color: var(--color-danger); }
.chats-menu-rule { height: 1px; margin: 4px 6px; background: var(--border-color); }
.chats-group:first-child { margin-top: 2px; }
.chat-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  text-align: left;
  color: var(--text-primary);
  transition: background-color var(--transition-fast);
}
.chat-row:hover { background: var(--bg-secondary); }
.chat-row.is-active { background: var(--bg-secondary); box-shadow: inset 0 0 0 1px var(--border-color); }
.chat-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chat-row-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.chat-row-name { font-weight: var(--font-weight-semibold); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.chat-row-time { flex: none; font-size: var(--font-size-xs); color: var(--text-muted); }
.chat-row-preview {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
}
.chat-row.is-unread .chat-row-preview,
.chat-row.is-unread .chat-row-time { color: var(--text-primary); }
.chat-row-unread {
  flex: none;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--accent-color);
  color: var(--accent-text);
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-bold);
  line-height: 20px;
  text-align: center;
}
.chat-row-glyph {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
  color: var(--text-muted);
  font-size: var(--font-size-md);
}
.chat-row-glyph--voice { color: var(--color-online); }
.chats-empty {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  color: var(--text-muted);
  font-size: var(--font-size-sm);
}

/* ---- Side column ------------------------------------------------------- */
.side-col { display: none; }
.side-inner {
  width: var(--side-col);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 28px 24px var(--space-lg) 20px;
}
.side-card { padding: 18px; display: flex; flex-direction: column; gap: 10px; }
.side-amount {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: 32px;
  line-height: 36px;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
.side-amount .iron-diamond { width: 20px; height: 20px; }
.side-amount--iron { color: var(--iron-gold); }
.side-amount--aura { color: var(--aura-core); font-size: var(--font-size-title); line-height: 28px; }
.light-mode .side-amount--iron { color: var(--iron-gold-deep); }
.light-mode .side-amount--aura { color: var(--aura-deep); }
.side-note { font-size: var(--font-size-xs); color: var(--text-secondary); }
.side-rule { height: 1px; margin: 4px 0; background: var(--border-color); }
.side-meter {
  height: 6px;
  overflow: hidden;
  border-radius: 3px;
  background: var(--bg-tertiary);
}
.side-meter-fill {
  display: block;
  height: 100%;
  /* scaleX squashes the cap; ask for r/s and get r back (floored so an
     empty meter does not divide by zero). */
  border-radius: calc(3px / max(var(--fill, 0), 0.02)) / 3px;
  background: var(--aura-core);
  transform-origin: left center;
  transform: scaleX(var(--fill, 0));
  transition: transform var(--transition-normal);
}
.light-mode .side-meter-fill { background: var(--aura-deep); }

.side-streak { display: flex; align-items: center; gap: 14px; }
.hex-badge {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 56px;
  height: 62px;
  color: var(--color-warning);
}
.hex-badge svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.hex-badge b {
  position: relative;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-size: var(--font-size-lg);
  line-height: 1;
  color: var(--text-primary);
}
.side-streak-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.side-streak-text strong { font-weight: var(--font-weight-semibold); }
.streak-days { display: flex; gap: 4px; }
.streak-days span {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-tertiary);
}
.streak-days span.on { background: var(--color-warning); }

.side-voice-row { display: flex; align-items: center; gap: 10px; }
.side-voice-row .v2-btn { margin-left: auto; }
.side-voice-faces { display: flex; }
.side-voice-faces .v2-person { border: 2px solid var(--bg-secondary); margin-left: -8px; }
.side-voice-faces .v2-person:first-child { margin-left: 0; }
.side-voice-name { font-weight: var(--font-weight-semibold); }

.side-friends { display: flex; flex-direction: column; gap: 2px; }
.side-friend {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  margin: 0 -8px;
  border-radius: var(--radius-md);
  text-align: left;
  color: var(--text-primary);
  transition: background-color var(--transition-fast);
}
.side-friend:hover { background: var(--bg-hover); }
.side-friend-body { display: flex; flex-direction: column; min-width: 0; }
.side-friend-name { font-weight: var(--font-weight-semibold); }
.side-friend-status { font-size: var(--font-size-xs); color: var(--text-muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* ---- Wallet chip (phones, Home) ---------------------------------------- */
.wallet-chip { display: none; }

/* ---- Feedback link ----------------------------------------------------- */
.feedback-link {
  position: fixed;
  right: var(--space-md);
  bottom: var(--space-sm);
  z-index: var(--z-panel);
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding: 2px 6px;
  color: var(--text-muted);
  font-size: var(--font-size-xs);
  transition: color var(--transition-fast);
}
.feedback-link:hover { color: var(--text-primary); }

/* ==========================================================================
   Desktop — rail + columns
   ========================================================================== */
@media (min-width: 769px) {
  #app {
    display: grid;
    grid-template-columns: var(--rail-w) var(--chats-w) minmax(0, 1fr) var(--side-w);
    grid-template-rows: minmax(0, 1fr);
  }
  #app.chats-collapsed { --chats-w: 0px; }
  /* The chats toggle slides the column like a drawer. Only the toggle
     animates the grid (js/shell.js sets .chats-animating for its length):
     a tab switch must not relayout the columns while the pages move. */
  #app.chats-animating { transition: grid-template-columns 420ms var(--ease-glide); }
  #app:is([data-tab="communication"], [data-tab="iron-center"]) { --side-w: 0px; }

  /* Rail */
  /* Three rows: logo + nests from the top, the tabs dead centre, chats +
     avatar at the foot. Equal 1fr rows keep the tabs centred whatever the
     two ends hold; the nests scroll inside the top row. */
  .nav-island-wrapper {
    grid-column: 1;
    grid-row: 1;
    position: relative;
    z-index: var(--z-nav);
    display: grid;
    /* The tabs stay dead centre (equal 1fr rows above and below). Nests fill
       the top row under the logo, continue in the bottom row under the tabs,
       and fold into "+N" when both are full (js/shell.js); the avatar sits
       at the foot. */
    grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr);
    justify-items: center;
    row-gap: var(--space-md);
    min-height: 0;
    padding: 18px 0 14px;
    border-right: 1px solid var(--border-color);
  }
  .rail-top,
  .rail-bottom {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    min-height: 0;
    width: 100%;
  }
  .rail-top, .rail-bottom { justify-content: flex-start; overflow: hidden; }
  /* Rings drawn outside a button (the profile ring, hover rings) are not cut
     by the halves' clipping: clip with a margin where supported, and leave
     room at the ends everywhere. */
  @supports (overflow-clip-margin: 4px) {
    .rail-top, .rail-bottom { overflow: clip; overflow-clip-margin: 16px; }
  }
  .rail-bottom { padding-bottom: 3px; }
  .rail-foot { display: flex; flex-direction: column; align-items: center; gap: var(--space-sm); margin-top: auto; }
  #chats-toggle[aria-expanded="true"] { color: var(--text-primary); background: var(--bg-secondary); }
  /* The tabs sit on their own grey track; the pill moves inside it. */
  .ironhub-nav-layer {
    padding: 6px;
    border-radius: var(--radius-pill);
    background: var(--bg-tertiary);
  }
  .ironhub-nav-layer .nav-indicator { --pill-surface: var(--bg-tertiary); }
  .rail-logo {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    color: var(--accent-color);
  }
  /* The IRONITT mark (flat tier: nav and chrome sizes). */
  .rail-logo-mark { display: block; width: 36px; height: 36px; }

  .ironhub-nav-layer { flex-direction: column; gap: var(--space-sm); width: 56px; }
  .nav-tab {
    width: 44px;
    height: 44px;
    padding: 0;
    gap: 0;
  }
  .nav-tab i { font-size: 18px; }
  .nav-tab .iron-diamond { width: 19px; height: 19px; }
  /* Icon-only rail: the label stays for screen readers, the title for hover. */
  .nav-tab > span:not(.iron-diamond):not(.notif-badge):not(.nav-tab-back) {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  /* Profile lives at the bottom of the rail as the avatar button. */
  .nav-tab[data-tab="profile"] { display: none; }
  #app[data-tab="profile"] .nav-indicator { opacity: 0; }
  #app[data-tab="profile"] .profile-hub-btn { box-shadow: 0 0 0 2px var(--accent-color); }

  .rail-divider { flex: none; width: 24px; height: 1px; margin: 10px 0; background: var(--border-color); }
  .rail-nests {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    flex: none;
    overflow: visible;
    width: 100%;
  }
  .rail-nest[hidden] { display: none; }
  .rail-nest.rail-more { font-size: 12px; color: var(--text-secondary); background: var(--bg-tertiary); }
  .rail-nests::-webkit-scrollbar { display: none; }
  .rail-nest {
    position: relative;
    flex: none;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-round);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: var(--font-weight-bold);
    transition: border-radius var(--transition-fast), color var(--transition-fast), background-color var(--transition-fast);
  }
  .rail-nest img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
  .rail-nest:hover { border-radius: 14px; color: var(--text-primary); background: var(--bg-hover); }
  .rail-nest.is-active {
    border-radius: 14px;
    color: var(--accent-color);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-color) 40%, transparent);
  }
  .rail-nest.is-active::before,
  .rail-nest.has-unread::before {
    content: '';
    position: absolute;
    left: -14px;
    top: 50%;
    width: 4px;
    height: 8px;
    margin-top: -4px;
    border-radius: 2px;
    background: var(--text-primary);
  }
  .rail-nest.is-active::before { height: 16px; margin-top: -8px; background: var(--accent-color); }

  .rail-btn {
    flex: none;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-round);
    color: var(--text-muted);
    font-size: 17px;
    transition: color var(--transition-fast), background-color var(--transition-fast);
  }
  .rail-btn:hover { color: var(--text-primary); background: var(--bg-hover); }
  .rail-spacer { flex: 1 1 auto; min-height: var(--space-sm); }

  .user-corner { position: relative; display: flex; }
  .profile-hub-btn {
    position: relative;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-round);
    transition: box-shadow var(--transition-fast);
  }
  .profile-hub-btn:hover { box-shadow: 0 0 0 2px var(--border-strong); }
  .profile-hub-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }
  .profile-hub-btn > .notif-badge { position: absolute; top: -4px; right: -6px; }
  .user-corner-avatar {
    width: 40px;
    height: 40px;
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    background: var(--bg-tertiary);
  }
  .user-corner-avatar .status-dot {
    width: 11px;
    height: 11px;
    border: 2px solid var(--bg-primary);
    background: var(--color-online);
  }

  /* Chats column */
  .chats-col {
    grid-column: 2;
    grid-row: 1;
    display: block;
    min-width: 0;
    overflow: hidden;
  }
  #app.chats-collapsed:not(.chats-animating) .chats-col { visibility: hidden; }

  /* Main */
  .main-content {
    grid-column: 3;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    padding: var(--space-md) var(--space-md) var(--space-md);
    border-left: 1px solid var(--border-color);
  }
  #app.chats-collapsed .main-content { border-left: 0; }
  .main-content > .view { flex: 1 1 auto; min-height: 0; height: auto; }

  /* Friends, Whispers and Posts mirror the rail: an icon pill on its own grey
     track, dead centre on the right edge, in the column the side column
     gives up on this tab. The labels stay for screen readers and titles. */
  #app[data-tab="communication"] { --side-w: var(--rail-w); }
  #app[data-tab="communication"] .comm-bar {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-nav);
    display: grid;
    place-items: center;
    width: var(--rail-w);
    border-left: 1px solid var(--border-color);
  }
  #comm-sub-right {
    flex-direction: column;
    gap: var(--space-sm);
    width: 56px;
    padding: 6px;
    border: 0;
    background: var(--bg-tertiary);
  }
  #comm-sub-right .comm-sub-indicator { top: 0; left: 6px; width: 44px; height: auto; background: var(--bg-hover); }
  #comm-sub-right .comm-sub-tab { width: 44px; height: 44px; padding: 0; gap: 0; justify-content: center; border-radius: var(--radius-round); }
  #comm-sub-right .comm-sub-tab i { font-size: 17px; }
  #comm-sub-right .comm-sub-tab > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  /* The composer sits on the bottom edge: no room is kept for a phone
     dock here (style.css's 60px), and the page's own foot padding goes. */
  #app[data-tab="communication"] .main-content { padding-bottom: 0; }
  .comm-content { margin-bottom: 0; }
  .chat-input-area { padding-bottom: var(--space-md); }
  /* Nests live on the rail; the Nests button is for phones only. */
  #comm-sub-left { display: none; }
  /* The nests strip on top of the Nests view repeats the rail. */
  .server-diamond-strip { display: none; }
  #app[data-dir][data-tab="communication"] .comm-bar {
    animation: v2-view-in var(--view-move) var(--ease-glide),
               v2-view-fade-in var(--view-fade) ease;
  }

  /* Side column */
  .side-col {
    grid-column: 4;
    grid-row: 1;
    display: block;
    min-width: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  #app:is([data-tab="communication"], [data-tab="iron-center"]) .side-col { display: none; }
  /* Coming back into view (a tab switch), it slides in from the edge. */
  .side-col { animation: v2-side-in var(--view-move) var(--ease-glide); }
  @keyframes v2-side-in { from { opacity: 0; transform: translate3d(32px, 0, 0); } }
  body:has(#app[data-tab="communication"]) .feedback-link { display: none; }
  /* The Quick Hub and the notifications panel open from the avatar at the
     foot of the rail, so they sit beside it rather than top-right. */
  .popup-panel { top: auto; right: auto; bottom: 12px; left: calc(var(--rail-w) + 8px); }
  .quick-hub-panel { max-height: calc(100vh - 24px); }
  /* Bottom-left of the content area, clear of the assistant launcher. */
  .feedback-link { left: calc(var(--rail-w) + 12px); right: auto; }
}

/* Narrow desktop: the side column goes first, then the chats column (and
   with it the toggle, which would have nothing to open). */
@media (min-width: 769px) and (max-width: 1240px) {
  #app { --side-w: 0px; }
  .side-col { display: none; }
}
@media (min-width: 769px) and (max-width: 1000px) {
  #app { --chats-w: 0px; }
  .chats-col, #chats-toggle { display: none; }
  .main-content { border-left: 0; }
}

/* ==========================================================================
   Phones — the floating island at the bottom edge
   ========================================================================== */
@media (max-width: 768px) {
  :root { --mobile-nav-h: 64px; }
  #app[data-dir="fwd"] :is(.view, .comm-bar) { --view-x: 100%; --view-y: 0px; }
  #app[data-dir="back"] :is(.view, .comm-bar) { --view-x: -100%; --view-y: 0px; }

  .rail-top, .rail-bottom, .rail-foot { display: contents; }
  .rail-logo, .rail-divider, .rail-nests, .rail-add-nest, .rail-spacer,
  #chats-toggle, .user-corner { display: none; }

  .main-content {
    display: flex;
    flex-direction: column;
    padding:
      calc(env(safe-area-inset-top, 0px) + var(--space-sm))
      var(--space-sm)
      calc(var(--mobile-nav-h) + env(safe-area-inset-bottom, 0px) + 40px);
  }
  .main-content > .view { flex: 1 1 auto; min-height: 0; height: auto; }

  .nav-island-wrapper {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
    z-index: var(--z-nav);
    display: flex;
    height: var(--mobile-nav-h);
    padding: 6px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-island);
    transition: transform var(--island-slide) var(--island-ease);
  }
  .ironhub-nav-layer { flex: 1 1 100%; align-self: stretch; }
  .nav-indicator { --pill-surface: var(--bg-elevated); }
  .nav-pill-mid { width: 100px; height: var(--pill-thick, 50px); }
  .nav-pill-mid.nav-pill-fill { width: 100px; height: calc(var(--pill-thick, 50px) - 2px); margin: 1px 0 0; }

  .nav-tab {
    flex: 1 1 0;
    flex-direction: column;
    gap: 3px;
    height: 100%;
    padding: 0 2px;
    font-size: var(--font-size-2xs);
    line-height: 1.1;
  }
  .nav-tab i { font-size: 18px; }
  .nav-tab .iron-diamond { width: 20px; height: 20px; }
  .nav-tab .nav-tab-badge { top: 4px; right: calc(50% - 22px); }
  .nav-icons-only .nav-tab span:not(.iron-diamond):not(.notif-badge) { display: none; }
  .nav-icons-only .nav-tab i { font-size: 22px; }

  /* No back chevron on the island (owner, 2026-10-27): going back is the
     page's own back button. The active tab stays inert, so a tap on it no
     longer doubles as "back" either. */

  .nav-island-wrapper.nav-autohide.nav-hidden { transform: translateY(150%); pointer-events: none; }
  #app.nav-autohide-on #view-communication.active {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-nav) - 1);
    height: auto;
    padding: var(--space-sm);
    background: var(--bg-primary);
  }

  /* Home only: Iron Center opens on its own IRON/AURA strip. */
  #app[data-tab="dashboard"] .wallet-chip {
    display: flex;
    flex: none;
    justify-content: flex-end;
    gap: 6px;
    padding: 0 2px var(--space-sm);
  }
  .wallet-chip-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 12px;
    border-radius: var(--radius-pill);
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    font-weight: var(--font-weight-bold);
    font-variant-numeric: tabular-nums;
  }
  .wallet-chip-item--iron { color: var(--iron-gold); }
  .wallet-chip-item--aura { color: var(--aura-core); }
  .light-mode .wallet-chip-item--iron { color: var(--iron-gold-deep); }
  .light-mode .wallet-chip-item--aura { color: var(--aura-deep); }
  .wallet-chip-item .iron-diamond, .wallet-chip-item .aura-emblem { width: 14px; height: 14px; }

  .feedback-link {
    left: 50%;
    right: auto;
    bottom: calc(var(--mobile-nav-h) + env(safe-area-inset-bottom, 0px) + 14px);
    z-index: calc(var(--z-nav) + 1);
    transform: translateX(-50%);
    min-height: 20px;
    font-size: var(--font-size-2xs);
  }
  .feedback-link.feedback-link-hidden { display: none; }

  /* PHONE — ON-SCREEN KEYBOARD OPEN (html.kb-open)
     js/mobile-viewport.js publishes the visible viewport as --app-vh.
     On-screen keyboard: size the shell to what is visible above it and get
     the island (and the link above it) out of the composer's way. */
  html.kb-open #app { height: var(--app-vh, 100vh); }
  html.kb-open .nav-island-wrapper { transform: translateY(130%); pointer-events: none; }
  html.kb-open .feedback-link { display: none; }
  html.kb-open .main-content { padding-bottom: var(--space-sm); }
  html.kb-open .comm-content { margin-bottom: 0; }
  html.kb-open .popup-panel { max-height: calc(var(--app-vh, 100dvh) - 58px); }

  /* PHONE — IN A CONVERSATION (html.in-conversation, js/communication.js)
     The island slides away while a whisper or channel is open; the page's
     back button returns to the list, and the island with it. */
  html.in-conversation .nav-island-wrapper { transform: translateY(130%); pointer-events: none; }
  html.in-conversation .feedback-link { display: none; }
  html.in-conversation .main-content { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + var(--space-sm)); }
  html.in-conversation .comm-content { margin-bottom: 0; }

  /* "Communication" is the longest label on the island: its tab gets a
     little more of the width so the pill clears the word on both sides. */
  .nav-tab[data-tab="communication"] { flex-grow: 1.4; }

  /* Popups float clear of the dock on phones, so every corner is rounded,
     the bottom ones too (the old bottom-sheet rule squared them off). */
  .popup-panel { border-radius: var(--radius-xl); }
}

/* ---- Segment glide (js/segment-glide.js) ------------------------------- */
/* One piece per row or grid of choices carries the selected look and slides
   to the new choice. "under" pieces are fills beneath see-through items;
   "over" pieces are rings or tints above opaque ones. While a piece is
   there the chosen item drops its own fill or ring. */
.has-seg-glide { position: relative; }
.seg-glide {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transition: transform 240ms var(--ease-glide), width 240ms var(--ease-glide),
    height 240ms var(--ease-glide), opacity 150ms ease;
}
.seg-glide--under { z-index: 0; }
.seg-under > :not(.seg-glide) { position: relative; z-index: 1; }
.seg-glide--over { z-index: 3; }
.seg-glide--pill { background: var(--bg-hover); }
.seg-glide--ring { box-shadow: inset 0 0 0 1px var(--accent-color); }
.seg-glide--ring-tint { box-shadow: inset 0 0 0 1px var(--accent-color); background: var(--accent-subtle); }
.seg-glide--tint { background: var(--accent-subtle); }
.seg-glide--lb { background: rgba(63, 182, 200, 0.16); box-shadow: inset 0 0 0 1px rgba(63, 182, 200, 0.4); }

#view-iron-center .has-seg-glide > .ic-station.active { background: transparent; }
.has-seg-glide > .ic-lb-cat-tab.active { background: var(--bg-secondary); border-color: rgba(255, 255, 255, 0.06); }
.has-seg-glide > .ep-tab.active { background: none; }
.has-seg-glide > :is(.qh-theme, .theme-option, .fs-language-option, .fs-radio-option).active { border-color: var(--border-color); }
.has-seg-glide > .onboarding-lang-option.active { border-color: var(--border-color); background: var(--bg-primary); }

@media (prefers-reduced-motion: reduce) {
  .seg-glide { transition: opacity 150ms ease; }
}

/* Inside a nest the column is that nest's channels, headed by its name. */
.chats-title--nest { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chats-head-menu .chats-icon-btn { width: 32px; height: 32px; }

/* With the chats column open (it holds Friends and Posts, and every whisper
   and channel), the right-edge Friends/Whispers/Posts pill and its column go:
   the conversation gets the width. Closed, the pill comes back. */
@media (min-width: 1001px) {
  #app:not(.chats-collapsed)[data-tab="communication"] { --side-w: 0px; }
  #app:not(.chats-collapsed)[data-tab="communication"] .comm-bar { display: none; }
}
/* An empty half-list must not add a gap of its own. */
@media (min-width: 769px) { .rail-nests:empty { display: none; } }

/* Desktop lines (owner, 2026-11-02): the conversation header's line runs from
   the chats column's edge to the screen's edge, and the chats column's own head
   ends on the same line, so the two read as one rule across the page. */
@media (min-width: 1001px) {
  /* The views inside clip what leaves them, so the page drops its own frame
     here instead of the header reaching out of it. */
  #app[data-tab="communication"] .main-content { padding: 0; }
  #app[data-tab="communication"] :is(.dm-thread-header:not(.dm-thread-header--mobile-only), .chat-area > .chat-header) {
    min-height: 64px;
  }
  .chats-inner { padding-top: 0; }
  .chats-head {
    min-height: 64px;
    padding-top: 0;
    padding-bottom: 0;
    margin-bottom: var(--space-sm);
    border-bottom: 1px solid var(--border-color);
  }
}
@media (min-width: 1001px) {
  /* Friends and Posts get the same 64px head and the same line. */
  #app[data-tab="communication"] :is(.friends-header, .posts-toolbar) {
    box-sizing: border-box;
    min-height: 64px;
    margin: 0 0 var(--space-md);
    padding-top: 0;
    padding-bottom: 0;
    padding-left: var(--space-lg);
    padding-right: var(--space-lg);
    align-items: center;
    border-bottom: 1px solid var(--border-color);
  }
}
@media (min-width: 1001px) {
  /* Inside a nest the column holds its channels: always open, no toggle. */
  #app.in-nest.chats-collapsed { --chats-w: 280px; }
  #app.in-nest.chats-collapsed:not(.chats-animating) .chats-col { visibility: visible; }
  #app.in-nest.chats-collapsed .main-content { border-left: 1px solid var(--border-color); }
  #app.in-nest #chats-toggle { display: none; }
}
@media (min-width: 1001px) {
  #app.in-nest[data-tab="communication"] { --side-w: 0px; }
  #app.in-nest[data-tab="communication"] .comm-bar { display: none; }
}
@media (min-width: 1001px) {
  #app.in-nest :is(.server-diamond-strip, .channel-sidebar) { display: none; }
}

/* The developer badge: big enough to notice beside a name. */
.developer-badge { width: 19px; height: 19px; font-size: 10px; border-radius: 6px; }
.chat-row-name { display: inline-flex; align-items: center; min-width: 0; }
.chat-row-name .developer-badge { margin-left: 6px; }
.developer-badge.developer-badge--label { width: auto; height: 24px; gap: 6px; padding: 0 10px; margin-left: 0; border-radius: var(--radius-pill); font-size: var(--font-size-xs); }
