/* ============================================================
   Brand palette — change these to repaint the whole app
   ============================================================ */

:root {
  --brand-brown:  #725E54;
  --brand-cream:  #F7F9F9;
  --brand-tan:    #E0D0C1;
  --brand-blue:   #246EB9;
  --brand-green:  #00A9A5;
  --brand-yellow: #FFF275;
  --brand-red:    #FE938C;
}

/* ============================================================
   Map brand colors onto Pico variables
   ============================================================ */

:root,
[data-theme="light"] {
  /* Page surface */
  --pico-background-color: var(--brand-tan);
  --pico-color:            var(--brand-brown);
  --pico-h1-color:         var(--brand-brown);
  --pico-h2-color:         var(--brand-brown);
  --pico-h3-color:         var(--brand-brown);
  --pico-h4-color:         var(--brand-brown);
  --pico-muted-color:      var(--brand-brown);
  --pico-muted-border-color: var(--brand-brown);

  /* Cards */
  --pico-card-background-color:            var(--brand-cream);
  --pico-card-sectioning-background-color: var(--brand-cream);
  --pico-card-border-color:                var(--brand-tan);

  /* Primary = blue (main CTA: Add Task, Submit) */
  --pico-primary:                  var(--brand-blue);
  --pico-primary-background:       var(--brand-blue);
  --pico-primary-border:            var(--brand-blue);
  --pico-primary-hover:             var(--brand-blue);
  --pico-primary-hover-background:  var(--brand-blue);
  --pico-primary-hover-border:      var(--brand-blue);
  --pico-primary-inverse:           var(--brand-cream);
  --pico-primary-focus:             rgba(114, 94, 84, 0.35);

  /* Secondary = brown */
  --pico-secondary:                  var(--brand-brown);
  --pico-secondary-background:       var(--brand-brown);
  --pico-secondary-border:           var(--brand-brown);
  --pico-secondary-hover:            var(--brand-brown);
  --pico-secondary-hover-background: var(--brand-brown);
  --pico-secondary-hover-border:     var(--brand-brown);
  --pico-secondary-inverse:          var(--brand-cream);
  --pico-secondary-focus:            rgba(114, 94, 84, 0.35);

  /* Contrast = also brown (used by Pico in a few places) */
  --pico-contrast:                  var(--brand-brown);
  --pico-contrast-background:       var(--brand-brown);
  --pico-contrast-hover:            var(--brand-brown);
  --pico-contrast-hover-background: var(--brand-brown);
  --pico-contrast-inverse:          var(--brand-cream);
  --pico-contrast-focus:            rgba(114, 94, 84, 0.35);

  /* Forms */
  --pico-form-element-background-color:         var(--brand-cream);
  --pico-form-element-border-color:             var(--brand-brown);
  --pico-form-element-color:                    var(--brand-brown);
  --pico-form-element-active-background-color:  var(--brand-cream);
  --pico-form-element-active-border-color:      var(--brand-brown);
  --pico-form-element-focus-color:              rgba(114, 94, 84, 0.5);
  --pico-form-element-placeholder-color:        var(--brand-brown);

  /* Links */
  --pico-link:                  var(--brand-blue);
  --pico-link-hover:            var(--brand-green);
  --pico-link-underline:        transparent;
  --pico-link-hover-underline:  var(--brand-green);

  /* Border radius — keep Pico default but expose it */
  --pico-border-radius: 0.5rem;
}

/* ============================================================
   Design tokens — type and vertical rhythm
   Every font size, font weight and vertical gap in this file comes from
   these, so the whole app retunes from here.
   ============================================================ */

