/* Custom CSS Reset (Joshua W. Comeau) https://www.joshwcomeau.com/css/custom-css-reset/ */ /* 1. Use a more-intuitive box-sizing model */ *, *::before, *::after { box-sizing: border-box; } /* 2. Remove default margin */ *:not(dialog) { margin: 0; } /* 3. Enable keyword animations */ @media (prefers-reduced-motion: no-preference) { html { interpolate-size: allow-keywords; } } body { /* 4. Increase line-height */ line-height: 1.5; /* 5. Improve text rendering */ -webkit-font-smoothing: antialiased; } /* 6. Improve media defaults */ img, picture, video, canvas, svg { display: block; max-width: 100%; } .svg-icon { display: block; width: 1em; height: 1em; background-color: currentColor; -webkit-mask: var(--icon-url) center / contain no-repeat; mask: var(--icon-url) center / contain no-repeat; } /* 7. Inherit fonts for form controls */ input, button, textarea, select { font: inherit; } /* 8. Avoid text overflows */ p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } /* 9. Improve line wrapping */ p { text-wrap: pretty; } h1, h2, h3, h4, h5, h6 { text-wrap: balance; } /* 10. Create a root stacking context */ #root, #__next { isolation: isolate; } /* Project design tokens. Names follow tmp/design_handoff_nav_lens_search/README.md. Light values are derived from the same cool-indigo hue family as the dark palette so the two themes feel like siblings. */ :root { --radius: 10px; --radius-sm: 7px; --radius-lg: 14px; --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; --sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, "Helvetica Neue", sans-serif; --bg: #ffffff; --bg-canvas: #f7f7fa; --surface: #f3f3f7; --surface-2: #e8e8ee; --surface-3: #d8d8e0; --line: #d8d8e0; --line-soft: #ececf2; --text: #1a1a22; --text-2: #595969; --text-3: #797988; --accent: #3a3acc; --accent-on: #ffffff; --accent-soft: rgba(58, 58, 204, 0.06); --accent-bg: rgba(58, 58, 204, 0.12); --accent-edge: rgba(58, 58, 204, 0.45); --good: #007a3d; --warn: #c46e1f; --danger: #b3261e; /* Per-type notification accents (inbox). One hue family per type; light values darkened for contrast on light surfaces. */ --t-update: #4747c9; --t-add: #0f8a55; --t-remove: #c2335a; --t-revision: #7a3fd1; --t-propagate: #0d7f8c; --t-pr-open: #1a7f37; --t-pr-merged: #8250df; /* Inbox control surfaces. In light mode these follow the app surfaces; in dark mode they use the redesign's deeper palette — the app's dark surfaces are too light for the inbox controls. */ --ibx-surface: var(--surface); --ibx-surface-2: var(--surface-2); --ibx-surface-3: var(--surface-3); --ibx-line: var(--line); --ibx-line-soft: var(--line-soft); /* Inset panel fill (e.g. expanded option detail). Tracks --surface in light mode; dark mode needs a deeper value — --surface reads too light for large filled areas there. */ --surface-inset: var(--surface); } @media (prefers-color-scheme: dark) { :root:not([data-theme]) { --bg: #080808; --bg-canvas: #080808; --surface: #323437; --surface-2: #404452; --surface-3: #373c4d; --line: #373c4d; --line-soft: #2f3340; --text: #e8e8ec; --text-2: #a8b2c0; --text-3: #8a93a3; --accent: #80a0ff; --accent-on: #080808; --accent-soft: rgba(128, 160, 255, 0.0375); --accent-bg: rgba(128, 160, 255, 0.15); --accent-edge: rgba(128, 160, 255, 0.3); --good: #36c692; --warn: #f0a868; --danger: #f28a82; --t-update: #8a8aff; --t-add: #5fd39a; --t-remove: #f07a92; --t-revision: #b694ff; --t-propagate: #4fc8d4; --t-pr-open: #4ac26b; --t-pr-merged: #b57bff; --ibx-surface: #15151b; --ibx-surface-2: #1c1c24; --ibx-surface-3: #25252f; --ibx-line: #2a2a36; --ibx-line-soft: #1f1f29; --surface-inset: #15151b; } } /* ======================================================================== Base element styles. Selectors here use elements (low specificity) so component styles below win cleanly. ======================================================================== */ html { color-scheme: light dark; /* Keep Safari from independently enlarging prose in individual result rows. */ -webkit-text-size-adjust: 100%; text-size-adjust: 100%; /* Keep centered content from shifting when the scrollbar comes and goes. */ scrollbar-gutter: stable; } body { background: var(--bg); color: var(--text); font-family: var(--sans); font-size: 0.9rem; line-height: 1.5; min-height: 100vh; } h1, h2, h3, h4, h5, h6 { color: var(--text); font-weight: 700; line-height: 1.25; margin: 0 0 0.5rem; } h1 { font-size: 2rem; } h2 { font-size: 1.625rem; } h3 { font-size: 1.375rem; } h4 { font-size: 1.125rem; } h5 { font-size: 1.0625rem; } h6 { font-size: 1rem; } hgroup { margin: 0 0 0.5rem; } hgroup > *:not(:last-child) { margin-bottom: 0.25rem; } hgroup > p { color: var(--text-2); font-weight: 400; } p { margin: 0 0 0.5rem; } a { color: var(--accent); text-decoration: underline; text-decoration-color: var(--accent-edge); text-underline-offset: 2px; } a:hover { text-decoration-color: var(--accent); } ul, ol { margin: 0 0 0.5rem; padding-left: 1.5rem; } dl { margin: 0 0 0.5rem; } dt { font-weight: 600; } dd { margin-left: 0; } hr { border: 0; border-top: 1px solid var(--line); margin: 1rem 0; } code, kbd, samp, pre { font-family: var(--mono); } code, kbd { background: var(--surface-2); color: var(--text); border-radius: var(--radius-sm); padding: 0.125em 0.375em; } pre { background: var(--surface); color: var(--text); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0.75rem 1rem; margin: 0 0 1rem; overflow-x: auto; } pre code { background: transparent; padding: 0; } mark { background: var(--accent-bg); color: var(--text); padding: 0.125em 0.25em; border-radius: var(--radius-sm); } small { font-size: 0.875em; } strong { font-weight: 600; } figure { margin: 0 0 1rem; overflow-x: auto; } .diff-summary { margin: 0 0 1rem; color: var(--text-2); } .diff-summary > div { display: flex; flex-wrap: wrap; gap: 0.5rem; } .diff-summary dt { font-weight: 600; margin: 0; } .diff-summary dd { margin: 0; } /* ======================================================================== Layout — .container ======================================================================== */ .container { width: 100%; margin-inline: auto; padding-inline: 1rem; } @media (min-width: 576px) { .container { max-width: 510px; padding-inline: 1.25rem; } } @media (min-width: 768px) { .container { max-width: 700px; } } @media (min-width: 1024px) { .container { max-width: 950px; } } @media (min-width: 1280px) { .container { max-width: 1200px; } } @media (min-width: 1536px) { .container { max-width: 1450px; } } main.container { padding-block: 1.5rem; } /* ======================================================================== Forms ======================================================================== */ button, input[type="button"], input[type="submit"], input[type="reset"], [role="button"] { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.5rem 1rem; background: var(--accent); color: var(--accent-on); border: 1px solid var(--accent); border-radius: var(--radius-sm); font: inherit; font-weight: 500; line-height: 1.2; text-decoration: none; cursor: pointer; user-select: none; } button:hover, input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover, [role="button"]:hover { filter: brightness(1.1); color: var(--accent-on); text-decoration: none; } button:focus-visible, input[type="button"]:focus-visible, input[type="submit"]:focus-visible, input[type="reset"]:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--accent-edge); outline-offset: 2px; } button:disabled, [role="button"][aria-disabled="true"], button[disabled] { opacity: 0.5; cursor: not-allowed; filter: none; } button.outline, [role="button"].outline { background: transparent; color: var(--accent); } button.outline:hover, [role="button"].outline:hover { background: var(--accent-soft); color: var(--accent); } button.secondary, [role="button"].secondary { background: var(--surface-2); color: var(--text); border-color: var(--line); } button.secondary:hover, [role="button"].secondary:hover { color: var(--text); } button.outline.secondary, [role="button"].outline.secondary { background: transparent; color: var(--text-2); border-color: var(--line); } button.outline.secondary:hover, [role="button"].outline.secondary:hover { background: var(--surface-2); color: var(--text); } button.contrast, [role="button"].contrast { background: var(--text); color: var(--bg); border-color: var(--text); } input, select, textarea { display: block; width: 100%; padding: 0.5rem 0.75rem; background: var(--surface); color: var(--text); border: 1px solid var(--line); border-radius: var(--radius-sm); font: inherit; line-height: 1.5; } input::placeholder, textarea::placeholder { color: var(--text-2); opacity: 1; } input:focus, select:focus, textarea:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-edge); } input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: #a60000; } input[type="search"] { -webkit-appearance: textfield; } input[type="checkbox"], input[type="radio"] { display: inline-block; width: auto; margin-right: 0.5em; padding: 0; vertical-align: middle; accent-color: var(--accent); } input[type="hidden"] { display: none; } select { background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%), linear-gradient(135deg, var(--text-2) 50%, transparent 50%); background-position: calc(100% - 14px) center, calc(100% - 9px) center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 2rem; -webkit-appearance: none; appearance: none; } label { display: block; margin-bottom: 0.25rem; font-weight: 500; } label > input[type="checkbox"], label > input[type="radio"] { margin-right: 0.5em; } fieldset { border: 0; margin: 0 0 1rem; padding: 0; } legend { font-weight: 600; margin-bottom: 0.5rem; } form { margin: 0 0 1rem; } /* ======================================================================== Tables ======================================================================== */ table { width: 100%; border-collapse: collapse; margin: 0 0 1rem; } th, td { padding: 0.5rem 0.75rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line-soft); } th { font-weight: 600; color: var(--text); } /* ======================================================================== Dialog (modal) ======================================================================== */ dialog { display: none; position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 1rem; border: 0; background: rgba(0, 0, 0, 0.5); color: var(--text); z-index: 100; overflow: auto; } dialog[open] { display: flex; align-items: center; justify-content: center; } dialog > .card, dialog > article { width: 100%; max-width: 32rem; } /* ======================================================================== Card — explicit replacement for
-as-card ======================================================================== */ .card { background: var(--surface); color: var(--text); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.25rem; margin: 0 0 1rem; } .card > header { margin: -1rem -1.25rem 1rem; padding: 0.75rem 1.25rem; border-bottom: 1px solid var(--line); } .card > footer { margin: 1rem -1.25rem -1rem; padding: 0.75rem 1.25rem; border-top: 1px solid var(--line); } /* ======================================================================== Details / summary ======================================================================== */ details { margin: 0 0 0.5rem; } summary { cursor: pointer; } summary:focus-visible { outline: 2px solid var(--accent-edge); outline-offset: 2px; } /* ======================================================================== Application styles ======================================================================== */ /* Flash notifications — self-contained card; doesn't rely on
. */ .flash-stack { position: fixed; bottom: 0.5rem; right: 0.5rem; z-index: 90; display: flex; flex-direction: column; gap: 0.5rem; pointer-events: none; } .flash { pointer-events: auto; width: 24rem; max-width: calc(100vw - 1rem); background: var(--surface); color: var(--text); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0.75rem 2.5rem 0.75rem 1rem; margin: 0; cursor: pointer; position: relative; } .flash > p { margin: 0; } .flash > header { margin-bottom: 0.25rem; } .flash[hidden] { display: none; } .flash-auto-dismiss { animation: flash-fade 4.5s ease-out forwards; } @keyframes flash-fade { 0%, 80% { opacity: 1; } 100% { opacity: 0; visibility: hidden; pointer-events: none; } } @media (prefers-reduced-motion: reduce) { .flash-auto-dismiss { animation-duration: 6s; } } .flash-info { background: #ecfff5; border-color: #006800; color: #006800; } .flash-error { background: #fff0f0; border-color: #a60000; color: #a60000; } @media (prefers-color-scheme: dark) { .flash-info { background: #0a2e1f; border-color: #36c692; color: #85dc85; } .flash-error { background: #2e0a0a; border-color: #ff5d5d; color: #ff5d5d; } } .flash .close-button { position: absolute; top: 0.25rem; right: 0.5rem; background: none; border: none; color: inherit; opacity: 0.4; cursor: pointer; padding: 0.25rem; margin: 0; width: auto; } .flash .close-button:hover { opacity: 0.7; } /* Loading states for LiveView */ .phx-click-loading { opacity: 0.75; } .phx-submit-loading { opacity: 0.75; } /* Visually hidden utility */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* Spin animation for reconnect indicator */ @keyframes spin { to { transform: rotate(360deg); } } .animate-spin { animation: spin 1s linear infinite; display: inline-block; } /* Sort header links - inherit header styling for no-JS fallback */ th a { color: inherit; text-decoration: none; } /* Revision link styling */ a.revision-link { font-family: var(--mono); } /* Package revision filters */ .revision-filters { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0; flex-wrap: wrap; } .revision-filters select, .revision-filters input[type="text"] { margin-bottom: 0; padding: 0.25rem 0.5rem; height: auto; width: auto; } .revision-filters button { margin-bottom: 0; padding: 0.25rem 0.5rem; height: auto; width: auto; } .revision-filters label { display: flex; align-items: center; gap: 0.25rem; margin-bottom: 0; white-space: nowrap; cursor: pointer; } .revision-filters label input[type="checkbox"] { margin: 0; } .package-show { display: grid; gap: 1.125rem; } .package-show__identity { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "title actions" "subtitle actions"; gap: 0.375rem 1.5rem; align-items: center; margin: 0; padding: 1.25rem 1.5rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); } .package-show__identity h1 { grid-area: title; margin: 0; } .package-show__identity > p { grid-area: subtitle; margin: 0; color: var(--text-2); } .package-show__identity > div { grid-area: actions; display: flex; gap: 0.5rem; align-items: center; justify-content: end; } .package-show__identity #feed-link { display: inline-flex; gap: 0.375rem; align-items: center; padding: 0.5rem 0.625rem; border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--text-2); font-size: 0.8125rem; font-weight: 500; text-decoration: none; } .package-show__identity #feed-link:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); } .package-show__identity #subscribe-toggle { margin: 0; } .package-show__grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(16rem, 0.9fr); grid-template-areas: "content facts"; gap: 1.125rem; align-items: start; } .package-show__content { display: grid; grid-area: content; gap: 1.125rem; } .package-show__meta { display: grid; grid-area: facts; gap: 0; } .package-show__meta > .package-show__panel + .package-show__panel { margin-top: 1.125rem; } .package-show__panel { border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); overflow: hidden; } .package-show__panel > .package-show__panel-header { margin: 0; padding: 1rem 1.125rem; border-bottom: 1px solid var(--line); } .package-show__description { padding: 1rem 1.125rem; } .package-show__description p { margin: 0; } .package-show__description p + p { margin-top: 1rem; } .package-show__panel > dl { margin: 0; padding: 0 1.125rem; } .package-show__panel > dl > div { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: 0.875rem; padding: 0.6875rem 0; position: relative; } .package-show__panel > dl > div:not(:last-child)::after { content: ""; position: absolute; right: -1.125rem; bottom: 0; left: -1.125rem; height: 1px; background: var(--line-soft); } .package-show__panel > dl dd { margin: 0; overflow-wrap: anywhere; } .package-show__panel > dl dd > span { margin-right: 0.375rem; } .package-show__panel > dl ul { margin: 0; padding: 0; list-style: none; } .package-show__panel > details { margin: 0; padding: 1rem 1.125rem; border-top: 1px solid var(--line); } .package-show__content > section { margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); overflow: hidden; } .package-show__content .section-header { margin: 0; padding: 0.875rem 1.125rem; border-bottom: 1px solid var(--line); } .package-show__content .row-list { border: 0; border-radius: 0; } .package-show__content .pagination { padding: 0 1.125rem 1rem; } .current-versions__selected { margin-left: 0.375rem; color: var(--accent); font-size: 0.75rem; font-weight: 600; } .current-versions__row--selected { background: var(--accent-soft); } #current-versions code { background: transparent; border-radius: 0; padding: 0; } #current-versions .row-meta code { font-weight: 700; } .current-versions__empty { margin: 0; padding: 1rem 1.125rem; color: var(--text-2); } .package-show__revisions > p { margin: 0; padding: 1rem 1.125rem; } @media (max-width: 719px) { .package-show__identity { grid-template-columns: 1fr; grid-template-areas: "title" "subtitle" "actions"; padding: 1rem; } .package-show__identity > div { justify-content: start; flex-wrap: wrap; } .package-show__grid { grid-template-columns: 1fr; grid-template-areas: "content" "facts"; } .package-show__meta > dl > div { grid-template-columns: 6.5rem minmax(0, 1fr); } } /* Sign-in page styling */ .sign-in-banner { text-align: center; margin-top: 3rem; } .sign-in-banner-text { font-weight: bold; margin-bottom: 1.5rem; } .sign-in-oauth { text-align: center; } .sign-in-oauth a { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1.5rem; border: 1px solid var(--line); border-radius: 0.375rem; text-decoration: none; color: var(--text); transition: background-color 0.2s, color 0.2s; } .sign-in-oauth a:hover { background-color: var(--accent); color: var(--accent-on); border-color: var(--accent); } .sign-in-oauth svg { width: 1.25rem; height: 1.25rem; flex-shrink: 0; } /* Options Show (V3). Spec: tmp/design_handoff_options_show/README.md */ .option-show section { margin-bottom: 1.75rem; } .option-show section h2 { font-size: 0.6875rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-2); font-weight: 600; margin: 0 0 8px; } /* Path bar — the breadcrumb header is the page's h1. */ :is(.option-show, .revision-comparison) .opt-pathbar { display: flex; align-items: center; flex-wrap: wrap; padding: 10px 12px; margin: 4px 0 24px; background: var(--bg); max-width: 100%; font-family: var(--mono); font-size: 1.375rem; font-weight: 600; letter-spacing: -0.005em; line-height: 1.2; word-break: break-all; } :is(.option-show, .revision-comparison) .crumb-link, :is(.option-show, .revision-comparison) .crumb-current { padding: 2px 6px; margin: 0 -2px; border-radius: 5px; text-decoration: none; color: var(--text); transition: background 120ms, color 120ms; word-break: break-all; } :is(.option-show, .revision-comparison) a.crumb-link:hover { background: var(--accent-bg); color: var(--accent); text-decoration: none; } :is(.option-show, .revision-comparison) .crumb-current { cursor: default; } :is(.option-show, .revision-comparison) .crumb-sep { color: var(--text-2); font-weight: 500; padding: 0 1px; user-select: none; } .option-show .opt-copy { margin-left: auto; align-self: center; font-size: 0.8125rem; display: inline-flex; align-items: center; gap: 4px; padding: 4px 9px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--text-2); font-family: var(--sans); font-weight: 400; cursor: pointer; text-decoration: none; transition: background 120ms, border-color 120ms, color 120ms; } .option-show .opt-copy:hover { background: var(--surface); border-color: var(--line); color: var(--text); } /* Copied confirmation: swap the icon in place for a same-size check so the button footprint never changes. */ .option-show .opt-check-icon { display: none; } .option-show :is(.opt-copy, .row-action).copied .opt-share-icon { display: none; } .option-show :is(.opt-copy, .row-action).copied .opt-check-icon { display: block; color: var(--good); } /* Section header — the heading above a row list. */ .section-header { display: flex; align-items: center; gap: 0.625rem; flex-wrap: wrap; margin-top: 1.375rem; margin-bottom: 0.5rem; } .section-controls { display: flex; align-items: center; gap: 0.5rem; /* Gecko will shrink this below an inflexible child's width and let the child spill out; Blink will not. Hold the intrinsic size either way. */ flex: none; } /* Too narrow to share the title's line: the controls take one of their own, below the title and count. */ @media (max-width: 48rem) { .section-controls { order: 1; flex-basis: 100%; } } .section-header h2 { margin: 0; font-size: 0.875rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text); } .section-header .rule { flex: 1; height: 1px; background: var(--ibx-line-soft); } .section-header .n { font-family: var(--mono); font-size: 0.6875rem; color: var(--text-3); } /* Row list — the app-wide list idiom: rows sharing one card surface, separated by dividers. */ .row-list { list-style: none; padding: 0; margin: 0; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; } .row-list > li { border-bottom: 1px solid var(--line); scroll-margin-top: 8rem; } .row-list > li:last-child { border-bottom: 0; } .row-list details { /* cancel the base details bottom margin — it shows as a page-background gap between the row and the li border */ margin: 0; } .row-line { padding: 10px 14px; display: grid; /* label, meta, actions — the label shrinks rather than pushing the trailing columns out of the row */ grid-template-columns: minmax(0, 1fr) auto auto; gap: 10px; align-items: baseline; transition: background 120ms; } /* Rows with a leading affordance gain a column for it, and centre their items — a glyph or checkbox has no useful baseline to sit on. */ .row-line--leading { grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; } .row-leading { display: inline-flex; align-items: center; } .row-body { display: flex; flex-direction: column; gap: 0.375rem; min-width: 0; } .row-sublabel { display: flex; align-items: center; gap: 0.5rem; /* one line always, so a long sublabel can't make its row taller than its peers and drift the page's pagination controls */ flex-wrap: nowrap; white-space: nowrap; overflow: hidden; mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent); font-size: 0.75rem; color: var(--text-3); } /* The other half of that: a row with no sublabel reserves the line anyway, so it matches the rows around it. Only in lists that declare an optional sublabel — keying off a sublabel being present on screen would make the reserve depend on the rows a page happened to load. Rows with a sublabel nest their label in .row-body, so a bare .row-label is a row without. */ .row-list--reserve-sublabel .row-line > .row-label::after { content: ""; display: block; font-size: 0.75rem; height: calc(1lh + 0.375rem); } /* Same contract for an optional :meta. Only the stacked layout gives meta a line of its own, so only there does an empty one shorten its row. */ .row-list--reserve-meta .row-meta { min-height: 1lh; } /* Same contract again for a label that runs long. A wrapped label is the last thing left that can make one row taller than its neighbours, so a list whose labels are prose — change titles — clips them to the row instead. Declared, not derived: whether a list's labels run long is a property of the list, and a page that happened to load short ones would otherwise opt itself out. */ .row-list--truncate-label .row-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Single-token labels behind a collapsible prefix — option names. One line at every width: a wrapped tail only spills a fragment of one token, so clipping costs no sense and keeps rows uniform. Its specificity beats the narrow-screen .row-label rule below that would otherwise let the tail wrap. */ .row-list--clip-label .row-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .row-list summary.row-line { list-style: none; cursor: pointer; } .row-list summary::-webkit-details-marker { display: none; } /* Custom marker on the label so the row keeps its grid. Expandable rows only — link and plain rows have nothing to disclose. */ .row-list details .row-label::before { content: "▸"; display: inline-block; color: var(--text-2); font-size: 0.75rem; margin-right: 8px; transition: transform 120ms; } .row-list details[open] .row-label::before { transform: rotate(90deg); } .row-list summary:hover { background: var(--surface); } .row-list details[open] > summary { border-bottom: 1px solid var(--line); } .row-link { text-decoration: none; } .row-link:hover { background: var(--accent-soft); text-decoration: none; } /* Keyboard cursor, all three row modes. Inset because the list clips its overflow — an outset outline is cut off on the first and last rows. */ .row-line:focus-visible { outline: 2px solid var(--accent-edge); outline-offset: -2px; background: var(--surface); } .row-label { font-family: var(--mono); font-weight: 500; font-size: 0.9375rem; color: var(--text); } .row-label .leading { color: var(--text-2); font-weight: 400; } .row-label .tail { color: var(--accent); } /* Leading identifier inside a label — a PR number, a revision hash. Unlike .leading it is never collapsed on narrow screens; it's the row's name. */ .row-num { color: var(--text-2); font-variant-numeric: tabular-nums; } .row-meta { display: inline-flex; align-items: baseline; gap: 12px; font-family: var(--mono); font-size: 0.8125rem; color: var(--text-2); } .row-actions { display: inline-flex; align-items: center; gap: 10px; color: var(--text-2); font-size: 0.8125rem; } /* Link rows keep their actions outside the row link, so they float over its trailing edge instead of taking a grid column. Only a real control catches the pointer — a decorative glyph would otherwise punch a dead spot in the row. */ .row-actions--float { position: absolute; inset-block: 0; right: 14px; pointer-events: none; } .icon-external { width: 1rem; height: 1rem; display: block; } .row-actions--float a, .row-actions--float button { pointer-events: auto; } .row-list > li:has(> .row-actions--float) { position: relative; } .row-list > li:has(> .row-actions--float) > .row-link { padding-right: 3rem; } /* Floating actions centre on the whole row, so the meta beside them has to leave the label's baseline and centre too — otherwise a two-line row shows its date up on the first line and its icon halfway down. */ .row-list > li:has(> .row-actions--float) .row-meta { align-self: center; } .option-show .opt-type { /* long types stay on one line; the full type is in the detail body */ display: inline-block; max-width: 40ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; } /* Row actions on expandable rows stay hidden until hover/open. */ .row-action { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border: 1px solid transparent; border-radius: 6px; color: var(--text-2); background: transparent; font-size: 0.75rem; text-decoration: none; align-self: center; cursor: pointer; transition: background 120ms, border-color 120ms, color 120ms, opacity 120ms; } .row-list summary .row-action { opacity: 0; } .row-list summary:hover .row-action, .row-list summary:focus-within .row-action, .row-list details[open] > summary .row-action { opacity: 1; } .row-action:hover { background: var(--surface); border-color: var(--line); color: var(--text); text-decoration: none; } .option-show .opt-share-icon { display: block; } /* Keep a just-clicked button visible even if the pointer leaves. */ .row-list summary .row-action.copied { opacity: 1; } .option-show .opt-detail { display: grid; grid-template-columns: 110px 1fr; gap: 6px 18px; margin: 0; padding: 12px 14px 16px; font-size: 0.9375rem; background: var(--surface-inset); } .option-show .opt-detail dt { color: var(--text-2); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; padding-top: 2px; } .option-show .opt-detail dd { margin: 0; /* let
 children shrink inside the grid instead of overflowing */
	min-width: 0;
	overflow-wrap: break-word;
}

