:root {
  --bg: #0d1117; --panel: #161b22; --border: #30363d; --fg: #e6edf3; --muted: #8b949e;
  --accent: #58a6ff; --ok: #3fb950; --warn: #d29922; --draft: #6e7681;
}
* { box-sizing: border-box; }
a { color: inherit; text-decoration: none; }
a.main { display: contents; }
/* 22px at 1920x1080, scaled by whichever of width/height is the limit, so the layout survives any aspect ratio. Tune with ?scale=0.8 */
html { font-size: min(1.146vw, 2.037vh); }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--fg); font-family: system-ui, sans-serif; line-height: 1.3; overflow: hidden; }
header {
  display: flex; align-items: center; gap: 2rem; height: 5rem; padding: 0 1.5rem;
  background: var(--panel); border-bottom: 2px solid var(--border);
}
header.stale { background: #4a3a10; }
header h1 { margin: 0; font-size: 2.4rem; letter-spacing: .05em; }
#clock { font-size: 2.4rem; font-variant-numeric: tabular-nums; }
#timeline { flex: 1; display: flex; flex-direction: column; gap: .15rem; font-size: .75rem; color: var(--muted); }
#phases, #dates { display: flex; justify-content: space-between; }
#phases { position: relative; height: 1rem; }
#phases span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
#phases .phase-left { color: var(--fg); font-weight: normal; }
#bar { position: relative; height: .7rem; background: var(--border); border-radius: .35rem; overflow: hidden; }
#elapsed { height: 100%; background: var(--accent); border-radius: .35rem; width: 0; transition: width 1s linear; }
#ticks span { position: absolute; top: 0; bottom: 0; width: .15rem; background: var(--bg); transform: translateX(-50%); }
#countdown { color: var(--fg); }
/* ring filling clockwise until the next data run; --p is 0..1 */
#updated { width: 2.2rem; height: 2.2rem; border-radius: 50%; flex: none;
  background: conic-gradient(var(--accent) calc(var(--p, 0) * 100%), var(--border) 0); position: relative; }
