/* ============================================================
   90-Day Sprint Tracker.

   The handoff specifies the Modernist dark system exactly: #0c0b0b ground,
   Archivo, sharp corners everywhere except the circular medallions, hairline
   borders, thin coloured top bars, and no shadow except on the celebration
   card. That is followed to the letter.

   The light theme is an addition, and the rule used to derive it: the spectrum
   hues are fixed points and do not move, because they carry meaning (a chapter
   is always its colour). Everything else inverts around them, and the three
   accent hues that fail contrast on white are darkened until they pass. Amber
   at #ffb02e on white is 1.7:1 and unreadable, so it becomes #8a5a00.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;600;800&display=swap');

.sprint-app {
  --page:    #0c0b0b;
  --surf:    #111010;
  --surf-2:  #0f0e0e;
  --tx:      #f3f2f2;
  --tx-2:    #9b9797;
  --tx-mut:  #8f8b8b;
  /* Solved against every ground it lands on rather than picked by eye:
     the previous value read 3.5:1 to 3.9:1 on the surfaces it is used on,
     and this is the smallest text on the page. */
  --tx-fnt:  #827e7e;
  --tx-brt:  #c9c6c6;
  --hair:    rgba(243,242,242,.12);
  --hair-in: rgba(243,242,242,.08);
  --hair-fx: rgba(243,242,242,.05);
  --link:    #ff6a52;

  --red:    #ff3b1f;
  --amber:  #ffb02e;
  --green:  #4ade80;
  --teal:   #2dd4bf;
  --blue:   #5b8cff;
  --purple: #a970ff;


  /* ---- the component contract ------------------------------------------
     The tracker names its tokens --page/--surf/--tx/--hair, which is its own
     vocabulary and is staying. tl-components.css asks for --bg/--surface/
     --text/--line, so the two are bridged here rather than by renaming a
     hundred rules.

     References, not copies, so the light block below overrides the source
     token and these follow. Only --cta-ink has to be restated there, because
     an ink is not derivable from the colour it sits on.
     ---------------------------------------------------------------------- */
  --bg:      var(--page);
  --bg2:     var(--surf-2);
  --surface: var(--surf);
  --text:    var(--tx);
  --muted:   var(--tx-2);
  --faint:   var(--tx-fnt);
  --line:    var(--hair);
  --line2:   var(--hair-in);
  --cta:      var(--green);
  --cta-text: var(--green);
  --cta-ink:  #06210f;
  --accent-soft: color-mix(in srgb, var(--green) 14%, transparent);

  /* The radius scale, matching tl-system.css. The tracker had no scale at
     all, which is why its cards, chips and buttons each carried a literal. */
  --r-xs:   clamp(6px,  0.5vw,  8px);
  --r-sm:   clamp(8px,  0.8vw, 12px);
  --r-md:   clamp(12px, 1.2vw, 18px);
  --r-lg:   clamp(14px, 1.5vw, 22px);
  --r-xl:   clamp(16px, 1.9vw, 28px);
  --r-pill: 999px;

  background: var(--page);
  color: var(--tx);
  font-family: 'Archivo', system-ui, sans-serif;
}

/* The light theme. Chapter hues hold; the three that fail on white are
   darkened until they reach 4.5:1, because a tag nobody can read is not a tag. */
:root[data-theme="light"] .sprint-app,
html:not([data-theme="dark"]) .sprint-app.light-pref {
  --page:    #faf9f7;
  --surf:    #ffffff;
  --surf-2:  #f4f2ef;
  --tx:      #14110f;
  --tx-2:    #55504a;
  --tx-mut:  #625d57;
  --tx-fnt:  #746e67;
  --tx-brt:  #2a2522;
  --hair:    rgba(20,17,15,.14);
  --hair-in: rgba(20,17,15,.09);
  --hair-fx: rgba(20,17,15,.06);
  --link:    #c2321a;
  --red:    #c2321a;
  --amber:  #8a5a00;
  --green:  #1c7a41;
  --teal:   #0f6b63;
  --blue:   #2b4fb8;
  --purple: #6b34c2;
  /* White on #1c7a41 is 5.6:1; the dark ink above is 1.2:1 on it. */
  --cta-ink: #ffffff;
}
/* The light theme is reached by choosing it, not by the operating system.
   BrandOS forces dark and stores the choice under tl-theme; the tracker used
   to follow prefers-color-scheme instead, so on a Mac set to Light the tracker
   came up cream while every other Turtle Labs page came up black. One product,
   two answers to the same question. The explicit [data-theme="light"] rule
   above still applies, so the toggle works in both directions and a visitor
   who has chosen light still gets light here. */