.option-show .opt-detail .read-only {
	color: var(--text-2);
}

/* File paths render as plain mono text, not code chips. */
.option-show .opt-detail dd code,
.option-show .opt-defined code {
	background: transparent;
	padding: 0;
	border-radius: 0;
}

.option-show .opt-detail pre {
	/* background comes from the linked Lumis theme (pre.lumis) so the
	   token colors and fill always match the active color scheme */
	margin: 0;
	border: 1px solid var(--line);
	border-radius: 6px;
	padding: 8px 10px;
	font-family: var(--mono);
	font-size: 0.8125rem;
	overflow-x: auto;
}

/* Rendered description markdown: paragraphs, inline code chips, links, and
   GFM-alert admonitions (mapped from nixos-render-docs fenced divs). */
.option-show .opt-detail dd .nixos-markdown p {
	margin: 0 0 0.6em;
}

.option-show .opt-detail dd .nixos-markdown p:last-child {
	margin-bottom: 0;
}

.option-show .opt-detail dd .nixos-markdown code {
	background: var(--surface-2);
	padding: 0.125em 0.375em;
	border-radius: var(--radius-sm);
}

.option-show .opt-detail dd .nixos-markdown a {
	color: var(--accent);
}

.option-show .opt-detail dd .nixos-markdown .markdown-alert {
	margin: 0.6em 0;
	padding: 8px 12px;
	border-left: 3px solid var(--accent);
	background: var(--surface-inset);
	border-radius: 0 6px 6px 0;
}

