/* THE GOALS ROOM — its styles, moved out of app.css by the rebuild (15 Oct). Loaded straight
   after app.css. Goals pace and board, the dashboard strip (gd-*), and the week it must survive (gw-*). */
  /* The keeping-up record: one mark per period, oldest first. Shape carries the
     meaning — filled, hollow, faded — so it reads the same to anybody who
     cannot tell the accent from the background. */
  .goal-dots{ display:inline-flex; gap:var(--space-1); margin-left:var(--space-2); vertical-align:middle; }
  .goal-dot{ width:7px; height:7px; border-radius:var(--radius-round); border:1.5px solid var(--text-faint);
             display:inline-block; }
  .goal-dot.on{ background:var(--accent); border-color:var(--accent); }
  .goal-dot.before{ opacity:.35; border-style:dotted; }

  /* ==========================================================
     GOALS — the long ones.
     ==========================================================

     Deliberately quiet. Nothing here is a progress bar, a percentage or a
     ring filling up: a number like that on a five-year goal is invented, and
     once it is on screen it is what gets read instead of the goal.

     The only thing coloured is "quiet" — how long since he last looked at
     one — because with no due date that is the single honest measure of
     neglect, and it is the reason to open this page at all. */
  .goal-card{ padding:var(--space-4) var(--space-4); border-radius:var(--radius-card); border:1px solid var(--glass-border);
    background:var(--glass-bg); margin-bottom:var(--space-3); }
  .goal-card.is-parked{ opacity:.62; }
  .goal-top{ display:flex; align-items:baseline; gap:var(--space-3); }
  .goal-title{ font-size:var(--type-lead); font-weight:650; flex:1; min-width:0; color:var(--text); }
  .goal-title.is-reached{ text-decoration:line-through; text-decoration-thickness:1px; }
  .goal-why{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-2); white-space:pre-wrap; }
  .goal-measure{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-2); }
  .goal-measure b{ color:var(--text); font-weight:600; }
  .goal-meta{ display:flex; flex-wrap:wrap; gap:var(--space-2) var(--space-4); margin-top:var(--space-2);
    font-size:var(--type-body); color:var(--text-dim); align-items:center; }
  /* Three states, and the middle one is the whole feature: a goal nobody has
     looked at since the spring. Never red — this is a nudge, not a bill. */
  .goal-quiet{ font-weight:600; color:var(--text-dim); }
  .goal-quiet.is-stale{ color:var(--amber, #C08A2E); }
  .goal-quiet.is-fresh{ color:var(--green-text, var(--text-dim)); }
  .goal-acts{ display:flex; gap:var(--space-2); flex-wrap:wrap; margin-top:var(--space-3); }
  .goal-acts .btn{ font-size:var(--type-body); padding:var(--space-2) var(--space-3); }
  .goal-links{ margin-top:var(--space-3); border-top:1px solid var(--glass-border); padding-top:var(--space-2); }
  .goal-link{ display:flex; align-items:baseline; gap:var(--space-2); font-size:var(--type-body);
    padding:var(--space-1) 0; color:var(--text-dim); }
  .goal-link .gl-mark{ flex:none; width:15px; text-align:center; }
  .goal-link.is-done .gl-name{ color:var(--text-faint); text-decoration:line-through; }
  .goal-link .gl-name{ flex:1; min-width:0; color:var(--text); cursor:pointer;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .goal-link .gl-name:hover{ text-decoration:underline; }
  .goal-horizons{ display:flex; gap:var(--space-2); flex-wrap:wrap; margin-bottom:var(--space-2); }
  .goal-horizon.is-on{ border-color:var(--accent); color:var(--text); }
  /* The page column: a line of prose stops at the reading measure, as .page-sub does. */
  .goal-empty{ font-size:var(--type-body); color:var(--text-dim); padding:var(--space-3) 0 var(--space-5);
    max-width:var(--prose-measure); }
  /* In a tile grid the gutter belongs to the grid, so the cards bring no bottom margin. */
  .tile-grid > .goal-card, .tile-grid > .goal-pace-row{ margin-bottom:0; }

  /* ---- PACE — "am I ahead or behind, and what is the single next thing." ----
     Colour carries the gap and nothing else: ahead and behind are the only two
     facts this row is allowed an opinion about, the same restraint the quiet
     bar above keeps. A passed deadline and a trend are plain text, never red —
     see _goal-pace.js for why "overdue" has no place on a life goal. */
  .goal-pace-row{ padding:var(--space-4) var(--space-4); border-radius:var(--radius-card); border:1px solid var(--glass-border);
    background:var(--glass-bg); margin-bottom:var(--space-3); }
  .goal-pace-row.is-parked{ opacity:.62; }
  .goal-pace-row .goal-top{ align-items:center; }
  .goal-pace-row .goal-title{ cursor:pointer; }
  .goal-pace-row .goal-title:hover{ text-decoration:underline; }
  .goal-pace-gap{ font-size:var(--type-lead); font-weight:650; margin-top:var(--space-2); display:flex;
    flex-wrap:wrap; gap:var(--space-1) var(--space-3); align-items:baseline; }
  .goal-pace-gap.is-behind{ color:var(--cat-red-2, var(--cat-red)); }
  .goal-pace-gap.is-ahead{ color:var(--green-2, var(--green)); }
  .goal-pace-gap.is-onpace{ color:var(--text); }
  .goal-pace-gap.is-untracked{ color:var(--text-dim); font-weight:600; font-size:var(--type-body); }
  .goal-pace-target{ font-weight:400; font-size:var(--type-body); color:var(--text-dim); }
  .goal-pace-deadline, .goal-pace-trend{ font-weight:400; font-size:var(--type-body); color:var(--text-faint);
    display:inline-flex; align-items:center; }
  .goal-pace-deadline::before, .goal-pace-trend::before{ content:'·'; margin-right:var(--space-3); }
  .goal-pace-next{ display:flex; align-items:baseline; gap:var(--space-2); font-size:var(--type-body); color:var(--text);
    margin-top:var(--space-3); padding-top:var(--space-2); border-top:1px solid var(--glass-border); cursor:pointer; }
  .goal-pace-next:hover{ text-decoration:underline; }
  .goal-pace-next .gl-mark{ flex:none; width:15px; text-align:center; color:var(--text-dim); }
  .goal-pace-next.is-empty{ color:var(--text-dim); }
  .goal-pace-due{ margin-left:auto; font-size:var(--type-body); color:var(--text-faint); }

  .goal-track-toggle{ font-size:var(--type-body); font-weight:600; color:var(--accent, var(--text));
    cursor:pointer; margin:var(--space-1) 0 var(--space-3); display:inline-block; }
  .goal-track-toggle:hover{ text-decoration:underline; }

  /* ROW 1722 — "a goal needs a specific date."
     The countdown, on the pace row and on the board card, so one goal cannot
     read two different ways depending on which view you are in. Three states
     and each one is a different WORD as well as a different colour: "42 days to
     go", "the date is today", "the date passed 6 days ago". The colour only
     ever confirms what the sentence already said, which is the rule the goal
     dots and the agenda temperature both follow.
     Nothing here goes red for a goal that is merely far away. A ten-year goal
     with a date in 2036 is not in trouble, and a screen that paints every
     deadline is a screen where no deadline means anything. */
  .goal-pace-when{ font-weight:600; font-size:var(--type-body); color:var(--text-dim);
    display:inline-flex; align-items:center; }
  .goal-pace-when + *{ margin-left:0; }
  .goal-pace-when::after{ content:'·'; margin:0 var(--space-2); color:var(--text-faint); font-weight:400; }
  .goal-pace-when.is-soon{ color:var(--orange); }
  .goal-pace-when.is-gone{ color:var(--cat-red-2, var(--cat-red)); }
  /* On paper the two warm states are stepped toward black for the same reason
     the late bar is: a warm hue at full strength on a near-white ground is the
     lowest-contrast thing on the page. */
  :root[data-mode="light"] .goal-pace-when.is-soon{ color:color-mix(in srgb, var(--orange) 74%, #000); }
  :root[data-mode="light"] .goal-pace-when.is-gone{ color:color-mix(in srgb, var(--cat-red) 82%, #000); }
  /* On the board card the meta row is already a list of short facts separated
     by space, so the countdown does not bring its own separator with it. */
  .goal-meta .goal-pace-when::after{ content:none; margin:0; }
  .goal-meta .goal-pace-when{ font-size:inherit; }

  /* ==========================================================
     THE GOALS DASHBOARD.

     "graphs charts, kpis, not rah rah, but something to jazz it
      up"   (Matt, 1 September.)

     Every number on it is uncomfortable on purpose. A dashboard
     for something that takes a decade is not there to say you
     are doing well — it is there to say which one you quietly
     stopped working on.

     Motion is one growth transition on arrival, and nothing
     after it. A screen that keeps moving is a screen people
     stop reading.
     ========================================================== */
/* THE LAST auto-FIT IN THE APP. .goal-dash is the strip of figures at the top
   of Goals and it carries the same bug .pulse-tiles had: auto-fit collapses
   the tracks it has not filled, so a person with one goal gets one 1734px-wide
   stat card. It could not be seen on the walk because the fixture has no goals
   in it — which is exactly the case that breaks — so it is fixed by reading
   rather than by screenshot, and the harness stages a single card into it to
   prove it. auto-fill keeps the empty tracks and the card stays card-sized.
   The 190px floor is its own and is right: these are figures, not cards. */
  .goal-dash{ display:grid; gap:var(--space-3); margin-bottom:var(--space-5);
    grid-template-columns:repeat(auto-fill, minmax(190px, 1fr)); }
  .gd-card{ border:1px solid var(--glass-border); border-radius:var(--radius-card);
    background:var(--glass-bg); padding:var(--space-3) var(--space-4); }
  .gd-wide{ grid-column:span 2; min-width:0; }
  @media (max-width: 700px){ .gd-wide{ grid-column:span 1; } }
  .gd-head{ font-size:var(--type-label); letter-spacing:.05em; text-transform:uppercase;
    color:var(--text-faint); margin-bottom:var(--space-2); }
  .gd-foot{ font-size:var(--type-label); color:var(--text-faint); margin-top:var(--space-2); }

  .gd-row{ display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-2); }
  .gd-label{ flex:0 0 38%; min-width:0; font-size:var(--type-body);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .gd-track{ flex:1; height:7px; border-radius:var(--radius-pill); min-width:0;
    background:color-mix(in srgb, var(--text) 8%, transparent); overflow:hidden; }
  /* The one piece of motion. It runs once, when the page arrives. */
  .gd-bar{ height:100%; border-radius:var(--radius-pill); width:0;
    animation: gdGrow .55s var(--ease-out) forwards; }
  @keyframes gdGrow{ from{ width:0; } }
  .gd-val{ flex:none; font-size:var(--type-label); color:var(--text-faint);
    font-variant-numeric:tabular-nums; min-width:34px; text-align:right; }

  .gd-big{ font-size:var(--type-figure); line-height:1; font-variant-numeric:tabular-nums; }
  .gd-big span{ font-size:var(--type-lead); color:var(--text-faint); }
  /* Amber, not red. Goals with no work against them are a prompt, not a fault. */
  .gd-warn{ color:var(--orange); }

  .gd-cols{ display:flex; align-items:flex-end; gap:var(--space-2); height:74px; }
  .gd-col{ flex:1; display:flex; flex-direction:column; justify-content:flex-end;
    align-items:center; height:100%; min-width:0; }
  .gd-col-bar{ width:100%; border-radius:var(--radius-control) var(--radius-control) 0 0; min-height:3px;
    background:var(--orb-accent, var(--accent));
    animation: gdRise .5s var(--ease-out) forwards; }
  @keyframes gdRise{ from{ height:0; } }
  .gd-col-lab{ font-size:var(--type-label); color:var(--text-faint); margin-top:var(--space-1); }

  /* Somebody who asked not to see motion gets the same chart, drawn. */
  @media (prefers-reduced-motion: reduce){
    .gd-bar, .gd-col-bar{ animation:none; }
    .gd-bar{ width:auto; }
  }


  /* ---- Goals: the week it must survive ---------------------------------- */
  .gw{ display:grid; grid-template-columns:minmax(0,1fr) 290px; gap:var(--space-4); align-items:start; }
  @media (max-width:900px){ .gw{ grid-template-columns:minmax(0,1fr); } }

  .gw-sheet{ padding:var(--space-5); }
  .gw-band{ padding-bottom:var(--space-5); margin-bottom:var(--space-5);
    border-bottom:1px solid var(--glass-border); }
  .gw-band:last-child{ border:0; padding-bottom:0; margin-bottom:0; }
  .gw-lab{ font-size:var(--type-label); font-weight:700; letter-spacing:.09em;
    text-transform:uppercase; color:var(--text-faint); margin:0 0 var(--space-3); }
  .gw-title{ font-size:20px; font-weight:600; margin:0 0 var(--space-1); }
  .gw-why{ color:var(--text-dim); font-style:italic; margin:0 0 var(--space-3); max-width:60ch; }
  .gw-topline{ display:flex; align-items:baseline; gap:var(--space-4); flex-wrap:wrap; }
  .gw-sub{ color:var(--text-dim); }
  .gw-fine{ font-size:var(--type-label); color:var(--text-faint); margin:var(--space-2) 0 0;
    font-style:italic; }

  /* The fourteen columns. A grid of fourteen equal tracks, so a fortnight that
     starts on a Tuesday still lines up with its labels. */
  .gw-14{ display:grid; grid-template-columns:repeat(14, minmax(0,1fr)); gap:3px;
    align-items:end; height:104px; margin-bottom:var(--space-2); }
  .gw-col{ position:relative; height:100%; display:flex; flex-direction:column;
    justify-content:flex-end; border-radius:3px 3px 0 0;
    background:color-mix(in srgb, var(--text) 5%, transparent); }
  .gw-fill{ border-radius:3px 3px 0 0; background:linear-gradient(180deg,
    color-mix(in srgb, var(--blue) 62%, transparent),
    color-mix(in srgb, var(--blue) 26%, transparent)); }
  .gw-col.is-away .gw-fill{ background:linear-gradient(180deg,
    color-mix(in srgb, var(--violet) 60%, transparent),
    color-mix(in srgb, var(--violet) 22%, transparent)); }
  .gw-col.has-room{ box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--green) 38%, transparent); }
  .gw-col.is-today{ box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent); }
  .gw-14lab{ display:grid; grid-template-columns:repeat(14, minmax(0,1fr)); gap:3px;
    font-family:'IBM Plex Mono', ui-monospace, monospace; font-size:9px;
    color:var(--text-faint); text-align:center; font-variant-numeric:tabular-nums; }
  .gw-14lab span.is-away{ color:var(--violet-2); }
  .gw-14lab span.is-today{ color:var(--text); font-weight:600; }

  .gw-key{ display:flex; gap:var(--space-4); flex-wrap:wrap; margin-top:var(--space-3);
    font-size:var(--type-label); color:var(--text-faint); }
  .gw-key i{ display:inline-block; width:9px; height:9px; border-radius:2px;
    margin-right:5px; vertical-align:-1px; }
  .gw-sw-busy{ background:color-mix(in srgb, var(--blue) 50%, transparent); }
  .gw-sw-away{ background:color-mix(in srgb, var(--violet) 50%, transparent); }
  .gw-sw-room{ background:transparent;
    box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--green) 55%, transparent); }
  .gw-sum{ margin-top:var(--space-3); font-size:16px; color:var(--text); }
  .gw-sum b{ color:var(--green-2); font-weight:600; }
  .gw-sum b.is-bad{ color:var(--pink-2); }

  /* THE FAILED READ. Deliberately unlike every other state on this page: a
     pink rule, an alert role, and NO COLUMNS ANYWHERE INSIDE IT. An empty
     fortnight and an unread one must not be able to look the same, so this
     block does not contain a .gw-14 and the check asserts that it does not. */
  .gw-unread{ border:1px solid color-mix(in srgb, var(--pink) 40%, transparent);
    border-left:3px solid var(--pink); border-radius:var(--radius-control);
    background:color-mix(in srgb, var(--pink) 8%, transparent); padding:var(--space-4); }
  .gw-unread-line{ margin:0 0 var(--space-2); font-size:16px; color:var(--text); }
  .gw-unread-why{ margin:0 0 var(--space-2); font-family:'IBM Plex Mono', ui-monospace, monospace;
    font-size:var(--type-label); color:var(--pink-2); word-break:break-word; }

  .gw-verdict{ border:1px solid var(--glass-border); border-radius:var(--radius-control);
    padding:var(--space-4); background:var(--wash-soft); }
  .gw-verdict p{ margin:0 0 var(--space-3); font-size:16px; line-height:1.4; }
  .gw-verdict.is-short,
  .gw-verdict.is-no-room,
  .gw-verdict.is-nothing{ border-left:3px solid var(--pink);
    background:color-mix(in srgb, var(--pink) 7%, transparent); }
  .gw-verdict.is-ahead{ border-left:3px solid var(--green);
    background:color-mix(in srgb, var(--green) 6%, transparent); }
  /* IT FITS — and only just, and only if he books it. Brass rather than
     green: it is not good news, it is a condition. It used to share the pink
     rule with "it does not get there", which had the colour arguing with the
     sentence. */
  .gw-verdict.is-fits,
  .gw-verdict.is-plain{ border-left:3px solid var(--brass);
    background:color-mix(in srgb, var(--brass) 7%, transparent); }
  .gw-verdict.is-unread{ border-left:3px solid var(--pink);
    background:color-mix(in srgb, var(--pink) 8%, transparent); }
  .gw-acts{ display:flex; gap:var(--space-2); flex-wrap:wrap; }

  .gw-ev{ display:flex; gap:var(--space-3); align-items:flex-start;
    padding:var(--space-2) var(--space-3); border-radius:var(--radius-control);
    background:var(--wash-soft); margin-bottom:var(--space-2); }
  .gw-ev:last-child{ margin-bottom:0; }
  .gw-ev.is-empty{ color:var(--text-dim); }
  .gw-ev-mk{ font-family:'IBM Plex Mono', ui-monospace, monospace; color:var(--text-faint);
    flex:none; width:16px; text-align:center; }
  .gw-ev-bd{ flex:1; min-width:0; }

  .gw-pick{ display:flex; flex-direction:column; gap:2px; padding:var(--space-3); }
  .gw-pick button{ display:flex; flex-direction:column; align-items:flex-start; gap:1px;
    width:100%; text-align:left; font-family:inherit; background:none; border:0; cursor:pointer;
    padding:var(--space-2) var(--space-3); border-radius:var(--radius-control);
    border-left:2px solid transparent; color:var(--text-dim);
    transition:background var(--dur-fast, 130ms) var(--ease-out); }
  .gw-pick button:hover{ background:var(--wash-hover); }
  .gw-pick button.is-on{ background:var(--wash-hover); color:var(--text);
    border-left-color:color-mix(in srgb, var(--accent) 75%, transparent); }
  .gw-pick button:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
  .gw-pick-t{ font-weight:600; }
  .gw-pick-s{ font-size:var(--type-label); color:var(--text-faint); }
  .gw-pick-s.is-short, .gw-pick-s.is-no-room, .gw-pick-s.is-nothing{ color:var(--pink-2); }
  .gw-pick-s.is-ahead{ color:var(--green-2); }
  .gw-pick-s.is-unread{ color:var(--orange-2); }

  @media (prefers-reduced-motion:reduce){
    .gw-pick button{ transition:none; }
  }