#updated::after { content: ""; position: absolute; inset: .45rem; border-radius: 50%; background: var(--panel); }
#updated.overdue { animation: pulse 2s ease-in-out infinite; } /* full ring pulsing: next run is late but data is not yet stale */
@keyframes pulse { 50% { opacity: .35; } }
header.stale #updated { background: var(--warn); }
header.stale #updated::after { content: "!"; display: grid; place-items: center; font-weight: bold; }
#logo { height: 3.5rem; }
main {
  display: grid; height: calc(100vh - 5rem); gap: .8rem; padding: .8rem;
  grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 11fr 9fr;
}
section { background: rgba(22, 27, 34, .8); /* translucent so the ambient glow shows through */ border: 1px solid var(--border); border-radius: .6rem; padding: .6rem .8rem; overflow: hidden; display: flex; flex-direction: column; }
section h2 { margin: 0 0 .5rem; font-size: 1.1rem; text-transform: uppercase; letter-spacing: .15em; color: var(--muted); }
section h2 .count { float: right; color: var(--fg); }
.cards { position: relative; /* offsetParent for the cards, so updateMore measures inside the column */ overflow-y: auto; scrollbar-width: none; mask-image: linear-gradient(to bottom, #000 calc(100% - 2rem), transparent); flex: 1; display: flex; flex-direction: column; gap: .25rem; }
.card { font-size: .75rem; flex: none; display: flex; align-items: center; gap: .5rem; padding: .15rem .5rem; border-radius: .4rem; background: var(--bg); border-left: .35rem solid var(--accent); white-space: nowrap; overflow: hidden; }
.card.other { opacity: .65; }
.card.draft { border-left-style: dashed; }
.card.focus { background: #1c2230; }
.divider { flex: none; font-size: .65rem; color: var(--muted); text-transform: uppercase; letter-spacing: .15em; padding: .2rem 0 0; border-top: 1px solid var(--border); }
.card .avatar { width: 1.5rem; height: 1.5rem; border-radius: 50%; flex: none; }
.card .num { color: var(--muted); flex: none; }
.card .title { overflow: hidden; text-overflow: ellipsis; flex: 1; }
.card .repo { font-size: .7rem; color: var(--muted); background: var(--border); padding: .1rem .4rem; border-radius: .3rem; flex: none; }
.card .tag { font-size: .7rem; padding: .1rem .4rem; border-radius: .3rem; background: var(--border); flex: none; }
.card .tag.draft { color: var(--draft); }
.card .tag.merged { background: #8250df; }
.card .tag.rfr { background: #1f6feb; }
.cards::-webkit-scrollbar { display: none; }
.more { color: var(--muted); font-size: .85rem; min-height: 1.1rem; text-align: center; cursor: pointer; user-select: none; }
.more:empty { cursor: default; }
.tag.closed { background: #cf222e; }
.tag.notplanned { background: #57606a; }
#statsrow { flex: 1; overflow: hidden; display: grid; grid-template-columns: 1fr 1fr 1.5fr; gap: 1.5rem; min-width: 0; }
#milestones { display: flex; flex-direction: column; gap: .3rem; font-size: .85rem; }
.milestone .bar { position: relative; height: .9rem; background: var(--border); border-radius: .2rem; overflow: hidden; }
.milestone .bar div { position: absolute; top: 0; bottom: 0; left: 0; }
.milestone .before { background: #1f6feb; }
.milestone .during { background: var(--ok); }
.milestone .label { display: flex; justify-content: space-between; white-space: nowrap; gap: .5rem; }
.milestone .label > a { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.milestone .label > span { flex: none; }
.milestone .label .muted { color: var(--muted); font-size: .75rem; }
#milestones .private { color: var(--muted); font-size: .75rem; margin-top: .2rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#statsrow > div { min-width: 0; overflow: hidden; }
#statsrow h3 { margin: 0 0 .3rem; font-size: .9rem; text-transform: uppercase; letter-spacing: .15em; color: var(--muted); }
#refactorings { list-style: none; margin: 0; padding: 0; font-size: .85rem; }
#refactorings li { display: flex; gap: .5rem; align-items: center; padding: 0; white-space: nowrap; overflow: hidden; }
#refactorings img { width: 1.4rem; height: 1.4rem; border-radius: 50%; }
#refactorings .repo { color: var(--muted); font-size: .8rem; }
#stats { grid-column: 1 / 3; }
#activity { grid-row: 1; grid-column: 3; }
#done { grid-row: 2; grid-column: 3; }
#totals { display: inline-flex; gap: 1.5rem; margin-left: 1.5rem; font-size: 1rem; letter-spacing: 0; text-transform: none; color: var(--fg); }
#totals .add { color: var(--ok); } #totals .del { color: #f85149; }
#components { display: grid; grid-template-columns: 6rem minmax(3rem, 1fr) 3rem; gap: .1rem .6rem; align-content: start; align-items: center; font-size: .85rem; }
#components .bar { height: .9rem; background: var(--accent); border-radius: .2rem; }
#leaderboard { display: flex; gap: .8rem; margin-top: auto; padding-top: .3rem; align-items: flex-end; }
.leader { text-align: center; font-size: .8rem; white-space: nowrap; }
.leader img { width: 2.6rem; height: 2.6rem; border-radius: 50%; border: .25rem solid var(--c); display: block; margin: 0 auto .2rem; }
.leader .pts { font-size: 1rem; font-weight: bold; }
.leader:first-child img { width: 3.4rem; height: 3.4rem; }
#activity { position: relative; }
#ticker { list-style: none; margin: 0; padding: 0; overflow: hidden; flex: 1; font-size: .95rem; }
#ticker li { display: flex; gap: .5rem; align-items: center; padding: .2rem 0; white-space: nowrap; overflow: hidden; }
#ticker img { width: 1.4rem; height: 1.4rem; border-radius: 50%; flex: none; }
#ticker .when { color: var(--muted); flex: none; width: 4.5rem; font-size: .8rem; }
#ticker .what { overflow: hidden; flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
#ticker .what > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#ticker .repo { max-width: 35%; overflow: hidden; text-overflow: ellipsis; font-size: .7rem; color: var(--muted); background: var(--border); padding: .1rem .4rem; border-radius: .3rem; flex: none; }
#ticker li.other { opacity: .65; }
#ticker .excerpt { color: var(--muted); font-style: italic; font-size: .85em; }
#ticker .pts { flex: none; font-size: .7rem; font-weight: bold; color: var(--ok); }
#gource { width: 100%; max-height: 32%; object-fit: contain; background: #000; border-radius: .4rem; margin-top: .4rem; }
#gource:not([src]) { display: none; }
#gource-missing { margin-top: .4rem; padding: .6rem; border: 1px dashed var(--border); border-radius: .4rem; color: var(--muted); font-size: .8rem; text-align: center; }
#gource-missing a { color: var(--muted); }
#gource[src] + #gource-missing { display: none; }
#toast { position: fixed; left: 50%; bottom: 2rem; transform: translateX(-50%); background: var(--ok); color: #000; font-size: 2rem; padding: .6rem 1.5rem; border-radius: 1rem; opacity: 0; transition: opacity .5s; pointer-events: none; }
#toast.show { opacity: 1; }
/* hover enlarges the video; it must cover the small video completely (bottom/right edge) or hover flickers. The free strip on the left shrinks it again. */
#gource[src]:hover { position: fixed; z-index: 10; top: 3%; bottom: 0; left: 10%; right: 0; width: auto; height: auto; max-height: none; box-shadow: 0 0 4rem #000; }
#footer { position: fixed; right: 1rem; bottom: .1rem; display: flex; gap: 1rem; font-size: .6rem; color: var(--muted); font-family: monospace; }
#components span:nth-child(3n+1) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Ambient motion so TVs with content-adaptive dimming don't treat the wall as a static image:
   a slow drifting glow behind the panels (whole-screen pixel change, low contrast) and a gentle
   breathing of the panel borders. Off with ?still=1 or reduced-motion. */
body::before {
  content: ""; position: fixed; inset: -40%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, #1f3a5f 0%, transparent 70%);
  opacity: .6; animation: drift 90s ease-in-out infinite alternate;
}
main { position: relative; z-index: 0; }
section { animation: breathe 20s ease-in-out infinite; }
/* every pixel changes slowly: the whole page brightens and darkens by ~10 % over 40 s */
body { animation: glow 40s ease-in-out infinite; }
@keyframes glow { 50% { filter: brightness(1.1); } }
@keyframes drift {
  0%   { transform: translate(-25%, -20%) scale(.8); }
  50%  { transform: translate(15%, 10%) scale(1.1); }
  100% { transform: translate(25%, -15%) scale(.9); }
}
@keyframes breathe { 50% { border-color: #3d4654; } }
@media (prefers-reduced-motion: reduce) { body, body::before, section { animation: none; } }
html.still body, html.still body::before, html.still section { animation: none; }