:root {
  /* Three text sizes:
     sm — meta & secondary: dates, hints, chips, badges, pills, tooltips
     md — everything you read or type: body, controls, labels, card titles
     lg — page and modal titles
     (md stays 16px: iOS zooms into form fields with smaller text) */
  --text-sm: 0.8125rem;
  --text-md: 1rem;
  --text-lg: 1.25rem;
  --text-display: 2.25rem; /* the fourth size, for the landing page headline */

  /* Two weights; italic is kept for "pending / empty" states */
  --weight-regular: 400;
  --weight-bold: 700;

  /* Vertical rhythm — the only vertical gaps used:
     1 within a group (label → field, rows of a list, card header/footer)
     2 between groups (field → field, cards, header → content)
     3 between sections of a screen
     4 page level */
  --space-1: 10px;
  --space-2: 20px;
  --space-3: 30px;
  --space-4: 40px;

  /* Motion: short and gentle; all of it is off for prefers-reduced-motion */
  --motion-fast: 150ms;
  --motion: 250ms;
  --motion-slow: 500ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* On phones the display size steps down — still one variable */
@media (max-width: 575px) {
  :root {
    --text-display: 1.75rem;
  }
}

/* Feed the tokens into Pico, so its own margins follow the same rhythm.
   Pico also grows the root font with the viewport (up to 131% on wide
   screens) — keep one size everywhere. */
:root {
  --pico-font-size: 100%;
  --pico-spacing: var(--space-2);
  --pico-typography-spacing-vertical: var(--space-2);
  --pico-block-spacing-vertical: var(--space-2);
  --pico-form-element-spacing-vertical: 0.5rem;
  --pico-form-element-spacing-horizontal: 0.8rem;
}

/* A light, crisp card shadow instead of Pico's wide soft halo
   (same selector as Pico's light theme, so this one wins) */
:root:not([data-theme="dark"]) {
  --pico-card-box-shadow:
    0 1px 2px color-mix(in srgb, var(--brand-brown) 10%, transparent),
    0 4px 14px color-mix(in srgb, var(--brand-brown) 6%, transparent);
}

/* The app's three key words — who / when / what — in the logo's colours,
   wherever they appear: the task form's labels, the landing page copy */
.keyword-who,  .label-who  { color: var(--brand-brown); }
.keyword-when, .label-when { color: var(--brand-blue); }
.keyword-what, .label-what { color: var(--brand-green); }

.keyword {
  font-weight: var(--weight-bold);
}

/* ✓ / ✗ in running text, coloured like the answer buttons on a task card */
.mark-yes { color: var(--brand-green); }
.mark-no  { color: var(--brand-red); }

h1, h2 { --pico-font-size: var(--text-lg); }
h3, h4, h5, h6 { --pico-font-size: var(--text-md); }

h1, h2, h3, h4, h5, h6 {
  --pico-font-weight: var(--weight-bold);
}

small {
  --pico-font-size: var(--text-sm);
}

/* Within a field group: label → control, control → its hint */
label,
fieldset legend {
  margin-bottom: var(--space-1);
}

:where(input, select, textarea, fieldset, .grid) + small {
  margin-top: calc(var(--space-1) - var(--pico-spacing));
}

/* Card header / footer strips */
article > header,
article > footer {
  padding-block: var(--space-1);
}

/* Page header: logo row padded by the nav items only, then the content */
body > header {
  padding-block: 0;
  --pico-nav-element-spacing-vertical: var(--space-1);
}

body > main {
  padding-top: var(--space-1);
}

/* A centred, readable column on wide screens rather than Pico's 1200px+ */
@media (min-width: 1024px) {
  .container {
    max-width: 60rem;
  }
}

/* Submit buttons hug their label instead of spanning the whole form */
form input[type="submit"] {
  width: auto;
  padding-inline: 1.25rem;
}

/* ============================================================
   White bold text on brown / blue / green surfaces
   (per spec: any text on those three colors must be bold + cream)
   ============================================================ */

button,
[role="button"],
input[type="submit"],
input[type="button"] {
  font-weight: var(--weight-bold);
  color: var(--brand-cream);
}

/* Outline / link variants of buttons keep their colored text — opt out */
[role="button"].outline,
button.outline,
[role="button"].secondary.outline,
button.secondary.outline {
  color: var(--brand-brown);
}

/* ============================================================
   Layout
   ============================================================ */

html {
  background-color: var(--brand-tan);
  /* Pico keeps hidden tooltip bubbles in the layout; one over an avatar at
     the right edge would otherwise make the page scroll sideways */
  overflow-x: clip;
}

body {
  background-color: var(--brand-tan);
  /* The same, for phones: html's overflow goes to the viewport, where clip
     turns into hidden — and mobile Chrome (the app's WebView too) still widens
     the page to fit the bubbles. On body (kept from the viewport by html's
     own value above) it's a plain clip. */
  overflow-x: clip;
  min-height: 100dvh;
}

/* Header / logo */

.header-logo {
  display: inline-grid;
  align-items: center;
}

.header-logo .logo {
  display: block;
  height: 3rem;
  width: auto;
  aspect-ratio: 260 / 90; /* the SVG's viewBox */
  max-width: none; /* keep its size; Pico's max-width: 100% squashes it in the grid */
  overflow: visible; /* the people step outside the viewBox on hover */
}

/* The three people of the logo, in the brand colours; on hover the outer two
   step apart (SVG transforms are in viewBox units: ~260 across) */
.logo-person-left   { color: var(--brand-brown); }
.logo-person-middle { color: var(--brand-blue); }
.logo-person-right  { color: var(--brand-green); }

.logo-person {
  transition: transform var(--motion-slow) var(--ease-out);
}

.header-logo:is(:hover, :focus-visible) .logo-person-left {
  transform: translateX(-14px);
}

.header-logo:is(:hover, :focus-visible) .logo-person-right {
  transform: translateX(14px);
}

/* Nav links in header */
header nav a {
  color: var(--brand-brown);
}

header nav a:hover {
  color: var(--brand-blue);
}

/* Logo + inline links on the left, hamburger pinned to the right */
header nav {
  display: grid;
  grid-template-columns: auto 1fr auto;
  column-gap: 1rem;
}

header nav > .nav-menu {
  grid-column: 3;
}

/* Tasks / Topics beside the logo, on every screen size */
.nav-links {
  display: flex;
}

.nav-links a {
  position: relative;
  font-weight: var(--weight-bold);
  text-decoration: none;
}

/* Underline that grows out from the centre on hover, and stays under the
   current page (inset by the link's padding so it spans just the text) */
.nav-links a::after {
  content: "";
  position: absolute;
  left: var(--pico-nav-link-spacing-horizontal);
  right: var(--pico-nav-link-spacing-horizontal);
  bottom: calc(var(--pico-nav-link-spacing-vertical) - 2px);
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transition: transform var(--motion) var(--ease-out);
}

.nav-links a:hover::after,
.nav-links a.active::after {
  transform: scaleX(1);
}

/* Current page inside the account / guest menus */
header nav details a.active {
  text-decoration: underline;
}


/* Pico renders nav dropdowns inline, so whitespace around them pushes the
   hamburger off the right edge — make it a block to line up with the content.
   Its negative vertical margin then lifts it above the links, so drop that too. */
.nav-menu details.dropdown {
  display: block;
  margin: 0;
}

/* Guests' hamburger and flag picker: the icon/flag is enough — drop Pico's
   dropdown chevron — and they're identical squares side by side */
.nav-menu details.dropdown:not(.user-menu) > summary::after {
  display: none;
}

.nav-menu details.dropdown:not(.user-menu) > summary {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
}

/* Signed-in account menu: their ringed badge + a quiet name in an outlined
   pill, keeping Pico's chevron so it reads as a button. (Selector matches
   Pico's own nav dropdown summary rule so this one wins.) */
header nav details.user-menu > summary:not([role]) {
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  column-gap: 0.5rem;
  height: auto;
  padding: 0.3rem 0.6rem 0.3rem 0.35rem;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 35%, transparent);
  border-radius: 999px;
  background-color: transparent;
  color: var(--brand-brown);
}