.sprint-app *, .sprint-app *::before, .sprint-app *::after { box-sizing: border-box; }
.sprint-app h1, .sprint-app h2, .sprint-app h3, .sprint-app h4 {
  font-weight: 800; letter-spacing: -.02em; line-height: 1.04; margin: 0;
}
.sprint-app a { color: var(--link); }
.sprint-app ::selection { background: rgba(255,59,31,.3); }
.sprint-app button { font-family: inherit; }
.sprint-app :focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.tw { max-width: 1240px; margin: 0 auto; padding: 0 32px; }
@media (max-width: 620px) { .tw { padding: 0 16px; } }

.spec { height: 5px; }

/* ---- top bar ---- */
.topbar { border-bottom: 1px solid var(--hair); }
.topbar .tw { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; padding-block: 16px; }
.tb-brand { display: flex; align-items: center; gap: 12px; margin: 0;
  font-size: 13px; letter-spacing: .16em; text-transform: uppercase; font-weight: 800; }
.tb-brand span { color: var(--tx-mut); padding-left: 12px; border-left: 1px solid var(--hair); }
.tb-right { display: flex; align-items: center; gap: 10px; margin: 0; }
.tb-right label { font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); }
.datefld { background: var(--surf-2); color: var(--tx); color-scheme: dark;
  border: 1px solid rgba(243,242,242,.16); padding: 8px 10px; font: inherit; font-size: 13px; }
:root[data-theme="light"] .datefld { color-scheme: light; border-color: var(--hair); }
.datefld:focus { border-color: var(--red); outline: none; }
.txtbtn { background: transparent; border: 1px solid var(--hair); color: var(--tx-mut);
  font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  padding: 8px 11px; cursor: pointer; }
.txtbtn:hover { border-color: var(--red); color: var(--red); }

/* ---- hero ---- */
.sprint { padding-bottom: 60px; }
.s-hero { padding: 34px 0 26px; }
.s-kicker { font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
  font-weight: 800; color: var(--red); margin: 0 0 14px; }
.s-hero h1 { font-size: clamp(30px, 5vw, 44px); margin: 0 0 14px; }
.grad { background: linear-gradient(90deg,var(--red),var(--amber),var(--green),var(--teal),var(--blue),var(--purple));
  -webkit-background-clip: text; background-clip: text; color: transparent; }
@supports not (background-clip: text) { .grad { color: var(--red); } }
.s-sub { font-size: 15px; color: var(--tx-2); max-width: 620px; margin: 0; line-height: 1.6; }

/* ---- dashboard ---- */
.dash { border: 1px solid var(--hair); background: var(--surf); margin-bottom: 26px; }
.dash-row { display: flex; flex-wrap: wrap; }
.cell { flex: 1 1 190px; padding: 22px 24px; border-right: 1px solid var(--hair-in); }
.cell:last-child { border-right: 0; }
.cell-lbl { font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); margin: 0 0 10px; }
.cell-n { font-size: 26px; font-weight: 800; letter-spacing: -.02em; margin: 0; line-height: 1.1; }
.cell-sub { font-size: 12px; color: var(--tx-fnt); margin: 5px 0 0; }
.cell-n.streak { color: var(--green); font-size: 30px; }

.cell-ring { display: flex; align-items: center; gap: 18px; position: relative;
  /* 132 ring + 18 gap + 48 padding leaves 132 for the count beside it, which
     is not enough for "TASKS DONE" over "0 / 36": the label wrapped to two
     lines and the number broke after the slash. */
  flex: 1 1 396px; }
.cell-ring .cell-lbl, .cell-ring .cell-n { white-space: nowrap; }
/* The ring is a 132px SVG and the handoff says so. Inside a flex row it was
   flex:0 1 auto, so the row shrank it to 109px, while .ring-mid below is
   positioned on the assumption that it is 132px: the percentage sat off the
   centre of its own circle. */