.option-show .opt-detail dd .nixos-markdown .markdown-alert p:first-child {
	margin: 0 0 4px;
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-weight: 600;
}

.option-show .opt-detail dd .nixos-markdown .markdown-alert-tip {
	border-left-color: var(--good);
}

.option-show .opt-detail dd .nixos-markdown .markdown-alert-warning {
	border-left-color: var(--warn);
}

.option-show .opt-detail dd .nixos-markdown .markdown-alert-caution {
	border-left-color: var(--danger);
}

/* Defined in — plain borderless mono rows. */
.option-show .opt-defined {
	list-style: none;
	padding: 0;
	margin: 0;
}

.option-show .opt-defined li {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 7px 0;
	font-family: var(--mono);
	font-size: 0.8125rem;
	margin-bottom: 6px;
}

/* Recent PRs. */
.option-show .opt-prs {
	list-style: none;
	padding: 0;
	margin: 0;
}

.option-show .opt-prs li {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 0;
	border-bottom: 1px solid var(--line-soft);
	font-size: 0.875rem;
}

.option-show .opt-prs li:last-child {
	border-bottom: 0;
}

.option-show .opt-prs .prnum {
	font-family: var(--mono);
	font-weight: 600;
	color: var(--accent);
	text-decoration: none;
}

.option-show .opt-prs .title {
	color: var(--text);
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

@media (max-width: 560px) {
	/* Path bar: smaller type; the copy button keeps margin-left: auto and
	   falls onto its own right-aligned line when the path wraps. */
	.option-show .opt-pathbar {
		font-size: 1.0625rem;
		row-gap: 2px;
	}

	/* Rows: let a long label wrap; keep meta and actions pinned. */
	.row-line {
		gap: 8px;
		align-items: center;
	}

	.row-label {
		min-width: 0;
		/* break inside a word only when it can't fit — attribute paths still
		   wrap, but prose titles break at spaces */
		overflow-wrap: anywhere;
	}

	/* Two lines here rather than one: the label owns the full width in a
	   stacked list, and at this size most change titles overrun a single
	   line, so clipping to one would hide the tail on the majority of rows.
	   Two caps the drift at one line and still fits nearly all of them. */
	.row-list--truncate-label .row-label {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		line-clamp: 2;
		white-space: normal;
	}

	/* Collapse the page-prefix part of a row label to an ellipsis — the
	   path bar already says where we are. font-size: 0 keeps the full text
	   selectable and readable to screen readers. */
	.row-label .leading {
		font-size: 0;
	}

	.row-label .leading::before {
		content: "…";
		font-size: 0.9375rem;
	}

	.row-list summary .row-action {
		/* always visible on touch — no hover to reveal it */
		opacity: 1;
	}

	/* Stacked lists: the label owns the first line, meta and actions share
	   the second — a wide multi-part meta would otherwise crush the label
	   to a couple of characters per line. */
	.row-list--stacked .row-line {
		grid-template-columns: minmax(0, 1fr) auto;
		row-gap: 6px;
	}

	/* .row-body is the grid item when a row has a sublabel; .row-label is
	   the item when it doesn't. */
	.row-list--stacked > li .row-label,
	.row-list--stacked > li .row-body {
		grid-column: 1 / -1;
	}

	/* A leading affordance keeps its own column and the label sits beside it,
	   so the trailing content drops to a second line aligned under the label
	   rather than under the glyph. */
	.row-list--stacked .row-line--leading {
		grid-template-columns: auto minmax(0, 1fr);
	}

	.row-list--stacked > li .row-line--leading .row-label,
	.row-list--stacked > li .row-line--leading .row-body,
	.row-list--stacked > li .row-line--leading .row-meta {
		grid-column: 2 / -1;
	}

	.row-list--stacked .row-actions {
		justify-content: flex-end;
	}

	/* The type tag is clutter at this width, and the detail body has it. */
	.option-show summary .row-meta {
		display: none;
	}

	/* Option detail: stack dt above dd in one column. */
	.option-show .opt-detail {
		grid-template-columns: 1fr;
		gap: 2px 0;
	}

	.option-show .opt-detail dt {
		padding-top: 10px;
	}

	.option-show .opt-detail dt:first-child {
		padding-top: 0;
	}

	/* Defined-in: wrap long paths instead of overflowing. */
	.option-show .opt-defined li {
		word-break: break-all;
	}

	/* PR rows: let the title wrap rather than ellipsize away. */
	.option-show .opt-prs li {
		flex-wrap: wrap;
	}

	.option-show .opt-prs .title {
		flex: 1 1 100%;
		order: 3;
		white-space: normal;
		overflow: visible;
	}
}

/* App chrome.
   Spec: tmp/design_handoff_nav_lens_search/README.md */

/* Strip base form/button styling inside chrome — the rules below own
   the look entirely. */
.app-header :is(input, select, button) {
	appearance: none;
	background: transparent;
	background-image: none;
	border: 0;
	box-shadow: none;
	outline: 0;
	margin: 0;
	padding: 0;
	height: auto;
	min-height: 0;
	width: auto;
	color: inherit;
	font: inherit;
	line-height: inherit;
}

.app-header :is(input, select, button):focus {
	box-shadow: none;
	background: transparent;
	outline: 0;
}

.app-header a {
	color: inherit;
	text-decoration: none;
}

.app-header a:hover {
	text-decoration: none;
}

/* Outer chrome — single bottom border */
.app-header {
	background: var(--bg);
	border-bottom: 1px solid var(--line);
}

/* Row 1 — brand · tabs · user. Flush bottom so tab underline aligns. */
.app-header__row--top {
	padding-top: 0.75rem;
}

.app-header__row--top > .container {
	display: flex;
	align-items: center;
	gap: 1.125rem;
}

/* Row 2 — search · lens */
.app-header__row--bottom {
	padding: 0.75rem 0 0.875rem;
}

.app-header__row--bottom > .container {
	display: flex;
	align-items: stretch;
	gap: 0.75rem;
	min-height: 2.5rem;
}

/* Brand */
.app-brand {
	display: inline-flex;
	align-items: center;
	gap: 0.5625rem;
	color: var(--text);
	font-weight: 600;
	letter-spacing: -0.01em;
	flex-shrink: 0;
}

.app-brand:hover {
	color: var(--text);
}

.app-brand__mark {
	width: 1.5rem;
	height: 1.5rem;
	flex-shrink: 0;
	overflow: visible;
}

/* Tabs — each tab carries its own horizontal padding; gap between tabs is 0 */
.app-tabs {
	display: inline-flex;
	align-items: center;
	gap: 0;
	list-style: none;
	margin: 0;
	padding: 0;
}

.app-tabs li {
	margin: 0;
	padding: 0;
}

.app-tabs a {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.875rem;
	color: var(--text-2);
	font-weight: 500;
	line-height: 1;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
}

.app-tabs a:hover {
	color: var(--text);
}

.app-tabs a[aria-current="page"] {
	color: var(--text);
	border-bottom-color: var(--accent);
}

/* Single nav source — desktop shows full labels and both/desktop items */
.app-tab__short {
	display: none;
}

.app-tabs .is-mobile-only {
	display: none;
}

/* Inbox icon — replaces the Inbox text tab. Carries the unread badge. */
.app-inbox {
	position: relative;
	margin-left: auto;
	width: 2.375rem;
	height: 2.375rem;
	border-radius: 0.625rem;
	display: grid;
	place-items: center;
	flex-shrink: 0;
	color: var(--text-2);
	background: var(--ibx-surface);
	border: 1px solid var(--ibx-line);
	transition:
		background 0.12s,
		color 0.12s;
}

.app-inbox:hover {
	background: var(--ibx-surface-2);
	color: var(--text);
}

.app-inbox[aria-current="page"] {
	background: var(--ibx-surface-2);
	color: var(--text);
	border-color: var(--ibx-line);
}

.app-inbox__icon {
	width: 1.25rem;
	height: 1.25rem;
}

.app-inbox__badge {
	position: absolute;
	top: -0.3125rem;
	right: -0.3125rem;
	min-width: 1.125rem;
	height: 1.125rem;
	padding: 0 0.25rem;
	border-radius: 0.5625rem;
	background: var(--accent);
	color: var(--accent-on);
	font-family: var(--mono);
	font-size: 0.65625rem;
	font-weight: 700;
	line-height: 1;
	display: grid;
	place-items: center;
	border: 2px solid var(--bg);
}

/* The user chip no longer needs to push itself right; the inbox icon does. */
.app-inbox + .app-user {
	margin-left: 0;
}

/* Mobile-only chrome: the lens-row bell, avatar disclosure, and sign-in
   icon. Hidden here; the mobile media block turns them on. */
.app-inbox--mobile,
.app-user--mobile,
.app-signin--mobile {
	display: none;
}

/* Desktop: the wrapper is transparent so the lens slot stays a direct flex
   item of the bottom row, exactly as before the mobile lens row existed. */
.app-header__lens-row {
	display: contents;
}

/* User chip */
.app-user {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
}

.app-user__menu {
	position: relative;
	/* Cancel the base `details` bottom margin; it pushes the chip above the
	   header row's center line. */
	margin: 0;
}

.app-user__chip {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.375rem 0.875rem;
	background: var(--ibx-surface);
	border: 1px solid var(--ibx-line);
	border-radius: var(--radius-sm);
	color: var(--text);
	font-weight: 500;
	cursor: pointer;
	list-style: none;
	position: relative;
	z-index: 51;
}

.app-user__chip::-webkit-details-marker {
	display: none;
}

.app-user__chip:hover .app-user__name,
.app-user__chip:hover .app-user__caret {
	color: var(--accent);
}

.app-user__menu[open] .app-user__chip {
	background: var(--bg);
	border-color: var(--line-soft);
	border-bottom-color: var(--bg);
	border-bottom-left-radius: 0;
	border-bottom-right-radius: 0;
}

.app-user__avatar {
	display: block;
	width: 1.5rem;
	height: 1.5rem;
	border-radius: 999px;
	background: var(--ibx-surface-2);
	object-fit: cover;
}

.app-user__avatar--monogram {
	display: inline-grid;
	place-items: center;
	color: var(--text);
	font-family: var(--mono);
	font-size: 0.625rem;
	font-weight: 600;
}

.app-user__caret {
	color: var(--text-3);
	transition: transform 0.15s ease;
	margin-left: auto;
}

.app-user__menu[open] .app-user__caret {
	transform: rotate(180deg);
}

.app-user__panel {
	position: absolute;
	top: calc(100% - 1px);
	right: 0;
	min-width: 100%;
	background: var(--bg);
	border: 1px solid var(--line-soft);
	border-radius: var(--radius-sm);
	border-top-right-radius: 0;
	box-shadow: none;
	padding: 0.5rem;
	z-index: 50;
}

.app-user__panel button,
.app-user__menu-item {
	display: block;
	width: 100%;
	text-align: left;
	padding: 0.5rem 0.875rem;
	background: transparent;
	border: 0;
	border-radius: calc(var(--radius-sm) - 2px);
	color: var(--text-2);
	font: inherit;
	font-size: 0.9375rem;
	font-weight: 400;
	text-decoration: none;
	cursor: pointer;
}

.app-user__panel button:hover,
.app-user__menu-item:hover {
	background: var(--surface-2);
	filter: none;
	color: var(--text);
	text-decoration: none;
}

/* Search input — row 2 */
.app-search {
	flex: 1;
	display: flex;
	align-items: center;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: 0.625rem;
	margin-bottom: 0;
	min-height: 2.25rem;
	color: var(--text-3);
	font-size: 1rem;
	cursor: text;
}

.app-search:focus-within {
	border-color: var(--accent);
	background: var(--surface-2);
}

.app-search__icon {
	width: 1.0625rem;
	height: 1.0625rem;
	color: var(--text-2);
	flex-shrink: 0;
}

/* .app-search prefix outranks the chrome reset above, which would
   otherwise zero the padding (.app-header :is(input, select, button)). */
.app-search .app-search__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	align-self: stretch;
	padding: 0 0.3125rem 0 0.875rem;
	margin: 0;
	border: 0;
	background: transparent;
	color: inherit;
	cursor: pointer;
	flex-shrink: 0;
}