header nav details.user-menu > summary:not([role]):hover,
header nav details.user-menu[open] > summary:not([role]) {
  border-color: var(--brand-brown);
}

/* The ring's inner gap matches the header background, not a card */
.user-menu .avatar-me {
  box-shadow: 0 0 0 2px var(--brand-tan), 0 0 0 4px var(--brand-blue);
}

/* Long names are cut server-side (UsersHelper#short_name); the full name is
   in its title and the menu's aria-label */
.nav-user-name {
  white-space: nowrap;
  font-size: var(--text-md);
  opacity: 0.8;
}

/* Phones: logo, Tasks / Topics and the account button must share one row, so
   shrink the logo, tighten the gaps and show just the badge (name is in the
   menu's aria-label) */
@media (max-width: 575px) {
  header nav {
    column-gap: 0.5rem;
    --pico-nav-element-spacing-horizontal: 0.3rem;
  }

  .header-logo .logo {
    height: 1.75rem;
  }

  .nav-user-name {
    display: none;
  }

  header nav details.user-menu > summary:not([role]) {
    column-gap: 0.25rem;
    padding: 0.2rem 0.4rem 0.2rem 0.2rem;
  }
}

/* The narrowest phones: the outlined pill alone says "button" — drop the chevron */
@media (max-width: 359px) {
  .header-logo .logo {
    height: 1.5rem;
  }

  header nav details.user-menu > summary:not([role]) {
    padding: 0.2rem 0.45rem;
  }

  header nav details.user-menu > summary:not([role])::after {
    display: none;
  }
}

/* Language picker for guests: a flag square beside the hamburger */
.flag {
  display: block;
  width: 1.5rem;
  max-width: none; /* Pico's max-width: 100% collapses it inside auto grid tracks */
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--brand-brown) 25%, transparent);
}


/* Square crop (no squashing); Esperanto keeps its starred corner in view */
.flag-square {
  aspect-ratio: 1;
  object-fit: cover;
}

.flag-square.flag-eo {
  object-position: left center;
}

/* The picker button is the flag itself, filling the hamburger-sized square */
.locale-menu > summary {
  overflow: hidden;
  border: none;
  background: none;
}

.locale-menu > summary .flag {
  width: 100%;
  height: 100%;
  border-radius: inherit;
}

.locale-option-form {
  margin: 0;
}

/* Each option is a bare button (flag + name) inside Pico's dropdown list */
.locale-option {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 0.6rem;
  width: 100%;
  margin: 0;
  padding: calc(var(--pico-nav-link-spacing-vertical) * 0.75) var(--pico-nav-link-spacing-horizontal);
  border: none;
  border-radius: var(--pico-border-radius);
  background: none;
  color: var(--brand-brown);
  text-align: start;
  white-space: nowrap;
}

.locale-option:hover {
  background-color: var(--brand-tan);
}

/* Dropdown menu items */
details.dropdown ul {
  background-color: var(--brand-cream);
}

details.dropdown ul a {
  color: var(--brand-brown);
}