.ring { flex: none; width: 132px; height: 132px; }
.ring circle { transition: stroke-dashoffset .5s ease; }
.ring-mid { position: absolute; left: 24px; width: 132px; height: 132px;
  display: grid; place-content: center; text-align: center; pointer-events: none; }
.ring-pct { display: block; font-size: 34px; font-weight: 800; letter-spacing: -.02em; }
.ring-pct::after { content: '%'; font-size: 16px; }
.ring-lbl { display: block; font-size: 9.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--tx-mut); font-weight: 800; }
.cell-side { margin-left: 150px; }

@media (max-width: 560px) {
  .cell-ring { flex-direction: column; align-items: flex-start; }
  .ring-mid { left: 24px; top: 22px; }
  .cell-side { margin-left: 0; margin-top: 8px; }
}

/* ---- badges ---- */
.sec-lbl { font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); margin: 0 0 14px; }
.badges-wrap { margin-bottom: 30px; }
.badges { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
@media (max-width: 760px) { .badges { grid-template-columns: repeat(2, 1fr); } }
.badge { background: var(--surf-2); border: 1px solid var(--hair-fx); padding: 0 0 16px;
  opacity: .72; text-align: center; }
.badge.earned { opacity: 1; background: #12100f; border-color: var(--tc); }
:root[data-theme="light"] .badge.earned { background: var(--surf); }
.badge-bar { height: 3px; background: var(--tc); }
.medal { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  margin: 16px auto 10px; border: 1px solid var(--tc); color: var(--tc); font-size: 17px; }
.badge-name { font-size: 12px; font-weight: 800; margin: 0 0 3px; letter-spacing: -.01em; }
.badge-sub { font-size: 10px; color: var(--tx-fnt); margin: 0 0 8px; }
.badge-state { font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); margin: 0; }
.badge.earned .badge-state { color: var(--tc); }

/* ---- layout ---- */
.grid { display: grid; grid-template-columns: 1fr 340px; gap: 26px; align-items: start; }
@media (max-width: 980px) { .grid { grid-template-columns: 1fr; } }
.sec-head { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.sec-head .sec-lbl { margin: 0; }
.expand { display: flex; gap: 8px; margin: 0; }

/* ---- windows ---- */
.win { border: 1px solid var(--hair); background: var(--surf); margin-bottom: 14px;
  border-top: 4px solid var(--wc); }
.win form { margin: 0; }
.win-head { display: flex; align-items: center; gap: 16px; width: 100%; text-align: left;
  background: none; border: 0; padding: 18px 20px; cursor: pointer; color: inherit; }
.win-n { font-size: 40px; font-weight: 800; color: var(--wc); letter-spacing: -.03em;
  line-height: 1; flex: none; font-variant-numeric: tabular-nums; }
.win-meta { display: block; margin-right: auto; }
.win-title { display: block; font-size: 23px; font-weight: 800; letter-spacing: -.02em; }
.win-range { display: block; font-size: 11px; color: var(--tx-fnt); letter-spacing: .1em;
  text-transform: uppercase; font-weight: 800; margin-top: 3px; }
.win-prog { display: flex; align-items: center; gap: 10px; flex: none; }
.win-bar { display: block; width: 90px; height: 4px; background: var(--hair-in); }
.win-bar span { display: block; height: 100%; background: var(--wc); transition: width .4s; }
.win-count { font-size: 12px; color: var(--tx-brt); font-variant-numeric: tabular-nums; }
.win-badge { font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-fnt); border: 1px solid var(--hair-in); padding: 5px 8px; flex: none; }
.win-badge.earned { color: var(--wc); border-color: var(--wc); }
.chev { font-size: 12px; color: var(--tx-mut); transition: transform .2s; flex: none; }
.win.open .chev { transform: rotate(180deg); }
@media (max-width: 700px) {
  .win-head { flex-wrap: wrap; gap: 10px; }
  .win-meta { margin-right: 0; width: calc(100% - 70px); }
  .win-prog, .win-badge { margin-left: 56px; }
}

.win-body { border-top: 1px solid var(--hair-in); }
.week { padding: 16px 20px; border-bottom: 1px solid var(--hair-fx); }
.week:last-child { border-bottom: 0; }
.week-h { display: flex; align-items: center; gap: 12px; margin: 0 0 10px; flex-wrap: wrap; }
.week-label { font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); }
.week-focus { font-size: 13px; color: var(--tx-brt); font-weight: 600; }
.week-done { font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 800; color: var(--green); animation: pop .34s cubic-bezier(.2,.9,.3,1.2); }