.app-search__submit:disabled {
	cursor: default;
}

/* The label fills the rest of the box so a click anywhere inside it
   natively focuses the input — no JS, no dead zones (trk-305). */
.app-search__field {
	flex: 1;
	display: flex;
	align-items: center;
	align-self: stretch;
	gap: 0.625rem;
	padding: 0.625rem 0.75rem 0.625rem 0.3125rem;
	margin: 0;
	font-weight: inherit;
	cursor: inherit;
}

.app-search input[type="search"] {
	flex: 1;
	color: var(--text);
	font: inherit;
	background-image: none;
}

.app-search input[type="search"]::placeholder {
	color: var(--text-3);
}

.app-search .app-search__clear {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.375rem;
	height: 1.375rem;
	border-radius: 999px;
	color: var(--text-2);
	flex-shrink: 0;
}

.app-search .app-search__clear:hover {
	background: var(--surface-2);
	color: var(--text);
}

.app-search__hint {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.25rem;
	height: 1.25rem;
	padding: 0 0.375rem;
	background: var(--surface-2);
	border: 1px solid var(--line);
	border-bottom-width: 2px;
	border-radius: 0.25rem;
	font-family: var(--mono);
	color: var(--text-2);
	flex-shrink: 0;
}

/* Inert search (channel pages): visibly dead, not just unresponsive. */
.app-search--inert {
	background: var(--surface-2);
	cursor: not-allowed;
	opacity: 0.5;
}