details.dropdown ul a:hover {
  background-color: var(--brand-tan);
  color: var(--brand-brown);
}

/* Tighter side margins & gaps on phones */
@media (max-width: 767px) {
  header.container,
  main.container {
    padding-inline: 1rem;
  }

  .tasks-navigation {
    column-gap: 0.75rem;
  }
}

/* ============================================================
   Landing page (home#index)
   ============================================================ */

.landing {
  display: grid;
  row-gap: var(--space-4);
  padding-block: var(--space-3) var(--space-4);
}

.landing h2 {
  text-align: center;
  margin-bottom: var(--space-1);
}

.landing h3 {
  margin-bottom: var(--space-1);
}

.landing p {
  margin: 0;
}

/* Hero: headline, lead, the two buttons and the main screenshot */
.landing-hero {
  display: grid;
  justify-items: center;
  row-gap: var(--space-2);
  text-align: center;
}

.landing-hero h1 {
  max-width: 20ch;
  margin: 0;
  font-size: var(--text-display);
  line-height: 1.15;
  text-wrap: balance;
}


.landing-lead {
  max-width: 38rem;
  text-wrap: pretty;
}

.landing-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-1) 0.75rem;
}

.landing-actions [role="button"] {
  margin: 0;
}

.landing-hero .landing-shot {
  margin-top: var(--space-2);
}

/* Screenshots: framed like a window floating on the page */
.landing-shot {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 15%, transparent);
  border-radius: 12px;
  box-shadow:
    0 2px 6px color-mix(in srgb, var(--brand-brown) 10%, transparent),
    0 18px 40px color-mix(in srgb, var(--brand-brown) 14%, transparent);
}

.landing .landing-section-lead {
  max-width: 34rem;
  margin: 0 auto var(--space-2);
  text-align: center;
}

/* Round icon badges, in the logo's three colours in turn */
.landing-icon {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background-color: var(--brand-brown);
  color: var(--brand-cream);
}

.landing-icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

:nth-child(3n + 2) > .landing-icon { background-color: var(--brand-blue); }
:nth-child(3n + 3) > .landing-icon { background-color: var(--brand-green); }

/* "One app, every circle": four small cards */
/* Two per row even on a phone, four on wide screens */
.landing-circles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: var(--space-2);
}

.landing-circle {
  margin: 0;
}

.landing-circle .landing-icon {
  margin-bottom: var(--space-1);
}

.landing-circle p,
.landing-steps p {
  font-size: var(--text-sm);
  opacity: 0.85;
}

/* How it works: three numbered steps */
.landing-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.landing-steps li {
  list-style: none;
  text-align: center;
}

.landing-step-number {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: var(--space-1);
  border: 2px solid var(--brand-blue);
  border-radius: 50%;
  color: var(--brand-blue);
  font-weight: var(--weight-bold);
}

/* Features: text beside a screenshot, sides alternating on wide screens */
.landing-features {
  display: grid;
  row-gap: var(--space-4);
}

.landing-feature {
  display: grid;
  row-gap: var(--space-2);
  align-items: center;
}

.landing-feature h2 {
  text-align: start;
}

@media (min-width: 768px) {
  .landing-feature {
    grid-template-columns: 2fr 3fr;
    column-gap: var(--space-4);
  }

  .landing-feature:nth-child(even) {
    grid-template-columns: 3fr 2fr;
  }

  .landing-feature:nth-child(even) .landing-feature-text {
    order: 2;
  }
}

/* A few small things that help */
.landing-perks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.landing-perks li {
  display: flex;
  align-items: center;
  column-gap: 0.75rem;
  list-style: none;
  font-size: var(--text-sm);
}

/* Closing call to action */
.landing-cta {
  display: grid;
  justify-items: center;
  row-gap: var(--space-1);
  padding: var(--space-3) var(--space-2);
  border-radius: 12px;
  background-color: var(--brand-cream);
  box-shadow: var(--pico-card-box-shadow);
  text-align: center;
}

.landing-cta [role="button"] {
  margin: var(--space-1) 0 0;
}

/* ============================================================
   Sign in / sign up & other Devise pages — a narrow centred card
   ============================================================ */

/* Sign-up's bot trap: there for bots, off screen for people (not display: none,
   which some bots skip) */
.honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.auth-card {
  max-width: 26rem;
  margin: var(--space-3) auto;
}

.auth-card input[type="submit"] {
  width: 100%;
}

/* Secondary links (sign up, forgot password…) stacked, small and quiet */
.auth-card > footer nav,
.auth-card > footer nav ul {
  display: block;
  margin: 0;
  padding: 0;
}

.auth-card > footer nav li {
  display: block;
  padding: 0;
  font-size: var(--text-sm);
}

/* ============================================================
   Settings — one narrow column of compact cards
   ============================================================ */

.settings {
  max-width: 40rem;
  margin-inline: auto;
}

.settings article > form {
  margin-bottom: 0;
}