@keyframes pop { from { opacity: 0; transform: scale(.86); } 60% { transform: scale(1.03); } }

/* ---- tasks ---- */
.task { display: flex; align-items: center; gap: 11px; padding: 12px 0;
  border-top: 1px solid var(--hair-fx); transition: opacity .2s; flex-wrap: wrap; }
.task:first-of-type { border-top: 0; }
.task.is-done { opacity: .5; }
.task form { margin: 0; display: flex; }
.box { width: 22px; height: 22px; flex: none; background: transparent; cursor: pointer;
  border: 1px solid var(--tc); color: #0c0b0b; display: grid; place-items: center; padding: 0; }
.task.is-done .box { background: var(--tc); }
.task-text { font-size: 14.5px; font-weight: 600; line-height: 1.4; margin: 0;
  flex: 1 1 200px; min-width: 0; }
.task.is-done .task-text { text-decoration: line-through; color: var(--tx-mut); }
.chap { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 800;
  color: var(--tc); border: 1px solid var(--tc); padding: 3px 6px; flex: none; }
.due { font-size: 10px; color: var(--tx-fnt); letter-spacing: .08em; text-transform: uppercase;
  font-weight: 800; flex: none; font-variant-numeric: tabular-nums; }
.tpill { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 800;
  padding: 3px 6px; flex: none; }
.tpill.over { color: var(--red); border: 1px solid var(--red); }
.tpill.today { color: var(--amber); border: 1px solid var(--amber); }
.tpill.flag { color: var(--purple); border: 1px solid var(--purple); }
.flagbtn { background: none; border: 0; color: var(--tx-fnt); cursor: pointer; padding: 4px; }
.flagbtn.on, .flagbtn:hover { color: var(--amber); }
.task.animate { animation: flash 1.4s ease; }
@keyframes flash { from { background: rgba(255,59,31,.18); } to { background: transparent; } }

/* ---- attention ---- */
.attn { border: 1px solid var(--hair); background: var(--surf); padding: 20px;
  position: sticky; top: 20px; }
@media (max-width: 980px) { .attn { position: static; } }
.attn-h { font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); margin: 0 0 8px; }
.attn-line { font-size: 14px; font-weight: 600; margin: 0 0 18px; }
.count { display: flex; align-items: center; gap: 14px; padding: 14px 0;
  border-top: 1px solid var(--hair-in); border-bottom: 1px solid var(--hair-in); margin-bottom: 16px; }
