/* ============================================================================
   Browser — a bookmarks-reader window, built to content/browser-frame.svg.
   Replaces the earlier 18-tab Chrome replica entirely.
   Every selector is prefixed .br- / #win-browser per components/DESIGN.md.

   2026-08-07: body was a 14-column grid — rail(3) / ad(2) / reader(7) /
   ad(2) — replacing the earlier design where 6 ad slots were mixed into the
   bookmarks rail itself.

   2026-08-09: body is now just two flex children — the full-height rail and
   a single .br-content column that scrolls the top banner, the ad-flanked
   article row, and both side ads together as one unit (one native scrollbar,
   at the window's outer right edge, not indented to the article column).
   Ad images render at their natural aspect ratio as rounded inset banner
   cards instead of being stretched to fill a column's height. See
   PROGRESS.md for the full history. Window: 82vw -> 60vw (80% of the doc
   window's 75vw); height: 62vh -> 74vh (+20%).
   ========================================================================== */

#win-browser {
  height: min(74vh, var(--desk-band));
  min-height: 320px;
  cursor: default;      /* only the title bar drags */
  touch-action: auto;
}

.br-chrome {
  /* Palette sampled from the reference: cool near-white ground, mint rail. */
  --br-line: #000000;
  --br-ground: #F9FFFF;
  --br-rail: #EEFFF8;
  --br-mint: #A6ECC7;
  --br-red: #FF4052;
  --br-muted: #8A8F8D;

  display: flex;
  flex-direction: column;
  height: 100%;
  border-radius: 20px;
  overflow: hidden;
  background: var(--br-ground);
  border: 1px solid var(--br-line);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: #000;
}

/* --- Title bar --- */
.br-titlebar {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: none;
  padding: 9px 12px 0;
  cursor: grab;
}
.br-chrome .br-titlebar:active { cursor: grabbing; }