/* Email / password: a row (label · value · "Change") that folds its form away */
.settings-rows {
  border-top: 1px solid color-mix(in srgb, var(--brand-brown) 12%, transparent);
}

.settings-rows > div {
  border-bottom: 1px solid color-mix(in srgb, var(--brand-brown) 12%, transparent);
}

.settings-rows > div:last-child {
  border-bottom: none;
}

.settings-row {
  margin: 0;
  border: none;
}

.settings-row > summary {
  display: grid;
  grid-template-columns: 7rem 1fr auto;
  align-items: center;
  column-gap: 1rem;
  padding: var(--space-1) 0;
  list-style: none;
}

/* The "Change" pill is the affordance — no Pico chevron */
.settings-row > summary::after,
.settings-row > summary::-webkit-details-marker {
  display: none;
}

.settings-row-label {
  font-weight: var(--weight-bold);
}

.settings-row-value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 0.8;
}

.settings-row-action {
  padding: 0.2rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 35%, transparent);
  border-radius: 999px;
  font-size: var(--text-sm);
}

.settings-row > summary:hover .settings-row-action,
.settings-row[open] .settings-row-action {
  border-color: var(--brand-brown);
}

.settings-row > form {
  padding-bottom: var(--space-2);
}

@media (max-width: 575px) {
  .settings-row > summary {
    grid-template-columns: 1fr auto;
  }

  .settings-row-value {
    grid-row: 2;
  }
}

/* Pending email change: a quiet line with its cancel button */
.settings-pending {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 0.75rem;
  padding-bottom: var(--space-1);
}

.settings-pending small {
  color: var(--brand-green);
  font-weight: var(--weight-bold);
}

.settings-pending form,
.settings-sign-out form {
  margin: 0;
}

/* Small outlined buttons (cancel pending change, sign out, delete account) */
.settings-pending button,
.settings-sign-out button,
.settings-danger button {
  width: auto;
  margin: 0;
  padding: 0.3rem 0.85rem;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 40%, transparent);
  background: transparent;
  color: var(--brand-brown);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

.settings-pending button:hover,
.settings-sign-out button:hover,
.settings-danger button:hover {
  border-color: var(--brand-brown);
}

/* Delete account: what it does, then the password with its button beside it */
.settings-danger h3 {
  margin-bottom: var(--space-1);
}

.settings-danger p {
  margin: 0;
  font-size: var(--text-sm);
  opacity: 0.8;
}

.settings-danger form {
  margin: var(--space-2) 0 0;
}

.settings-danger-row {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.settings-danger-row input {
  flex: 1;
  margin: 0;
}

.settings-danger-row button {
  align-self: stretch;
}

.settings-danger button:hover {
  border-color: var(--brand-red);
  color: var(--brand-brown);
}

/* Language: compact flag + name pills */
.locale-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) 0.5rem;
}

.locale-choice-form {
  margin: 0;
}

.locale-choice {
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  column-gap: 0.5rem;
  width: auto;
  margin: 0;
  padding: 0.4rem 0.85rem 0.4rem 0.6rem;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 25%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--brand-brown);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
}

.locale-choice:hover {
  border-color: var(--brand-brown);
}

.locale-choice.active {
  border-color: var(--brand-blue);
  box-shadow: 0 0 0 1px var(--brand-blue);
  font-weight: var(--weight-bold);
}

/* ============================================================
   Tasks & Topics list
   ============================================================ */

.tasks-navigation {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 1rem;
  align-items: center;
  margin-bottom: var(--space-2);
}

/* Only an action button (no title / filter): keep it on the right */
.tasks-navigation > [role="button"]:only-child {
  grid-column: 2;
}

.tasks-navigation select,
.tasks-navigation [role="button"] {
  margin-bottom: 0;
}

.tasks-navigation h2 {
  margin-bottom: 0;
}

.tasks-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

/* The grid gap spaces the cards (grid items' margins would add to it) */
.tasks-grid > article {
  margin-bottom: 0;
}

/* Card internals — grid only */

.task-card > header,
.task-card > footer {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 0.5rem;
}

.task-card > header strong {
  color: var(--brand-brown);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
}

/* A task the signed-in user is assigned to: a blue stripe down the left edge
   (the colour of their ringed badge). It's drawn over the header/footer
   backgrounds and follows the card's rounded corners — no overflow: hidden,
   which would clip the avatar tooltips. */
.task-card-mine {
  position: relative;
}

.task-card-mine::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  z-index: 1;
  width: 4px;
  border-radius: var(--pico-border-radius) 0 0 var(--pico-border-radius);
  background-color: var(--brand-blue);
  pointer-events: none;
}


.task-card > footer small,
.now-marker small {
  color: var(--brand-brown);
  opacity: 0.75;
}

/* "Now" marker between past and upcoming tasks: a faint full-width line with
   the current time above it, inset like the dates in the card footers */
.now-marker {
  display: grid;
}

.now-marker small {
  padding-inline: var(--pico-block-spacing-horizontal);
}