.count-n { font-size: 34px; font-weight: 800; color: var(--tc, var(--green));
  letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.count-name { display: block; font-size: 13px; font-weight: 800; }
.count-sub { display: block; font-size: 11px; color: var(--tx-fnt); margin-top: 2px; }
.att-group { margin-bottom: 16px; }
.att-h { font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; font-weight: 800;
  margin: 0 0 8px; color: var(--tx-mut); display: flex; justify-content: space-between; }
.g-over .att-h { color: var(--red); }
.g-today .att-h { color: var(--amber); }
.g-week .att-h { color: var(--teal); }
.g-flag .att-h { color: var(--purple); }
.att-item { display: flex; gap: 10px; align-items: baseline; justify-content: space-between;
  padding: 8px 0 8px 10px; border-left: 2px solid currentColor; text-decoration: none;
  color: inherit; margin-bottom: 2px; }
.g-over .att-item { border-color: var(--red); }
.g-today .att-item { border-color: var(--amber); }
.g-week .att-item { border-color: var(--teal); }
.g-flag .att-item { border-color: var(--purple); }
.att-item:hover { background: var(--hair-fx); }
.att-text { font-size: 12.5px; color: var(--tx-brt); }
.att-due { font-size: 10px; color: var(--tx-fnt); flex: none; font-variant-numeric: tabular-nums; }
.allclear { font-size: 13px; color: var(--green); margin: 0 0 16px; }
.attn-foot { font-size: 10px; color: var(--tx-fnt); margin: 0; padding-top: 14px;
  border-top: 1px solid var(--hair-fx); }

/* ---- footer ---- */
.s-foot { margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--hair);
  display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.s-foot p { font-size: 11px; color: var(--tx-fnt); margin: 0; }

/* ---- celebration ---- */
.celeb { position: fixed; inset: 0; background: rgba(6,5,5,.82); display: grid;
  place-items: center; z-index: 90; padding: 20px; }
.celeb-card { background: var(--surf-2); border: 1px solid var(--hair);
  box-shadow: 0 30px 90px rgba(0,0,0,.6); width: min(420px, 100%); text-align: center;
  padding-bottom: 28px; animation: pop .34s cubic-bezier(.2,.9,.3,1.2); }
.celeb-medal { width: 64px; height: 64px; border-radius: 50%; display: grid; place-items: center;
  margin: 26px auto 16px; border: 1px solid var(--tc); color: var(--tc); font-size: 24px; }
.celeb-kicker { font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-mut); margin: 0 0 10px; }
.celeb-title { font-size: 40px; font-weight: 800; letter-spacing: -.03em; margin: 0 0 10px; }
.celeb-sub { font-size: 13.5px; color: var(--tx-2); margin: 0 0 22px; padding: 0 26px; }
.celeb-cta { background: var(--tc); color: #0c0b0b; border: 0; padding: 12px 22px;
  font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; cursor: pointer; }
.celeb form { margin: 0; }

@media (prefers-reduced-motion: reduce) {
  .sprint-app *, .celeb-card, .week-done { animation: none !important; transition: none !important; }
}

/* ---- corners ---------------------------------------------------------------
   The handoff specifies sharp corners throughout, on purpose: flat rectangles,
   hairline borders, thin coloured top-bars, the Modernist set. Rounded on
   request, because the tracker sits inside Turtle Labs rather than beside it,
   and a square-cornered page between six rounded ones reads as a different
   product rather than as a deliberate one.

   The radius scale is the same one every other surface uses. Panels take the
   large step, rows and controls the small one, and small marks stay pills.
   Anything with a coloured bar across its top gets overflow:hidden, or the bar
   draws square corners over the rounded ones beneath it.
   ------------------------------------------------------------------------ */
.sprint-app .dash,
.sprint-app .win,
.sprint-app .badge,
.sprint-app .attn { border-radius: var(--r-lg); overflow: hidden; }

.sprint-app .task,
.sprint-app .week,
.sprint-app .count,
.sprint-app .datefld,
.sprint-app .txtbtn { border-radius: var(--r-sm); }

.sprint-app .chap,
.sprint-app .win-badge { border-radius: var(--r-pill); }

/* The celebration card, which is the one surface the handoff gives a shadow. */
.sprint-app .celeb-card { border-radius: var(--r-lg); }

/* A row inside a rounded panel should not fight its parent's corner. */
.sprint-app .win-body .week:first-child { border-top-left-radius: 0; border-top-right-radius: 0; }

/* ---- the audit's focus ---------------------------------------------------
   Set by the Brand Audit when it builds a plan: the chapters that scored worst
   are marked here so the tracker says why you are looking at it. Absent for
   anybody who came straight to the tracker, and nothing below applies then. */
.sprint-app .focus-note {
  border: 1px solid var(--hair);
  border-left: 3px solid var(--green);
  background: var(--surf);
  padding: 18px 20px;
  margin: 0 0 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sprint-app .fn-eyebrow {
  margin: 0; font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 800; color: var(--tx-2);
}
.sprint-app .fn-body { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--tx); max-width: 68ch; }
.sprint-app .fn-link { align-self: flex-start; font-size: 13.5px; font-weight: 700; color: var(--link); }

.sprint-app .tpill.focus {
  background: color-mix(in srgb, var(--green) 18%, transparent);
  color: var(--green);
  border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
}
/* The marked rows, kept quiet: a whole chapter can be focus, and eight rows
   shouting at once is worse than none of them speaking. */
.sprint-app .task.is-focus { background: color-mix(in srgb, var(--green) 5%, transparent); }
.sprint-app .task.is-focus .task-text { font-weight: 600; }