.app-search--inert:focus-within {
	border-color: var(--line);
	background: var(--surface-2);
}

/* The whole box already fades; keep the button from fading twice. */
.app-search--inert .app-search__submit,
.app-search--inert .app-search__field,
.app-search--inert input[type="search"] {
	cursor: not-allowed;
	opacity: 1;
}

/* The "/" shortcut can't focus a disabled input — don't advertise it. */
.app-search--inert .app-search__hint {
	display: none;
}

/* Lens chip — divided pill */
.app-header__lens-slot {
	display: flex;
	align-items: stretch;
}

.lens {
	display: flex;
	flex-shrink: 0;
}

/* Draws the eye to the channel picker when a page needs a specific channel.
   Pure CSS so it also works on dead renders (anonymous visitors load no JS). */
@media (prefers-reduced-motion: no-preference) {
	.lens-attention .lens__form {
		animation: lens-pulse 1.6s ease-in-out 3;
	}
}

.lens-attention .lens__form {
	border-color: var(--accent);
}

@keyframes lens-pulse {
	0%,
	100% {
		box-shadow: 0 0 0 0 transparent;
	}

	50% {
		box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 35%, transparent);
	}
}

.lens__form {
	position: relative;
	display: inline-flex;
	align-items: stretch;
	flex: 1;
	border: 1px solid var(--line);
	border-radius: 0.5rem;
	background: var(--surface);
	overflow: hidden;
	margin-bottom: 0;
}