.now-marker::after {
  content: "";
  border-top: var(--pico-border-width) solid var(--brand-brown);
  opacity: 0.3;
}

/* Assignees: a row of initial badges, wrapping when there are many */
.avatars {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-1) 0.4rem; /* room for the "me" ring and the answer marks */
}

.avatar {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--brand-green);
  color: var(--brand-cream);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
  line-height: 1;
}

/* Drop Pico's dotted "help" underline; the tooltip opens on click/tap too */
.avatar[data-tooltip] {
  border-bottom: none;
  cursor: pointer;
}

/* The signed-in user's own badge: a blue ring, set off by a card-coloured gap */
.avatar-me {
  box-shadow: 0 0 0 2px var(--brand-cream), 0 0 0 4px var(--brand-blue);
}

/* Their answer on the task: ✓ / ✗ mark tucked into the badge's corner */
.avatar-status {
  position: absolute;
  right: -0.35rem;
  bottom: -0.35rem;
  display: grid;
  place-items: center;
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--brand-cream);
  border-radius: 50%;
}

.avatar-status svg {
  width: 0.6rem;
  height: 0.6rem;
  stroke-width: 4;
}

.avatar-status-yes {
  background: var(--brand-green);
  color: var(--brand-cream);
}

.avatar-status-no {
  background: var(--brand-red);
  color: var(--brand-brown);
}

/* No description: hide the empty paragraph and drop the header/footer
   dividers + spacing so the card has no blank gap */
.task-card:has(> p:empty) > p {
  display: none;
}

.task-card:has(> p:empty) > header {
  margin-bottom: 0;
  border-bottom: none;
}

.task-card:has(> p:empty) > footer {
  margin-top: 0;
  border-top: none;
}

.task-actions {
  display: grid;
  grid-auto-flow: column;
  column-gap: 0.75rem;
  align-items: center;
}

.task-actions a {
  color: var(--brand-brown);
  display: inline-grid;
  align-items: center;
}

/* Lucide's 24px default is loud next to the card text */
.task-actions svg,
.member-controls svg {
  width: 1.15rem;
  height: 1.15rem;
}

.task-actions a:hover {
  color: var(--brand-blue);
}

.task-actions .danger:hover {
  color: var(--brand-brown);
  opacity: 0.6;
}

/* The assignee's own ✓ / ✗ answer: faint until hovered or chosen */
.task-actions .confirm-toggle {
  opacity: 0.45;
}

.task-actions .confirm-toggle:hover,
.task-actions .confirm-toggle.active {
  opacity: 1;
}

.task-actions .confirm-toggle-yes:hover,
.task-actions .confirm-toggle-yes.active {
  color: var(--brand-green);
}

.task-actions .confirm-toggle-no:hover,
.task-actions .confirm-toggle-no.active {
  color: var(--brand-red);
}

/* ============================================================
   Icon buttons — grow slightly on hover, with delayed tooltips
   ============================================================ */

.icon-action {
  transition: color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
  transform-origin: center;
}

.icon-action:hover,
.icon-action:focus-visible {
  transform: scale(1.25);
}

/* Any outline-based focus ring should be brown, matching the modal border */
:focus-visible {
  outline-color: var(--brand-brown);
}

/* On-brand tooltip colour (Pico vars recolour both the bubble and its arrow) */
[data-tooltip] {
  --pico-tooltip-background-color: var(--brand-brown);
  --pico-tooltip-color: #fff;
}

/* Mobile app: a form's submit button is in the app's top bar instead
   (bridge/form_controller.js — the app lists the components it supports here) */
[data-bridge-components~="form"] [data-bridge--form-target="submit"] {
  display: none;
}

/* None in the mobile app: on a touch screen a bubble would only stick after a tap */
.native-app [data-tooltip]::before,
.native-app [data-tooltip]::after {
  display: none;
}

/* Smaller, more compact tooltip bubble */
[data-tooltip]::before {
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  padding: 0.12rem 0.38rem;
}

/* Hold off a moment so tooltips read as intentional, not twitchy.
   (Pico's own pseudo-elements load before this file, so these win.) */
[data-tooltip]:hover::before,
[data-tooltip]:hover::after,
[data-tooltip]:focus::before,
[data-tooltip]:focus::after {
  transition-delay: 0.35s;
}

/* ============================================================
   Clickable topic card — stretched link
   ============================================================ */

.topic-card {
  position: relative;
  transition: border-color 0.15s ease;
}

.topic-card-link {
  text-decoration: none;
  color: var(--brand-brown);
}

.topic-card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
}

.topic-card .task-actions {
  position: relative;
  z-index: 1;
}

.topic-card:hover {
  border-color: var(--brand-blue);
}

.topic-card:hover .topic-card-link strong {
  color: var(--brand-blue);
}

/* Description → member chips is one group */
.topic-card > p {
  margin-bottom: var(--space-1);
}

.topic-members {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) 0.35rem;
}