.br-lights { display: flex; gap: 6px; flex: none; }
.br-lights i {
  display: block; width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid var(--br-line);
}
.br-lights i:nth-child(1) { background: #FF8875; }
.br-lights i:nth-child(2) { background: #FFE78E; }
.br-lights i:nth-child(3) { background: #94E9BC; }

.br-globe { width: 23px; height: 23px; flex: none; margin-left: 2px; }
.br-appname { font-size: 15px; font-weight: 700; }

/* --- Tab strip ---
   Tabs sit on the toolbar's top edge, so the active one loses its bottom
   border and overlaps the divider by 1px to read as connected. */
.br-tabs {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  flex: none;
  padding: 6px 12px 0 26px;
  margin-bottom: -1px;
  position: relative;
  z-index: 1;
}

.br-tab {
  display: flex; align-items: center; gap: 7px;
  font: inherit; font-size: 12.5px; font-weight: 500; color: #000;
  padding: 6px 14px;
  background: transparent;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: 9px 9px 0 0;
  cursor: pointer;
  white-space: nowrap;
}
.br-tab:hover { background: rgba(0, 0, 0, .04); }
.br-tab.is-active {
  background: var(--br-ground);
  border-color: var(--br-line);
  padding-bottom: 7px;
}
.br-tab-icon { width: 9px; height: 13px; flex: none; }
/* The LinkedIn tab's favicon is square, not a bookmark ribbon. */
.br-tab-icon-li { width: 13px; height: 13px; }

/* --- Toolbar --- */
.br-toolbar {
  display: flex; align-items: center; gap: 8px;
  flex: none;
  padding: 8px 14px;
  border-top: 1px solid var(--br-line);
  border-bottom: 1px solid var(--br-line);
  background: var(--br-ground);
}

.br-nav {
  display: grid; place-items: center;
  width: 22px; height: 22px; flex: none;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.br-nav svg { width: 15px; height: 15px; display: block; }
.br-nav:hover { opacity: .55; }
.br-reload svg { width: 16px; height: 16px; }

.br-url {
  flex: 1; min-width: 0;
  height: 26px;
  display: flex; align-items: center; gap: 6px;
  padding: 0 4px 0 12px;
  background: var(--br-ground);
  border: 1px solid var(--br-line);
  border-radius: 8px;
  font-size: 12px;
  color: #2B2B2B;
}

.br-url-text {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.br-url-open {
  flex: none;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  background: none; border: 0; padding: 0;
  cursor: pointer;
}
.br-url-open svg { width: 100%; height: 100%; display: block; }
.br-url-open:hover { opacity: .65; }

/* --- Body: rail + one scrollable content column ---
   Just two flex children. .br-rail is full-height and flush to the left/top/
   bottom edges (its own scrollbar only kicks in if the bookmark list itself
   overflows). .br-content takes the rest of the width and is the ONE
   scrolling element for everything to the right of the rail — top banner,
   ad-flanked article row, side ads — so it all moves together and the
   native scrollbar sits at the window's outer right edge. */
.br-body {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* Bookmarks rail — real articles only, no ads mixed in */
.br-rail {
  flex: 0 0 21.4%;
  min-width: 0;
  overflow-y: auto;
  background: var(--br-rail);
  border-right: 1px solid var(--br-line);
  padding: 6px 0;
}
.br-rail::-webkit-scrollbar { width: 8px; }
.br-rail::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, .2); border-radius: 4px; }

.br-item {
  display: flex; gap: 10px; align-items: flex-start;
  width: 100%; text-align: left;
  padding: 9px 12px;
  background: none; border: 0; cursor: pointer;
  font: inherit; color: #000;
}
.br-item:hover { background: rgba(0, 0, 0, .045); }
.br-item.is-active { background: rgba(0, 0, 0, .075); }

/* The md carries no imagery, so each site gets a flat chip with its initial */
.br-thumb {
  width: 40px; height: 40px; flex: none;
  border-radius: 8px;
  border: 1px solid var(--br-line);
  display: grid; place-items: center;
  color: #fff; font-size: 15px; font-weight: 700;
}

.br-item-text { min-width: 0; }
.br-item-title {
  font-size: 12.5px; font-weight: 700; line-height: 1.32;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.br-item-site {
  display: flex; align-items: center; gap: 5px;
  margin-top: 4px; font-size: 11.5px; color: var(--br-muted);
}
.br-favicon {
  width: 12px; height: 12px; flex: none; border-radius: 3px;
  display: grid; place-items: center;
  color: #fff; font-size: 7.5px; font-weight: 700; line-height: 1;
}

/* Content column — the single scroll container for everything right of the
   rail. Its scrollbar is what shows at the window's outer right edge. */
.br-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
.br-content::-webkit-scrollbar { width: 9px; }
.br-content::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, .2); border-radius: 5px; }

/* Page pane */
.br-page {
  flex: 1;
  min-width: 0;
  background: #FFFFFF;
}

/* Row wrapping the middle column between its two flanking ads. The left/
   right ads and .br-middle all start at the same top edge — the top banner
   lives inside .br-middle, above .br-page, so it reads as sitting between
   the two side ads rather than spanning full width above them. */
.br-ad-row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px;
  flex: 1;
  min-height: 0;
}

.br-middle {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Ad creatives — same static "plum" campaign artwork on every article, no
   per-article variation. Rendered as inset banner cards: rounded corners,
   natural aspect ratio (never stretched to fill a column's height) —
   distinct from the full-bleed rail, which touches every edge. --plum-red
   is the site's existing token (css/style.css :root), used as the
   letterbox/fallback fill so the SVG creatives (whose own background is
   the same red) blend in seamlessly. */
.br-ad {
  flex: none;
  min-width: 0;
  overflow: hidden;
  border-radius: 12px;
  background: var(--plum-red, #FF4052);
  cursor: pointer; /* clicking an ad opens the Talk form (data-talk-form) */
}
.br-ad img { display: block; width: 100%; height: auto; }
.br-ad-left { width: 15%; min-width: 110px; }
.br-ad-right { width: 15%; min-width: 110px; }

/* Reader view: real headline + full article body, extracted from the md and
   rendered to HTML by tools/build-browser-content.py. Text-only — no images
   were extracted from the source export. */
.br-reader { padding: 34px 34px 44px; max-width: 660px; }
.br-reader-kicker {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--br-muted); margin-bottom: 14px;
}
.br-reader h1 { font-size: 25px; line-height: 1.24; font-weight: 700; margin-bottom: 18px; }
.br-reader h2 { font-size: 18px; line-height: 1.3; font-weight: 700; margin: 26px 0 10px; }
.br-reader h3 { font-size: 15px; line-height: 1.32; font-weight: 700; margin: 20px 0 8px; }
.br-reader h4 { font-size: 13.5px; font-weight: 700; margin: 16px 0 6px; }
.br-reader p { font-size: 13.5px; line-height: 1.62; color: #1E1E1E; margin-bottom: 13px; }
.br-reader ul, .br-reader ol { margin: 0 0 13px 20px; padding: 0; }
.br-reader li { font-size: 13.5px; line-height: 1.55; color: #1E1E1E; margin-bottom: 8px; }
.br-reader a { color: #2C6BE8; text-decoration: none; }
.br-reader a:hover { text-decoration: underline; }
.br-reader strong { font-weight: 700; }
.br-reader em { font-style: italic; }
.br-reader-url {
  display: block; margin-top: 22px; padding-top: 14px;
  border-top: 1px solid rgba(0, 0, 0, .12);
  font-size: 11.5px; color: var(--br-muted); word-break: break-all;
}
.br-reader-url:hover { color: #2C6BE8; text-decoration: underline; }

/* Below this WINDOW width the ad-flanked layout would crush the article
   column. Container scope lives on .br-chrome (not .br-body) so the top
   banner — nested inside .br-content — is covered by the same query.
   .br-page is already flex: 1 inside .br-ad-row, so hiding the rail and
   both ads is enough for it to fill the full width on its own. */
@container brbody (max-width: 640px) {
  .br-rail, .br-ad, .br-ad-top { display: none; }
}
.br-chrome { container-type: inline-size; container-name: brbody; }

/* ==========================================================================
   Tab 2 — "Plum:Posts | Linkedin"
   ==========================================================================
   A second real tab, not a second view of the same page: switching swaps the
   entire viewport, bookmarks rail included, the way a browser tab does. That
   is what .is-linkedin below does, and it is also why the rail's mobile
   drawer furniture (scrim + handle, both appended to .br-body by
   MobileShell.createDrawer) has to go with it — leaving the handle behind
   would offer to pull open a rail that is no longer on this tab.

   Chrome is drawn in the house style — flat fills, 1px black hairlines,
   initial-chip avatars (the same convention the Slack window uses for
   people) — rather than as a pixel copy of LinkedIn's own UI.
   ========================================================================== */
.br-li {
  display: none;
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  background: #F4F2EE;
  --li-line: var(--br-line);
  --li-blue: #0A66C2;
  --li-dim: #5A6B7A;
}
.br-li::-webkit-scrollbar { width: 9px; }
.br-li::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, .2); border-radius: 5px; }

.br-chrome.is-linkedin .br-rail,
.br-chrome.is-linkedin .br-content,
.br-chrome.is-linkedin .m-drawer-scrim,
.br-chrome.is-linkedin .m-drawer-handle { display: none; }
.br-chrome.is-linkedin .br-li { display: block; }

/* --- Global nav --- */
.li-nav {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  background: #FFFFFF;
  border-bottom: 1px solid var(--li-line);
}
.li-logo { width: 26px; height: 26px; flex: none; }
.li-logo svg { width: 100%; height: 100%; display: block; }

.li-search {
  flex: 1 1 auto;
  min-width: 60px;
  max-width: 230px;
  height: 24px;
  display: flex; align-items: center; gap: 7px;
  padding: 0 11px;
  border: 1px solid var(--li-line);
  border-radius: 999px;
  background: #FFFFFF;
}
.li-search-icon { width: 12px; height: 12px; flex: none; }
.li-search-text { font-size: 11px; color: var(--li-dim); }

.li-nav-items { display: flex; align-items: center; gap: 2px; flex: none; }
.li-nav-items-biz { margin-left: 0; }

.li-navitem {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 2px 7px;
  min-width: 0;
  color: #1E1E1E;
}
.li-navicon { position: relative; display: block; height: 17px; }
.li-navicon svg { width: 17px; height: 17px; display: block; }
.li-navlabel {
  display: flex; align-items: center; gap: 3px;
  font-size: 9.5px; line-height: 1.1; white-space: nowrap;
}
.li-caret { width: 6px; height: 4px; flex: none; }

.li-badge {
  position: absolute;
  top: -4px; left: 10px;
  min-width: 12px; height: 12px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--br-red);
  border: 1px solid var(--li-line);
  color: #FFFFFF;
  font-size: 7.5px; font-weight: 700; line-height: 10px;
  text-align: center;
}

.li-nav-divider {
  width: 1px; height: 26px; flex: none;
  background: rgba(0, 0, 0, .18);
  margin: 0 2px;
}

/* Initial-chip avatars — the site never ships photographs of people. */
.li-avatar {
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--li-line);
  background: #FFAA8D;
  color: #1E1E1E;
  font-weight: 700;
}
.li-avatar-sm { width: 17px; height: 17px; font-size: 9px; }
.li-avatar-lg {
  width: 54px; height: 54px; font-size: 22px;
  border-width: 2px;
  box-shadow: 0 0 0 2px #FFFFFF;
  margin: -27px auto 0;
  position: relative;
}

/* --- Three-column page --- */
.li-cols {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
}
.li-left  { flex: 0 0 22%; min-width: 150px; display: flex; flex-direction: column; gap: 10px; }
.li-feed  { flex: 1; min-width: 0; }
.li-right { flex: 0 0 16%; min-width: 118px; }

.li-card {
  background: #FFFFFF;
  border: 1px solid var(--li-line);
  border-radius: 11px;
  overflow: hidden;
}

/* --- Profile card --- */
.li-cover {
  position: relative;
  height: 62px;
  background:
    radial-gradient(120% 90% at 18% 105%, #F0A38C 0%, rgba(240,163,140,0) 62%),
    linear-gradient(150deg, #3B2C63 0%, #6B4A85 42%, #C86E8A 74%, #E9A487 100%);
  border-bottom: 1px solid var(--li-line);
}
.li-cover-tag {
  position: absolute; top: 5px; right: 7px;
  font-size: 9px; font-weight: 700; color: #FFFFFF;
}
.li-cover-note {
  position: absolute; top: 17px; right: 7px;
  font-size: 7.5px; line-height: 1.3; text-align: right;
  color: rgba(255, 255, 255, .82);
}

.li-profile-body { padding: 7px 12px 14px; text-align: center; }
.li-name {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  font-size: 14px; font-weight: 700;
}
.li-verified { width: 12px; height: 12px; flex: none; }
.li-headline { font-size: 10.5px; line-height: 1.35; margin-top: 4px; }
.li-place { font-size: 10px; color: var(--li-dim); margin-top: 6px; }
.li-company {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  font-size: 10.5px; font-weight: 600; margin-top: 9px;
}
.li-company-mark { width: 14px; height: 14px; flex: none; }
.li-company-mark img { width: 100%; height: 100%; display: block; }

/* --- Stats card --- */
.li-stats { padding: 4px 0; }
.li-stat {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 12px;
  font-size: 10.5px;
  color: var(--li-dim);
}
.li-stat b { color: var(--li-blue); font-weight: 700; }
.li-stat-premium {
  justify-content: flex-start;
  gap: 6px;
  border-top: 1px solid rgba(0, 0, 0, .12);
  font-weight: 600;
  color: #1E1E1E;
}
.li-premium-mark { width: 11px; height: 11px; flex: none; }

/* --- The post --- */
.li-post-head {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 13px 14px 8px;
}
.li-post-mark { width: 38px; height: 38px; flex: none; }
.li-post-mark img { width: 100%; height: 100%; display: block; }
.li-post-id { flex: 1; min-width: 0; }
.li-post-name {
  display: flex; align-items: center; gap: 5px;
  font-size: 13.5px; font-weight: 700;
}
.li-post-inmark { width: 12px; height: 12px; flex: none; }
.li-post-link a { font-size: 11px; font-weight: 600; color: var(--li-blue); text-decoration: none; }
.li-post-link a:hover { text-decoration: underline; }
.li-post-meta {
  display: flex; align-items: center; gap: 4px;
  font-size: 10.5px; color: var(--li-dim); margin-top: 2px;
}
.li-globe { width: 11px; height: 11px; flex: none; }
.li-post-more {
  flex: none; align-self: flex-start;
  font-size: 15px; font-weight: 700; line-height: 1;
  color: var(--li-dim);
}

.li-post-body { padding: 2px 14px 12px; }
.li-post-body p { font-size: 12.5px; line-height: 1.5; margin-bottom: 11px; }
.li-post-body p:last-child { margin-bottom: 0; }
.li-post-body a { color: var(--li-blue); font-weight: 600; text-decoration: none; }
.li-post-body a:hover { text-decoration: underline; }

.li-post-media {
  border-top: 1px solid var(--li-line);
  border-bottom: 1px solid var(--li-line);
  background: var(--plum-red, #FF4052);
}
.li-post-media img { display: block; width: 100%; height: auto; }

.li-post-counts {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  font-size: 10.5px; color: var(--li-dim);
}
.li-reacts { display: flex; flex: none; }
.li-react {
  width: 13px; height: 13px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid #FFFFFF;
  margin-right: -3px;
}
.li-react svg { width: 8px; height: 8px; display: block; }
.li-react-like { background: var(--li-blue); }
.li-react-love { background: var(--br-red); }
.li-react-clap { background: #44712E; }
.li-counts-you { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.li-counts-rest { flex: none; }

.li-post-actions {
  display: flex; align-items: center; justify-content: space-around; gap: 4px;
  padding: 7px 8px 9px;
  border-top: 1px solid rgba(0, 0, 0, .12);
}
.li-action {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; color: #1E1E1E;
  white-space: nowrap;
}
.li-action svg { width: 15px; height: 15px; flex: none; display: block; }
.li-action.is-on { color: var(--br-red); }

/* The right column reuses .br-ad's card treatment (rounded, letterboxed on
   --plum-red) so both tabs' ads read as the same campaign. */
.li-ad { width: 100%; }

/* Narrow WINDOW (not viewport): the three-column page has nowhere left to go,
   so drop the profile rail, stack the ad under the post, and let the nav run
   as icons only. Same container as the reader tab's collapse above. */
@container brbody (max-width: 700px) {
  .li-cols { flex-direction: column; }
  .li-left { display: none; }
  .li-right { flex: none; width: 100%; }
  .li-ad { display: block; max-width: 300px; margin: 0 auto; }
  .li-navlabel { display: none; }
  .li-navitem { padding: 2px 6px; }
}

/* ==========================================================================
   Mobile (<=767px). Appended at the end so desktop (>=768px) stays
   byte-identical — none of these rules match above the breakpoint.

   The @container query above also fires at phone width (the window is far
   narrower than 640px there) and hides .br-rail / .br-ad / .br-ad-top. On
   mobile the rail becomes an off-canvas drawer (js/mobile.js's
   MobileShell.createDrawer, wired in browser.js) instead of disappearing,
   and all three ads must stay reachable (each is a live
   window.openTalkForm trigger via data-talk-form) — so every selector the
   @container rule hides is explicitly restored here. A plain class
   selector in this later media block beats the earlier @container rule of
   equal specificity by source order.
   ========================================================================== */
@media (max-width: 767px) {
  #win-browser {
    min-height: 0;
  }

  /* Edge-to-edge app, not a floating card. */
  .br-chrome { border-radius: 0; }

  /* .br-rail becomes the drawer panel (see browser.js createDrawer call).
     .br-body is its positioning container. */
  .br-body {
    position: relative;
  }
  .br-rail {
    display: block;
  }

  /* Only the TOP ad survives on mobile (user decision: one ad, the top
     banner). It stays a live Sponsored-Ad talk trigger; the left/right
     ads (ad-1/ad-3) stay hidden — same as the @container collapse above. */
  .br-ad-row {
    flex-direction: column;
    padding: 12px;
    gap: 12px;
  }
  .br-ad-top {
    display: block;
  }

  /* Article reader: drop the desktop readable-width cap so it uses the
     full phone width, with tighter side padding. */
  .br-reader {
    padding: 20px 16px 36px;
    max-width: none;
  }

  /* Scrolled content bottoms out above the dock's peeking band. */
  .br-content { padding-bottom: var(--m-bottom-inset); }

  /* Tab strip assumed desktop spacing to clear the (now hidden) lights
     cluster; tighten it for the narrower window. Two tabs no longer fit
     side by side at phone width, so let the strip scroll sideways rather
     than squeeze or wrap either label. */
  .br-tabs {
    padding-left: 12px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .br-tabs::-webkit-scrollbar { display: none; }

  /* ---- Tab 2 on mobile ----
     The @container rule above already stacked the columns and dropped the
     profile rail; here the nav gets phone spacing. Unlike the reader tab —
     which restores .br-ad-top — this tab carries NO ad on a phone (user
     decision): the post is the whole point of the tab, and the topbar's
     "Talk to an expert" CTA is the mobile conversion path instead. The
     @container rule's .br-ad collapse already hides .li-ad; the column that
     held it goes too, so it leaves no gap. */
  .li-nav { gap: 7px; padding: 7px 10px; }
  /* Eight icons plus a search field do not fit a phone strip, and a search
     box that has to be scrolled to is worse than one collapsed to its
     glyph — which is what LinkedIn's own phone nav does. */
  .li-search { flex: none; width: 32px; padding: 0 9px; }
  .li-search-text { display: none; }
  .li-nav-divider { display: none; }
  .li-cols { padding: 12px; gap: 12px; }
  .li-right { display: none; }

  /* Scrolled content bottoms out above the dock's peeking band, matching
     .br-content. */
  .br-li { padding-bottom: var(--m-bottom-inset); }
}