.lens-label {
	display: inline-flex;
	align-items: center;
	padding: 0.3125rem 0.625rem;
	background: var(--surface-2);
	border-right: 1px solid var(--line);
	color: var(--text-3);
	font-family: var(--mono);
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.lens-channel-cell {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.3125rem 0.625rem;
}

.lens-channel-name {
	color: var(--text);
	font-family: var(--mono);
	font-weight: 500;
	white-space: nowrap;
}

.lens-dot {
	width: 0.375rem;
	height: 0.375rem;
	border-radius: 999px;
	background: var(--accent);
	flex-shrink: 0;
}

/* The invisible select covers the pill while the visible cells size it to
   the selected channel rather than the widest native option. */
.lens__form .lens__select {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
	opacity: 0;
	cursor: pointer;
}

/* The select is an invisible overlay, so a ring on it would never show. Put it
   on the pill instead, or focusing the lens looks like nothing happened. */
.lens__form:has(.lens__select:focus-visible) {
	outline: 2px solid var(--accent-edge);
	outline-offset: 2px;
}

/* Disabled lens (channel pages): the disabled attribute sits on the
   invisible overlay select, so grey the whole pill explicitly. */
.lens__form.lens--disabled {
	background: var(--surface-2);
	cursor: not-allowed;
	opacity: 0.5;
}

.lens--disabled .lens__select {
	cursor: not-allowed;
}

/* The whole pill already fades; keep the button from fading twice. */
.lens--disabled .lens__submit:disabled {
	cursor: not-allowed;
	opacity: 1;
}

.lens--disabled .lens-dot {
	background: var(--text-3);
}

.lens-rev {
	display: inline-flex;
	align-items: center;
	padding: 0.3125rem 0.625rem;
	border-left: 1px solid var(--line);
	color: var(--text-2);
	font-family: var(--mono);
}

.pagination-button {
	padding: 0.25rem 0.75rem;
	font-size: 0.875rem;
	text-decoration: none;
}

.pagination-button[aria-disabled="true"] {
	opacity: 0.5;
	pointer-events: none;
}

/* Scoped under .lens__form to out-specify the .app-header control reset
   (`.app-header :is(input, select, button)`, specificity 0,1,1). */
.lens__form .lens__submit {
	position: relative;
	z-index: 2;
	padding: 0.3125rem 0.875rem 0.3125rem 0.625rem;
	color: var(--text-2);
	cursor: pointer;
	/* keep the arrow pinned to the pill's right edge; spare width in a
	   stretched form collects before it, not between the cells */
	margin-left: auto;
}

.lens__form .lens__submit:hover:not(:disabled) {
	color: var(--text);
}

.lens__icon {
	width: 1.0625rem;
	height: 1.0625rem;
	flex-shrink: 0;
	background: currentColor;
	-webkit-mask: url("/images/arrow-forward.svg") center / contain no-repeat;
	mask: url("/images/arrow-forward.svg") center / contain no-repeat;
}

@media (max-width: 719px) {
	/* Identity moves off the top row on mobile: the user chip and inbox icon
	   re-render as the search-row avatar and the lens-row bell. The brand
	   stays, compacted into the home mark at the head of the tab strip. */
	.app-header__row--top .app-user,
	.app-header__row--top .app-inbox {
		display: none;
	}

	.app-header__row--top > .container {
		gap: 0.75rem;
	}

	/* Brand → home mark: glyph-only in a 30px surface box, pinned left of
	   the scrolling strip (per the navbar_header handoff). */
	.app-brand__word {
		display: none;
	}

	.app-brand__mark {
		width: 1.875rem;
		height: 1.875rem;
		padding: 0.3125rem;
		border-radius: 0.5rem;
		background: var(--ibx-surface);
		border: 1px solid var(--ibx-line);
	}

	/* The nav anchors both the right-edge fade and the More dropdown panel,
	   so neither lives inside the scroller's clip. */
	.app-nav {
		flex: 1;
		min-width: 0;
		position: relative;
	}

	.app-nav::after {
		content: "";
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		width: 1.25rem;
		background: linear-gradient(90deg, transparent, var(--bg));
		pointer-events: none;
	}

	.app-tab__full {
		display: none;
	}

	.app-tab__short {
		display: inline;
	}

	.app-tabs .is-desktop-only {
		display: none;
	}

	/* "More" rides at the end of the strip. */
	.app-tabs .is-mobile-only {
		display: flex;
		margin-left: auto;
	}

	/* Horizontally scrollable strip; the fade above hints at the overflow. */
	.app-tabs {
		display: flex;
		width: 100%;
		gap: 1.25rem;
		overflow-x: auto;
		scrollbar-width: none;
		padding-right: 1.25rem;
	}

	.app-tabs::-webkit-scrollbar {
		display: none;
	}

	.app-tabs li {
		flex: none;
		display: flex;
		/* Fixed height so every cell matches: the More cell's 
wrapper is otherwise ~8px taller than the plain tab cells, which the row's centering turns into a vertical misalignment. */ height: 2.75rem; } /* Underline the active tab like desktop: keep the base rule's transparent bottom border (it turns accent for aria-current=page at any width) so the underline spans the whole tab and sits at the tab's bottom edge. */ .app-tabs a { flex: none; font-size: 0.9375rem; white-space: nowrap; padding: 0.375rem 0; margin-bottom: 0; } /* "More" tab is a native
disclosure: the summary looks like a tab, the panel drops down beneath it (no JS needed). Static so the panel positions against .app-nav, escaping the strip's overflow clip. */ .app-more { position: static; flex: none; display: flex; } .app-more__summary { flex: 1; display: flex; align-items: center; justify-content: center; gap: 0.25rem; min-height: 2.75rem; padding: 0.375rem 0; color: var(--text-2); font-size: 0.9375rem; font-weight: 500; line-height: 1; white-space: nowrap; list-style: none; cursor: pointer; border-bottom: 2px solid transparent; } .app-more__summary::-webkit-details-marker { display: none; } .app-more__summary:hover { color: var(--text); } .app-more__summary[aria-current="page"] { color: var(--text); border-bottom-color: var(--accent); } .app-more__caret { font-size: 0.7em; } .app-more__panel { position: absolute; top: 100%; right: 0; z-index: 60; min-width: 10rem; padding: 0.3125rem; background: var(--bg); border: 1px solid var(--line); border-radius: 0.625rem; box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.18); } .app-more__panel a { display: flex; align-items: center; justify-content: flex-start; min-height: 2.5rem; padding: 0.375rem 0.75rem; color: var(--text-2); font-weight: 500; /* Panel items are a stacked menu, not tabs — no tab underline. */ border-bottom: 0; border-radius: 0.5rem; } .app-more__panel a:hover { color: var(--text); background: var(--surface); } .app-more__panel a[aria-current="page"] { color: var(--accent); } .app-header__row--bottom > .container { flex-wrap: wrap; gap: 0.625rem; } /* Search and lens sit at the same 2.5rem height as the avatar and bell that share their rows. */ .app-search { flex: 1; min-width: 0; height: 2.5rem; } .app-search__field { padding-top: 0; padding-bottom: 0; } .app-search__hint { display: none; } /* Search-row identity: a 40px avatar opening the account menu, or a 40px person icon linking to sign-in. */ .app-user--mobile { display: block; flex-shrink: 0; } .app-user--mobile .app-user__chip { padding: 0; border: 0; border-radius: 999px; } .app-user--mobile[open] .app-user__chip { background: transparent; border-color: transparent; border-radius: 999px; } .app-user--mobile .app-user__avatar { width: 2.5rem; height: 2.5rem; border: 1px solid var(--ibx-line); } .app-user--mobile .app-user__avatar--monogram { font-size: 0.875rem; } .app-user--mobile .app-user__panel { top: calc(100% + 0.375rem); min-width: 11rem; border-radius: var(--radius-sm); box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.18); } .app-signin--mobile { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; flex-shrink: 0; border-radius: 999px; background: var(--ibx-surface); border: 1px solid var(--ibx-line); color: var(--text-2); } .app-signin--mobile .svg-icon { width: 1.3125rem; height: 1.3125rem; } /* Lens row: full-width chip beside the inbox bell (signed in). The bell keeps the base margin-left:auto so it hugs the right edge even on pages with no lens. */ .app-header__lens-row { display: flex; align-items: center; flex: 1 1 100%; gap: 0.625rem; } .app-header__lens-slot { flex: 1; min-width: 0; } .app-inbox--mobile { display: grid; width: 2.5rem; height: 2.5rem; flex-shrink: 0; border-radius: 0.6875rem; background: var(--ibx-surface); border-color: var(--ibx-line); } .lens { flex: 1; } .lens__form { display: flex; width: 100%; min-height: 2.5rem; } /* The label doesn't fit alongside the revision display; the dot + channel name carry the meaning (the select keeps its aria-label). */ .lens-label { display: none; } } .change-show { display: grid; gap: 1.125rem; } .change-show__identity { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.55rem 1.5rem; align-items: center; padding: 1.25rem 1.5rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); } .change-show__identity h1 { grid-column: 1; margin: 0; letter-spacing: -0.02em; } .change-show__status { grid-column: 1; grid-row: 2; display: flex; align-items: center; } .change-show__identity #subscribe-toggle { grid-column: 2; grid-row: 1 / 3; margin: 0; } .change-show__pr-link { display: inline-flex; align-items: center; gap: 0.3em; white-space: nowrap; font-family: var(--mono); font-weight: 500; color: var(--accent); } .change-show__identity .change-show__pr-link { margin-left: 0.4rem; vertical-align: middle; font-size: 0.5em; letter-spacing: 0; text-decoration: none; } .change-show__identity .change-show__pr-link:hover { text-decoration: underline; text-underline-offset: 2px; } .change-show__pr-link .icon-external { width: 1em; height: 1em; } /* Shared accent pill (change list/show state, inbox type chip). Tinted background derives from --pill-color so each theme's accent values carry through to dark mode automatically. */ .pill { display: inline-flex; align-items: center; gap: 0.375rem; padding: 2px 0.5625rem 2px 0.4375rem; border-radius: 999px; font-size: 0.71875rem; font-weight: 600; letter-spacing: 0.01em; line-height: 1.5; white-space: nowrap; color: var(--pill-color, var(--accent)); background: color-mix( in srgb, var(--pill-color, var(--accent)) 14%, transparent ); } .pill .dot { width: 0.375rem; height: 0.375rem; border-radius: 50%; background: var(--pill-color, var(--accent)); } .pill--lg { gap: 0.4rem; padding: 0.25rem 0.7rem; font-size: 0.85rem; } .pill--lg .dot { width: 0.5rem; height: 0.5rem; } .pill-merged { --pill-color: var(--t-revision); } .pill-open { --pill-color: var(--t-add); } .pill-closed { --pill-color: var(--t-remove); } .pill-draft { --pill-color: var(--text-3); } .pill-removed { --pill-color: var(--t-remove); } .pill-landed { --pill-color: var(--t-propagate); } .change-filters label { display: flex; align-items: center; gap: 0.35rem; margin-bottom: 0; white-space: nowrap; cursor: pointer; } .change-filters label input[type="checkbox"] { margin: 0; } .sub-events { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.9rem; margin-bottom: 1rem; padding: 0.6rem 0.85rem; border: 1px solid var(--line-soft); border-radius: 8px; background: var(--surface); font-size: 0.9rem; } .sub-events__label { color: var(--text-2); margin-right: 0.25rem; } .sub-events label { display: flex; align-items: center; gap: 0.35rem; margin-bottom: 0; white-space: nowrap; cursor: pointer; } .sub-events label input[type="checkbox"] { margin: 0; } .change-show__grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(16rem, 0.9fr); gap: 1.125rem; align-items: start; } .change-show__content, .change-show__aside { display: grid; gap: 1.125rem; min-width: 0; align-content: start; } .change-show__panel { min-width: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); } .change-show__panel > .section-header { margin: 0; padding: 1rem 1.125rem; border-bottom: 1px solid var(--line); } .change-show__propagation > .section-header { padding-bottom: 0.5rem; border-bottom: 0; } .change-show__reach { font-family: var(--mono); font-size: 0.6875rem; color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; } .change-show__dag { padding: 0.35rem 1.125rem 1.25rem; } .change-show__dag .propagation-dag { display: block; max-width: 100%; height: auto; margin: auto; } .change-show__dag .propagation-dag a { text-decoration: none; } .change-show__dag .propagation-dag text { font-size: 12px; font-family: var(--mono); } .change-show__tree { display: none; } .change-show__panel .row-list { border: 0; border-radius: 0; } .change-show__panel .pagination { padding: 0 1.125rem 1rem; } .change-show .section-controls form { width: 320px; max-width: 100%; margin: 0; } .change-show .section-controls form input[type="search"] { margin: 0; } .change-show__notice { margin: 0; padding: 1rem 1.125rem; border: 1px solid var(--line); border-radius: var(--radius); color: var(--text-2); } .change-show__more { margin: 0; padding: 1rem 1.125rem; border-top: 1px solid var(--line); color: var(--text-2); } .change-show__panel > dl { margin: 0; padding: 0 1.125rem; } .change-show__panel > dl > div { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: 0.875rem; position: relative; padding: 0.6875rem 0; } .change-show__panel > dl > div:not(:last-child)::after { content: ""; position: absolute; right: -1.125rem; bottom: 0; left: -1.125rem; height: 1px; background: var(--line-soft); } .change-show__panel > dl dt { font-weight: 500; } .change-show__panel > dl dd { min-width: 0; margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; } .change-show__meta .change-show__pr-link { font-size: 0.8125rem; } .change-show__chips { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 1rem 1.125rem; } .change-show .label-chip { display: inline-flex; padding: 0.25rem 0.625rem; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--text-2); font-size: 0.75rem; line-height: 1.4; } .change-show__job pre { margin: 0; padding: 1rem 1.125rem; overflow-wrap: anywhere; white-space: pre-wrap; } .change-show__job > button { margin: 1rem 1.125rem; } .change-show .mono { font-family: var(--mono); } @media (max-width: 719px) { .change-show__identity { grid-template-columns: 1fr; padding: 1rem; } .change-show__identity h1 { font-size: 1.375rem; line-height: 1.22; text-wrap: pretty; overflow-wrap: anywhere; } .change-show__identity #subscribe-toggle { grid-column: 1; grid-row: 3; justify-self: start; margin-top: 0.25rem; } .change-show__grid { grid-template-columns: 1fr; } .change-show__dag { display: none; } .change-show__tree { display: block; padding: 0 1.125rem 1rem; } .change-show__panel > dl > div { grid-template-columns: 6.5rem minmax(0, 1fr); } /* Branch tree — nested
    with CSS elbow connectors. */ .change-show .m4-tree, .change-show .m4-tree ul { list-style: none; padding: 0; margin: 0; } .change-show .m4-tree { display: block; padding: 0.25rem 0 0.125rem; } .change-show .m4-tree ul { position: relative; padding-left: 1.625rem; } .change-show .m4-tree ul::before { content: ""; position: absolute; left: 13px; top: -4px; bottom: 0; width: 2px; background: var(--line); } .change-show .m4-tree ul.is-live::before { background: var(--accent); } .change-show .m4-tree li { position: relative; } .change-show .m4-tree ul > li::before { content: ""; position: absolute; left: -13px; top: 0; width: 15px; height: 24px; border-left: 2px solid var(--line); border-bottom: 2px solid var(--line); border-bottom-left-radius: 10px; } .change-show .m4-tree ul.is-live > li::before { border-left-color: var(--accent); } .change-show .m4-tree ul.is-live > li.is-done::before { border-color: var(--accent); } .change-show .m4-tree ul > li:last-child::after { content: ""; position: absolute; left: -14px; top: 24px; bottom: -2px; width: 4px; background: var(--bg); } .change-show .m4-row { display: grid; grid-template-columns: 28px 1fr; align-items: center; gap: 0.625rem; padding: 0.5rem 0; position: relative; z-index: 1; } .change-show .m4-row-body { min-width: 0; } .change-show .m4-node { width: 28px; height: 28px; border-radius: 999px; display: flex; align-items: center; justify-content: center; border: 2px solid var(--line); background: var(--bg); color: var(--text-2); font-size: 13px; font-weight: 700; } .change-show .m4-tree li.is-done > .m4-row .m4-node { background: var(--accent); border-color: var(--accent); color: var(--accent-on); } .change-show .m4-tree li.is-mine > .m4-row .m4-node { box-shadow: 0 0 0 3px var(--accent-edge); } .change-show .m4-node-name { font-family: var(--mono); font-size: 0.84375rem; font-weight: 600; line-height: 1.2; word-break: break-all; } .change-show .m4-node-name a { color: inherit; text-decoration: none; } .change-show .m4-tree li:not(.is-done) > .m4-row .m4-node-name { color: var(--text-2); font-weight: 500; } .change-show .m4-tree li.is-mine > .m4-row .m4-node-name::after { content: " · Lens"; color: var(--accent); font-family: var(--sans); font-size: 0.59375rem; font-weight: 700; letter-spacing: 0.08em; margin-left: 0.25rem; } .change-show .m4-node-sub { font-size: 0.65625rem; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.06em; margin-top: 0.125rem; font-weight: 600; } } /* ======================================================================== Badges — inline status pills. ======================================================================== */ .badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.0625rem 0.5rem; border-radius: 999px; font-size: 0.75rem; font-weight: 500; line-height: 1.4; border: 1px solid transparent; white-space: nowrap; } .badge--neutral { background: var(--surface-2); color: var(--text-2); border-color: var(--line); } .badge--ok { background: color-mix(in srgb, var(--good) 12%, transparent); color: var(--good); border-color: color-mix(in srgb, var(--good) 35%, transparent); } .badge--warn { background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); } .badge--danger { background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, transparent); } /* ======================================================================== Inbox — triage view. Spec: tmp/design_handoff_inbox_redesign/README.md ======================================================================== */ .ibx { max-width: 51.25rem; margin: 0 auto; } .ibx-icon { width: 1rem; height: 1rem; display: block; } /* Toolbar: segment · actions · full-width filter chip row */ .ibx-toolbar { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; padding-bottom: 0.875rem; margin-bottom: 0.375rem; border-bottom: 1px solid var(--ibx-line-soft); } .ibx-seg { display: inline-flex; background: var(--ibx-surface); border: 1px solid var(--ibx-line); border-radius: 0.5rem; padding: 2px; gap: 2px; } .ibx-toolbar .ibx-seg :is(button, a) { border: 0; background: transparent; color: var(--text-2); font-size: 0.78125rem; font-weight: 500; padding: 0.3125rem 0.6875rem; border-radius: 0.375rem; cursor: pointer; display: inline-flex; align-items: center; gap: 0.375rem; text-decoration: none; } .ibx-toolbar .ibx-seg :is(button, a):hover { filter: none; color: var(--text); } .ibx-seg button .n { font-family: var(--mono); font-size: 0.6875rem; color: var(--text-3); } .ibx-toolbar .ibx-seg :is(button, a).is-active { background: var(--ibx-surface-3); color: var(--text); } .ibx-seg button.is-active .n { color: var(--accent); } .ibx-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 0.5rem; } .ibx-toolbar .ibx-btn { display: inline-flex; align-items: center; gap: 0.4375rem; padding: 0.375rem 0.75rem; border-radius: 0.5rem; border: 1px solid var(--ibx-line); background: var(--ibx-surface); color: var(--text); font-size: 0.78125rem; font-weight: 500; cursor: pointer; } .ibx-toolbar .ibx-btn .ibx-icon { width: 0.875rem; height: 0.875rem; color: var(--text-2); } .ibx-toolbar .ibx-btn--primary { background: var(--accent-bg); border-color: var(--accent-edge); color: var(--text); } .ibx-toolbar .ibx-btn--primary:hover:not(:disabled) { filter: none; background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--text); } .ibx-iconbtn { width: 2rem; height: 2rem; border-radius: 0.5rem; border: 1px solid var(--ibx-line); background: var(--ibx-surface); color: var(--text-2); display: grid; place-items: center; cursor: pointer; list-style: none; } .ibx-iconbtn:hover { border-color: var(--ibx-surface-3); color: var(--text); } /* Copy-on-click feedback: a transient "Copied!" bubble above the control. */ .is-copied { position: relative; } .is-copied::after { content: "Copied!"; position: absolute; bottom: calc(100% + 0.375rem); left: 50%; transform: translateX(-50%); z-index: 20; background: var(--ibx-surface-3); color: var(--text); font-size: 0.6875rem; font-weight: 600; padding: 0.125rem 0.375rem; border-radius: 0.25rem; white-space: nowrap; pointer-events: none; } /* Notifications feed controls on the settings page. */ .settings-feed { display: flex; align-items: center; gap: 0.5rem; } .settings-feed__copy { display: grid; place-items: center; } .settings-feed__revealed { margin-top: 0.75rem; } .settings-feed__revealed #feed-url { flex: 1; min-width: 0; font-family: monospace; } /* Type filter chips — own full-width row inside the toolbar */ .ibx-filters { display: inline-flex; gap: 0.375rem; flex-wrap: wrap; flex-basis: 100%; order: 2; margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--ibx-line-soft); } .ibx-filters .ibx-chip { display: inline-flex; align-items: center; gap: 0.4375rem; padding: 0.3125rem 0.6875rem 0.3125rem 0.5625rem; border-radius: 999px; background: var(--ibx-surface); border: 1px solid var(--ibx-line); color: var(--text-2); font-size: 0.78125rem; font-weight: 500; cursor: pointer; transition: border-color 0.12s, background 0.12s, color 0.12s; } .ibx-filters .ibx-chip:hover { filter: none; border-color: var(--ibx-surface-3); color: var(--text); } .ibx-chip .swatch { width: 0.5rem; height: 0.5rem; border-radius: 50%; } .ibx-chip .n { font-family: var(--mono); font-size: 0.6875rem; color: var(--text-3); } .ibx-filters .ibx-chip.is-active { background: var(--accent-bg); border-color: var(--accent-edge); color: var(--text); } .ibx-chip.is-active .n { color: var(--accent); } .ibx-t-update { background: var(--t-update); } .ibx-t-add { background: var(--t-add); } .ibx-t-remove { background: var(--t-remove); } .ibx-t-revision { background: var(--t-revision); } .ibx-t-propagate { background: var(--t-propagate); } .ibx-t-pr-open { background: var(--t-pr-open); } .ibx-t-pr-merged { background: var(--t-pr-merged); } /* Notification rows */ /* Unread = full opacity + right dot; read rows dim back (single indicator). */ .ibx li.is-read { opacity: 0.72; transition: opacity 0.12s; } .ibx li.is-read:hover { opacity: 1; } /* Inbox rows pack their trailing dot and actions tighter than the shared row gap. */ .ibx .row-actions { gap: 0.25rem; } .ibx-glyph { width: 1.875rem; height: 1.875rem; border-radius: 0.5625rem; display: grid; place-items: center; background: color-mix(in srgb, var(--type-color) 16%, transparent); color: var(--type-color); flex-shrink: 0; } .ibx-attr, .ibx-title { font-family: var(--mono); color: var(--text); font-size: 0.84375rem; letter-spacing: -0.01em; word-break: break-word; } .ibx-attr { font-weight: 600; } /* Verbatim change title (free-form; ligatures off so "->" never draws as an arrow the data doesn't contain). */ .ibx-title { font-weight: 500; line-height: 1.4; font-variant-ligatures: none; font-feature-settings: "liga" 0, "calt" 0; } .ibx-attr a, .ibx-title a { color: var(--text); text-decoration: none; } .ibx-attr a:hover, .ibx-title a:hover { color: var(--accent); } /* Type label chip — carries the type's colour identity */ /* Inbox type chip: the shared .pill colored by the row's per-type accent. */ .ibx-typechip { --pill-color: var(--type-color, var(--accent)); } .ibx-tag { display: inline-flex; align-items: center; gap: 0.3125rem; padding: 2px 0.5rem; border-radius: 999px; background: var(--ibx-surface); border: 1px solid var(--ibx-line); color: var(--text-2); font-size: 0.71875rem; font-family: var(--mono); text-decoration: none; } .ibx-tag .dot { width: 0.3125rem; height: 0.3125rem; border-radius: 50%; background: var(--accent); } .ibx-tag--pr { color: var(--text); } .ibx-tag--pr .hash { color: var(--text-3); } .ibx-tag--package { color: var(--text); font-weight: 600; } .ibx-tag--reached { font-family: var(--sans); } .ibx-dot-sep { color: var(--ibx-line); } .ibx-time { color: var(--text-3); font-variant-numeric: tabular-nums; } .ibx-unread-dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--type-color, var(--accent)); flex-shrink: 0; align-self: center; margin-right: 2px; } .ibx-row-acts { display: inline-flex; gap: 2px; opacity: 0; transition: opacity 0.12s; } .row-line:hover .ibx-row-acts, .row-line:focus-within .ibx-row-acts { opacity: 1; } .ibx-act { width: 1.75rem; height: 1.75rem; padding: 0; border-radius: 0.4375rem; border: 1px solid transparent; background: transparent; color: var(--text-3); display: grid; place-items: center; cursor: pointer; } .ibx-act:hover { filter: none; background: var(--ibx-surface-3); color: var(--text); border-color: var(--ibx-line); } .ibx-act .ibx-icon { width: 0.9375rem; height: 0.9375rem; } .ibx-save.is-saved { color: var(--accent); } .ibx-save.is-saved .ibx-icon { -webkit-mask-image: url("/images/saved-filled.svg"); mask-image: url("/images/saved-filled.svg"); } .ibx-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } @media (pointer: coarse), (max-width: 719px) { .ibx-act { width: 2.75rem; height: 2.75rem; } .ibx-row-acts { opacity: 1; } } .ibx-empty { text-align: center; color: var(--text-3); padding: 3.75rem 0; } @media (max-width: 719px) { /* Segment stretches to fill; chips scroll in one row; actions always on. */ .ibx-seg { flex: 1 1 auto; } .ibx-toolbar .ibx-seg button { flex: 1; justify-content: center; } .ibx-actions { flex-shrink: 0; } .ibx-filters { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; margin-top: 0.625rem; padding-top: 0.625rem; scrollbar-width: none; } .ibx-filters .ibx-chip { flex-shrink: 0; } /* Narrow inbox rows: the trailing dot and actions wrap under the body. */ .ibx .row-line--leading { grid-template-columns: 1.625rem minmax(0, 1fr); padding: 0.75rem 0.5rem; } .ibx-glyph { width: 1.625rem; height: 1.625rem; } .ibx .row-actions { grid-column: 1 / -1; justify-content: flex-end; margin-top: 0.25rem; } } /* ======================================================================== Keyboard shortcut overlay (?) ======================================================================== */ .shortcuts > header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; } .shortcuts > header h2 { margin: 0; font-size: 1rem; } .shortcuts__close { padding: 0.25rem 0.5rem; border: 0; background: none; color: var(--text-2); font-size: 1.25rem; line-height: 1; cursor: pointer; } .shortcuts__close:hover { color: var(--text); } .shortcuts__groups { display: grid; gap: 1.25rem; } .shortcuts__groups h3 { margin: 0 0 0.5rem; color: var(--text-2); font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase; } .shortcuts__row { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: 0.75rem; align-items: baseline; padding: 0.25rem 0; } .shortcuts__row dd { margin: 0; } kbd { display: inline-block; padding: 0.125rem 0.4rem; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; background: var(--surface); color: var(--text); font-family: inherit; font-size: 0.8125rem; line-height: 1.4; white-space: nowrap; } kbd + kbd { margin-left: 0.25rem; } .pipeline-error { margin: 0; max-height: 14rem; overflow-y: auto; white-space: pre-wrap; overflow-wrap: anywhere; } /* Diagnostics, not decoration: the sublabel carries the failed step, the retry budget and the blocked-revision count, so it wraps instead of being clipped. */ .pipeline-list .row-sublabel { flex-wrap: wrap; white-space: normal; overflow: visible; mask-image: none; } /* Shared channel revision show / comparison surface. */ .revision-comparison .comparison-header { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.5rem 1rem; margin-bottom: 1rem; } .revision-comparison .opt-pathbar { margin: 0; } .revision-comparison .comparison-released { grid-column: 1; margin: 0; color: var(--text-2); font-size: 0.8125rem; font-variant-numeric: tabular-nums; } .revision-comparison .comparison-lens { grid-column: 2; grid-row: 1; } .revision-comparison :is(.comparison-lens, .comparison-endpoints a[role="button"]) { margin: 0; padding: 0.5rem 0.75rem; font-size: 0.78125rem; white-space: nowrap; } .revision-comparison .comparison-endpoints { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; } .revision-comparison .comparison-endpoint { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; min-width: 0; padding: 0.875rem 1.125rem; border-right: 1px solid var(--line); } .revision-comparison .comparison-endpoint > div > a { font-family: var(--mono); font-size: 1.125rem; } .revision-comparison .comparison-value-label { display: block; margin-bottom: 0.25rem; font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-2); } .revision-comparison .comparison-compare { display: flex; align-items: center; padding: 0.75rem 1rem; } .revision-comparison .comparison-baseline { padding: 1rem; border: 1px solid var(--line); border-radius: var(--radius); color: var(--text-2); } .revision-comparison .comparison-section-heading { display: flex; align-items: center; gap: 0.875rem; margin: 1.5rem 0 0.75rem; } .revision-comparison .comparison-section-heading h2 { margin: 0; font-size: 1.375rem; flex-shrink: 0; } .revision-comparison .comparison-section-heading::after { content: ""; height: 1px; background: var(--line-soft); flex: 1; order: 1; } .revision-comparison .comparison-section-heading > span { order: 2; color: var(--text-2); font-size: 0.8125rem; } .revision-comparison :is(.comparison-package-panel, .comparison-options) { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; } .revision-comparison .comparison-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; padding: 0.75rem 1rem; border-bottom: 1px solid var(--line); } .revision-comparison .comparison-filters [role="button"] { width: auto; margin: 0; padding: 0.375rem 0.625rem; border: 1px solid transparent; background: transparent; color: var(--text); font-size: 0.78125rem; text-decoration: none; } .revision-comparison .comparison-filters [aria-pressed="true"] { background: var(--accent-bg); border-color: var(--accent-edge); color: var(--accent); } .revision-comparison .comparison-filters [role="button"]:hover { background: var(--accent-soft); filter: none; } .revision-comparison .comparison-filters [role="button"] span { margin-left: 0.625rem; font-family: var(--mono); font-variant-numeric: tabular-nums; } .revision-comparison .comparison-packages { width: 100%; table-layout: fixed; margin: 0; font-size: 0.8125rem; } .revision-comparison .comparison-packages th:first-child { width: 46%; } .revision-comparison .comparison-packages th:nth-child(2) { width: 18%; } .revision-comparison .comparison-packages :is(th, td) { padding: 0.625rem 0.875rem; border-bottom: 1px solid var(--line-soft); background: var(--bg); overflow-wrap: anywhere; } .revision-comparison .comparison-packages th { background: var(--surface); color: var(--text-2); font-weight: 500; } .revision-comparison .comparison-packages tr:last-child td { border-bottom: 0; } .revision-comparison :is(.comparison-package-name, .comparison-version, .comparison-option-header > a) { font-family: var(--mono); } .revision-comparison .comparison-package-name a { text-decoration: none; } .revision-comparison .comparison-version-from { color: var(--text-2); } .revision-comparison .comparison-version-arrow { display: none; } .revision-comparison .comparison-badge { display: inline-block; border-radius: 999px; padding: 0.125rem 0.5rem; font-size: 0.71875rem; line-height: 1.4; color: var(--t-update); background: color-mix(in srgb, var(--t-update) 12%, transparent); } .revision-comparison .comparison-badge--added { color: var(--t-add); background: color-mix(in srgb, var(--t-add) 12%, transparent); } .revision-comparison .comparison-badge--removed { color: var(--t-remove); background: color-mix(in srgb, var(--t-remove) 12%, transparent); } .revision-comparison .comparison-option { margin: 0; padding: 0; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: var(--bg); box-shadow: none; } .revision-comparison .comparison-option-header { display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem; margin: 0; padding: 0.875rem 1rem; border-bottom: 1px solid var(--line-soft); background: var(--bg); overflow-wrap: anywhere; } .revision-comparison .comparison-option-header > a { min-width: 0; text-decoration: none; } .revision-comparison .comparison-field { padding: 1rem; border-bottom: 1px solid var(--line-soft); } .revision-comparison .comparison-field:last-child { border-bottom: 0; } .revision-comparison .comparison-field-label { margin: 0 0 0.75rem; font-size: 0.8125rem; color: var(--text-2); } .revision-comparison .comparison-field-label strong { color: var(--text); font-family: var(--mono); font-weight: 500; } .revision-comparison .comparison-values { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; } .revision-comparison .comparison-values > div { min-width: 0; padding: 0.875rem; border: 1px solid var(--line-soft); border-radius: 8px; background: var(--surface); } .revision-comparison .comparison-values :is(p, pre) { margin: 0; font-size: 0.8125rem; white-space: pre-wrap; overflow-wrap: anywhere; } .revision-comparison .comparison-values pre { padding: 0; background: transparent; color: var(--text); } .revision-comparison .comparison-field details { margin: 1rem 0 0; padding: 0; font-size: 0.8125rem; } .revision-comparison .comparison-field summary { color: var(--text-2); } .revision-comparison .comparison-full-values { margin-top: 0.75rem; } .revision-comparison :is(.comparison-empty, .comparison-option-counts) { margin: 0; padding: 0.75rem 1rem; color: var(--text-2); font-size: 0.8125rem; } .revision-comparison .comparison-footnote { margin: 1rem 0 0; color: var(--text-2); font-size: 0.78125rem; } @media (max-width: 719px) { .revision-comparison .comparison-header { gap: 0.5rem; margin-bottom: 0.75rem; } .revision-comparison .opt-pathbar { grid-column: 1 / -1; padding: 0 2px; font-size: 1.0625rem; } .revision-comparison .comparison-lens { grid-row: 2; padding: 0.375rem 0.625rem; } .revision-comparison .comparison-released { font-size: 0.6875rem; } .revision-comparison .comparison-endpoints { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .revision-comparison .comparison-endpoint { display: block; padding: 0.75rem; } .revision-comparison .comparison-endpoint:nth-child(2) { border-right: 0; } .revision-comparison .comparison-endpoint a[role="button"] { margin-top: 0.375rem; padding: 0.25rem 0.5rem; font-size: 0.6875rem; } .revision-comparison .comparison-compare { grid-column: 1 / -1; padding: 0; border-top: 1px solid var(--line); } .revision-comparison .comparison-compare a { width: 100%; border: 0; border-radius: 0; background: var(--accent-soft); } .revision-comparison .comparison-section-heading { gap: 0.75rem; } .revision-comparison .comparison-section-heading h2 { font-size: 1.125rem; } .revision-comparison .comparison-filters { padding: 0.75rem; gap: 0.25rem; } .revision-comparison .comparison-packages :is(thead, .comparison-version-arrow) { display: none; } .revision-comparison .comparison-packages, .revision-comparison .comparison-packages tbody { display: block; } .revision-comparison .comparison-packages tr { display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto; gap: 0.375rem; padding: 0.625rem 0.75rem; border-bottom: 1px solid var(--line-soft); } .revision-comparison .comparison-packages tr:last-child { border-bottom: 0; } .revision-comparison .comparison-packages td { padding: 0; border: 0; min-width: 0; } .revision-comparison .comparison-package-name { grid-column: 1 / -1; grid-row: 1; } .revision-comparison .comparison-package-change { grid-column: 3; grid-row: 2; align-self: start; text-align: right; max-width: 8rem; } .revision-comparison .comparison-version-from { grid-column: 1; grid-row: 2; max-width: 7rem; } .revision-comparison .comparison-version-to { grid-column: 2; grid-row: 2; } .revision-comparison .comparison-packages .comparison-version-arrow { display: inline; margin-right: 0.375rem; color: var(--text-2); } .revision-comparison .comparison-values { grid-template-columns: minmax(0, 1fr); } }