.topic-members li {
  list-style: none;
  font-size: var(--text-sm);
  padding: 0.1rem 0.55rem;
  border-radius: 999px;
  background-color: var(--brand-tan);
  color: var(--brand-brown);
}

/* Invited but no account yet — muted grey to set them apart from members */
.topic-members li.pending {
  background-color: #e6e3df;
  color: #7a756e;
  font-style: italic;
}

/* ============================================================
   Task form
   ============================================================ */

.task-form label,
.task-form legend {
  font-weight: var(--weight-bold);
}

/* "Who" label with the people filter beside it */
.assignee-header {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 0.75rem;
  margin-bottom: var(--space-1);
  font-weight: var(--weight-bold);
}

.assignee-header input[type="search"] {
  margin: 0;
  --pico-form-element-spacing-vertical: 0.3rem;
  /* Pico gives search inputs a pill (5rem) radius; match the other fields */
  --pico-border-radius: inherit;
}

/* "Who": topic members as checkbox rows — the whole row is the label.
   Bleeds to the modal's edges (like Pico's article header/footer) so the
   selected-row highlight spans the full width. */
.assignee-list {
  --assignee-divider: color-mix(in srgb, var(--brand-brown) 20%, transparent);
  display: grid;
  margin: 0 calc(var(--pico-block-spacing-horizontal) * -1); /* the fieldset spaces it */
  border-block: 1px solid var(--assignee-divider);
}

.task-form .assignee-row {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  column-gap: 0.6rem;
  margin: 0;
  padding: var(--space-1) var(--pico-block-spacing-horizontal);
  border-bottom: 1px solid var(--assignee-divider);
  font-weight: var(--weight-regular);
  cursor: pointer;
  width: auto; /* Pico shrinks checkbox labels to fit-content; span the row */
}

.task-form .assignee-row:last-child {
  border-bottom: none;
}

.assignee-row:hover {
  background: color-mix(in srgb, var(--brand-brown) 8%, transparent);
}

.assignee-row:has(:checked) {
  background: color-mix(in srgb, var(--brand-green) 15%, transparent);
}

.assignee-row input[type="checkbox"] {
  margin: 0;
}

.assignee-empty {
  display: block;
  padding: var(--space-1) var(--pico-block-spacing-horizontal);
  font-size: var(--text-sm);
  font-style: italic;
  opacity: 0.75;
}

/* Who / When / What carry the brand palette from the logo — here and on
   the landing page (see "Key words" near the top) */

/* ============================================================
   Modal (Pico dialog) chrome
   ============================================================ */

/* Brown border + page-matching tan surface around the whole modal */
dialog article {
  border: 2px solid var(--brand-brown);
  background-color: var(--brand-tan);
  /* Nothing here scrolls sideways; without this Chrome counts the header's
     edge-to-edge bleed plus padding and shows a horizontal scrollbar */
  overflow-x: hidden;
}

/* Header carries only the title + close button — drop Pico's surface + divider,
   and keep the title close to the content below it */
dialog article > header {
  padding-top: var(--space-2); /* border → title, matching the button → border gap below */
  margin-bottom: var(--space-1); /* + the header's own padding: title → content is --space-2 */
  background-color: transparent;
  border-bottom: none;
}

/* The turbo-frame modal's header: optional title, close button pinned right */
#modal dialog article > header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 1rem;
}

#modal dialog article > header h2 {
  margin: 0;
}

/* The modal's padding is the gap under the final button — drop its own margin */
dialog article input[type="submit"]:last-child {
  margin-bottom: 0;
}

#modal dialog article > header .modal-close {
  grid-column: 2;
}

/* Close "X": border-coloured Lucide icon, no Pico button chrome.
   Scaling on hover is handled by the shared .icon-action rule. */
.modal-close {
  width: auto;
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  color: var(--brand-brown);
  line-height: 0;
}

.modal-close svg {
  width: 1.3rem;
  height: 1.3rem;
}

/* ============================================================
   Confirmation dialog (replaces window.confirm — see confirm.js)
   ============================================================ */

.confirm-dialog article {
  max-width: 28rem;
}

.confirm-dialog h3 {
  margin-bottom: 0;
}

.confirm-dialog p {
  margin: 0 0 var(--space-2);
}

/* Footer holds the action buttons, right-aligned; drop Pico's footer chrome */
.confirm-actions {
  display: grid;
  grid-auto-flow: column;
  justify-content: end;
  column-gap: 0.75rem;
  margin: 0;
  padding: 0;
  background-color: transparent;
  border-top: none;
}

.confirm-actions button {
  width: auto;
  margin: 0;
}

/* ============================================================
   Members modal
   ============================================================ */

.member-list {
  display: grid;
  row-gap: var(--space-1);
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-3);
}

.member-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 0.5rem;
  margin: 0;
}

.member-row small {
  color: var(--brand-green);
  font-weight: var(--weight-bold);
}

/* Pending invitation (no account yet) — muted grey, like the card chips */
.member-row-pending {
  color: #7a756e;
  font-style: italic;
}

.member-row-pending small {
  color: #9a948c;
  font-weight: var(--weight-regular);
}

.member-row .icon-action {
  color: var(--brand-brown);
  display: inline-grid;
  align-items: center;
}

.member-row .icon-action:hover {
  opacity: 0.6;
}

/* Per-member controls: compact role <select> + remove button on one line */
.member-controls {
  display: flex;
  align-items: center;
  column-gap: 0.5rem;
}

.member-controls form {
  margin: 0;
}

.member-controls select {
  margin: 0;
  width: auto;
  padding: 0.15rem 2rem 0.15rem 0.6rem;
  font-size: var(--text-sm);
  --pico-form-element-spacing-vertical: 0.15rem;
}

.member-role-badge {
  color: var(--brand-green);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

/* "Choose a role" matches the bold "Add member" heading above it */
#invite_form label {
  font-weight: var(--weight-bold);
}

/* Role explanation under the invite-form select (spaced as a field hint) */
.role-hint {
  color: var(--brand-brown);
  opacity: 0.8;
}

/* ============================================================
   Motion — CSS only, small and quick
   ============================================================ */

/* Page changes: Turbo runs them as view transitions (meta tag in the layout);
   the default cross-fade, just quicker. The header keeps still. */
@view-transition {
  navigation: auto; /* full page loads too, e.g. switching language */
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--motion);
}

body > header {
  view-transition-name: site-header;
}

/* Dropdown menus unroll downwards from their button and roll back up when
   closed; the folding settings rows drop open and fold away. The closing
   halves run under .closing — details_controller.js waits for them. */
details.dropdown[open] > summary + ul {
  animation: unroll var(--motion) ease-out;
}

details.dropdown.closing > summary + ul {
  animation: roll-up var(--motion) ease-in forwards;
}

.settings-row[open] > form {
  animation: drop-in var(--motion) var(--ease-out);
}

.settings-row.closing > form {
  animation: fold-up var(--motion) ease-in forwards;
}

/* Flash: slides in, then fades and folds away just before flash_controller
   removes it (its default delay is 4s) */
.flash {
  animation:
    rise-in var(--motion) var(--ease-out),
    flash-out var(--motion) ease-in calc(4s - var(--motion)) forwards;
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
  }
}

@keyframes unroll {
  from {
    opacity: 0;
    clip-path: inset(0 0 100% 0);
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    clip-path: inset(0 0 -1rem 0); /* the end state still shows the drop shadow */
  }
}

@keyframes roll-up {
  to {
    opacity: 0;
    clip-path: inset(0 0 100% 0);
    transform: translateY(-10px);
  }
}

@keyframes drop-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

@keyframes fold-up {
  to {
    opacity: 0;
    transform: translateY(-4px);
  }
}

@keyframes flash-out {
  from { max-height: 6rem; }
  to {
    opacity: 0;
    max-height: 0;
    margin-bottom: 0;
    padding-block: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after,
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
  }

  /* Its fade-out is timed — with no delay it would vanish at once; the JS
     still removes it after 4s */
  .flash {
    animation: none !important;
  }
}

/* ============================================================
   Flash messages (top of page)
   ============================================================ */

#flash:not(:empty) {
  margin-top: var(--space-1);
}

#modal_flash:not(:empty) {
  margin-bottom: var(--space-1);
}

.flash {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 0.5rem;
  padding: var(--space-1) 1rem;
  margin-bottom: var(--space-1);
  border-radius: var(--pico-border-radius);
  color: var(--pico-color);
  font-weight: var(--weight-bold);
}

.flash-notice {
  background: var(--brand-green);
}

.flash-alert {
  background: var(--brand-yellow);
}

.flash-error {
  background: var(--brand-red);
}

/* Strip Pico button chrome from the close control */
.flash-close {
  background: transparent;
  border: none;
  width: auto;
  padding: 0;
  margin: 0;
  color: var(--pico-color);
  display: inline-grid;
  align-items: center;
  cursor: pointer;
}

.flash-close:hover {
  opacity: 0.7;
}

/* ============================================================
   Notices & errors
   ============================================================ */

.notice {
  background: var(--brand-green);
  color: var(--brand-cream);
  font-weight: var(--weight-bold);
  padding: var(--space-1) 1rem;
  border-radius: var(--pico-border-radius);
}

#error_explanation {
  background: var(--brand-yellow);
  color: var(--pico-color);
  padding: var(--space-1) 1rem;
  border-radius: var(--pico-border-radius);
  margin-bottom: var(--space-2);
}

#error_explanation h2 {
  --pico-font-size: var(--text-md);
  margin-bottom: var(--space-1);
  color: var(--pico-color);
}

#error_explanation ul {
  margin: 0 0 0 1rem;
  padding-left: 0;
}

/* Override Pico's `ul li { list-style: square }` */
#error_explanation li {
  color: var(--pico-color);
  list-style: disc;
}
