/*
 * The app shell: page headers, panels, meters, the dashboard, search and settings.
 *
 * Separate from app.css, which is the base layer (reset, type, buttons, forms).
 * This file is the dense-tool layer: hairlines instead of shadows, compact rows,
 * and no card ever floating above anything.
 */

/* ---------------------------------------------------------------- chrome */

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--header-h);
  padding: 0 var(--space-6);
  border-bottom: 1px solid var(--border);
}

.page-head h1 {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.012em;
}

/* Ways to start a note, at the head of the screen they will appear on.
 *
 * This replaces .page-actions, which was the far end of the app bar and held
 * whatever each screen felt like: three drawn buttons here, five ghost words on
 * a note, a month picker on the calendar. One slot, three unrelated jobs, and
 * so three different button styles above three consecutive screens. */
.page-make {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* On the dashboard these sit under the one-line capture box, which is the
   fourth and fastest way to start. Nothing here is primary, because the box
   already is. */
.page-make-quiet {
  margin-top: calc(var(--space-2) * -1);
}

/* This used to be a rescue: five actions in the app bar came to 399px, which is
   nine more than a 390px phone has, and Delete was the one that fell off the
   end. The five have left the bar, so there is nothing to rescue — but a row of
   ways-to-start still wraps on a narrow screen, and it should wrap tidily. */
@media (max-width: 640px) {
  .page-make {
    gap: var(--space-1);
  }

  .page-make .btn {
    padding: 0 var(--space-2);
  }
}

.page-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6) var(--space-8);
}

/* A key, shown rather than hidden in a help page: a dense tool is only fast if
   people learn its shortcuts. */
.kbd {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 5px;
  border-radius: 4px;
  background: var(--surface-3);
  box-shadow: inset 0 0 0 1px var(--border);
  font-family: var(--font-mono);
  font-size: var(--text-3xs);
  color: var(--ink-faint);
}

/* ---------------------------------------------------------------- panels */

/* A bordered region, not a card: no shadow and no elevation, because nothing
   here floats above anything else. */
.panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-panel);
  background: var(--surface-2);
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.panel-title {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--ink);
}

.panel-meta {
  font-size: var(--text-2xs);
  color: var(--ink-faint);
}

.panel-note {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--ink-muted);
  line-height: 1.5;
}

.plan-badge {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  color: var(--ink-muted);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
}

.plan-pro,
.plan-team {
  background: var(--primary-soft);
  color: var(--primary);
}

/* ---------------------------------------------------------------- meters */

.meters {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
}

.meter {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px var(--space-2);
}

.meter-label {
  font-size: var(--text-2xs);
  color: var(--ink-muted);
}

.meter-value {
  font-size: var(--text-2xs);
  color: var(--ink);
  margin: 0;
}

/* A real <progress>, not a div pretending to be one: assistive technology reads
   the value out, and the fill needs no inline width, which the CSP forbids. */
.meter-track {
  grid-column: 1 / -1;
  width: 100%;
  height: 4px;
  border: none;
  border-radius: 2px;
  background: var(--surface-3);
  overflow: hidden;
  appearance: none;
  color: var(--primary);
}

.meter-track::-webkit-progress-bar {
  background: var(--surface-3);
  border-radius: 2px;
}

.meter-track::-webkit-progress-value {
  background: currentcolor;
  border-radius: 2px;
  transition: width var(--duration-slow) var(--ease-out);
}

.meter-track::-moz-progress-bar {
  background: currentcolor;
  border-radius: 2px;
}

/* Colour only once it matters. A bar that turns amber at 40 percent teaches
   people to ignore the colour. */
.meter-warn { color: var(--warning); }
.meter-full { color: var(--danger); }

.meter-plain {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: var(--text-2xs);
  color: var(--ink-muted);
}

.meter-plain dd {
  margin: 0;
  color: var(--ink);
}

/* ---------------------------------------------------------------- narrow */

@media (max-width: 900px) {
  .dash-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Usage and activity are reference, not the reason the app was opened, so on a
     small screen they sit below the notes rather than above them. */
  .dash-side {
    order: 2;
  }
}

@media (max-width: 767px) {
  .page-head,
  .page-body {
    padding-inline-start: var(--space-4);
    padding-inline-end: var(--space-4);
  }

  .page-head {
    flex-wrap: wrap;
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
  }
}

/* ---------------------------------------------------------------- accents */

.accent-picker {
  display: flex;
  gap: var(--space-2);
}

/* Each swatch shows its own hue, not the current one, so the choice is visible
   before it is made. Same ramp as the tokens, so what you see is what you get. */
.accent-swatch {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: 50%;
  cursor: pointer;
  color: #fff;
  transition: transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}

/* Gated: a touch device fires hover on tap, and an ungated transform leaves the
   swatch stuck at 1.08 after the finger has gone. This was the only hover in
   the product that moved something, and the only gate in it. */
@media (hover: hover) and (pointer: fine) {
  @media (hover: hover) {
    .accent-swatch:hover { transform: scale(1.08); }
  }
}

.accent-swatch.is-active {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 3px var(--ink);
}

.accent-moss  { background: oklch(0.52 0.13 150); }
.accent-ink   { background: oklch(0.52 0.13 265); }
.accent-tide  { background: oklch(0.52 0.13 230); }
.accent-ember { background: oklch(0.52 0.13 45); }
.accent-rose  { background: oklch(0.52 0.13 12); }
.accent-plum  { background: oklch(0.52 0.13 320); }

.setting-note-spaced { margin-top: var(--space-3); }

/* A checkbox and its label as one target, so the words are clickable and the
   pair cannot be tabbed to separately. Full 44px tall: this one is a security
   setting, and a mis-tap on it is worse than a mis-tap on a view switch. */
.setting-switch {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  min-height: 44px;
  font-size: var(--text-sm);
  cursor: pointer;
}

.setting-switch input {
  width: 18px;
  height: 18px;
  flex: none;
  accent-color: var(--primary);
  cursor: pointer;
}

.setting-switch:has(input:disabled) {
  cursor: progress;
  opacity: 0.6;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- avatars ----
   A picture, or the initials of somebody who has not set one. Here rather than
   scoped to the sidebar, which is where this lived while the sidebar was the
   only place that showed a person: comments and the profile page show them too
   now, and a scoped rule is invisible from both.

   The initials are the normal case. Most accounts have no picture, and the ones
   that do are the exception the img handles. */

.avatar {
  display: grid;
  place-items: center;
  flex: none;
  border-radius: 50%;
  background: var(--primary);
  color: var(--on-primary);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  /* The image is square and the frame is round, so the corners have to go. */
  overflow: hidden;
}

.avatar-image {
  width: 100%;
  height: 100%;
  display: block;
  /* Cover, not contain: a portrait taken in landscape should fill the circle
     rather than sit in it with bars, and the middle of a photograph of a face
     is the face. */
  object-fit: cover;
}

/* Beside a name in a comment. */
.avatar-small {
  width: 28px;
  height: 28px;
  font-size: calc(var(--text-3xs) * 1.1);
}

/* The sidebar account row, which is where this size came from. */
.avatar-medium {
  width: 22px;
  height: 22px;
  font-size: var(--text-3xs);
}

/* The profile page, where the picture is the subject rather than a marker. */
.avatar-large {
  width: 96px;
  height: 96px;
  font-size: var(--text-3xl);
}

/* ---- the dropdown ----
   A native select is fine until it opens, and what it opens into belongs to the
   operating system: a grey list in another typeface on Windows, a full-screen
   sheet on Android, and nowhere in either of them does this app have an accent
   colour or a dark mode. The closed control matched the design and the open one,
   which is what somebody is looking at while deciding, did not. */

.select {
  /* The list is positioned against this. Nothing here may be given overflow,
     or the list is clipped by the control it belongs to. */
  position: relative;
  display: inline-flex;
  min-inline-size: 0;
}

.select-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  inline-size: 100%;
  min-block-size: var(--control-h);
  padding: 0 var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) {
  .select-trigger:hover:not(:disabled) {
    border-color: var(--border-strong);
  }
}

.select-trigger:disabled {
  opacity: 0.5;
  cursor: default;
}

.select-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The only thing on this control that moves, and it moves because the open
   state otherwise rests entirely on a list somebody may have scrolled past. */
.select-caret {
  flex: none;
  color: var(--ink-faint);
  transition: transform var(--duration-fast) var(--ease-out);
}

.select.is-open .select-caret {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .select-trigger,
  .select-caret {
    transition: none;
  }
}

/* ---------------------------------------------------------------- the notice

   Long-form prose, which nothing else in this app is. Wider than the settings
   column and narrower than the window: measured in characters because that is
   what governs whether a line can be read without the eye losing its place. */
.legal {
  max-width: 68ch;
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-12);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  line-height: 1.65;
}

/* Sits above the title rather than in a bar across the top: there is one link,
   and a whole chrome bar built to hold one link is furniture. */
.legal-home {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  text-decoration: none;
}

@media (hover: hover) {
  .legal-home:hover {
    color: var(--primary);
  }
}

.legal-head h1 {
  font-size: var(--text-2xl);
  text-wrap: balance;
}

.legal-updated {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.legal h2 {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--ink-muted);
  margin-bottom: var(--space-3);
}

.legal p + p {
  margin-top: var(--space-3);
}

/* The paragraph that answers "so what happens to it there". It is the least
   comfortable sentence on the page, which is a reason to set it apart rather
   than a reason to bury it. */
.legal-caveat {
  margin-top: var(--space-4);
  padding-left: var(--space-4);
  border-left: 1px solid var(--border);
  color: var(--ink-muted);
}

.legal-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-left: var(--space-5);
  list-style: disc;
}

[dir="rtl"] .legal-list {
  padding-left: 0;
  padding-right: var(--space-5);
}

[dir="rtl"] .legal-caveat {
  padding-left: 0;
  border-left: none;
  padding-right: var(--space-4);
  border-right: 1px solid var(--border);
}

/* A table is the one thing on this page that cannot reflow, so it scrolls
   inside its own box rather than pushing the page sideways. */
.legal-scroll {
  overflow-x: auto;
}

.legal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-xs);
  text-align: start;
}

.legal-table th,
.legal-table td {
  padding: var(--space-3) var(--space-4) var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  text-align: start;
}

[dir="rtl"] .legal-table th,
[dir="rtl"] .legal-table td {
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
}

.legal-table thead th {
  color: var(--ink-muted);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

.legal-table tbody th {
  font-weight: var(--weight-medium);
}

.legal-table td {
  color: var(--ink-muted);
}

/* A document on a note. The same row as a picture without the picture: an icon
   standing in for a thumbnail that cannot exist, then the name, then what was
   read out of it. */
.doc-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-control);
  background: var(--surface-2);
}

.doc-icon {
  display: flex;
  flex: 0 0 auto;
  padding-top: 2px;
  color: var(--ink-muted);
}

.doc-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
}

/* The one line that must not wrap into three: a filename can be sixty
   characters of hash and it is not worth three lines of a note. */
.doc-name {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ---------------------------------------------------------------- the bar

   One row across the top of every screen: what this is, the notes that are
   open, and what can be done here. It replaced two stacked bars — the tab strip
   and each page's own header — which between them spent eighty pixels and two
   horizontal rules on chrome above every screen.

   It sticks rather than the tab strip sticking, because it is now the thing
   that has to stay reachable while a long note scrolls. */
.appbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--header-h);
  padding: 0 var(--space-4);
  background: var(--chrome);
  color: var(--chrome-ink);
  border-bottom: 1px solid var(--chrome-line);

  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}

.appbar-lead {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 0 0 auto;
  min-width: 0;
}

/* The page's name, at the weight a page title had before it moved in here.
   Truncates rather than wrapping: the bar is one row and a two-line title
   would make every screen taller than the one before it. */
.appbar-title {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.012em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 40ch;
}

.appbar-count {
  font-size: var(--text-xs);
  color: var(--chrome-muted);
}

/* The way out of a note. A control with a direction on it, rather than the bare
   underlined anchor this was for the whole life of the product. */
.appbar-back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 30px;
  padding: 0 var(--space-3) 0 var(--space-2);
  border-radius: var(--radius-pill);
  color: var(--chrome-muted);
  font-size: var(--text-sm);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) {
  .appbar-back:hover {
    background: var(--chrome-raised);
    color: var(--chrome-ink);
  }
}

/* A word, at the far end. Nothing in here is a control any more, so nothing
   needs to reach the bar's bottom line — which is what the stretch, the
   flex-end and four rules about tab-shaped buttons meeting a border were all
   for. They have gone with the buttons. */
.appbar-status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: auto;
  flex: 0 0 auto;
}

/* Below the sidebar breakpoint the tabs are gone, so the bar is a title and a
   word about whether the work is safe. It no longer wraps, at any width, in
   either language: it was 80 to 90 pixels on a phone because a screen's buttons
   had to go somewhere, and it is one row of 44 now because they do not. */
@media (max-width: 899px) {
  .appbar {
    padding-inline: var(--space-4);
  }

  .appbar-title {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ---- the install offer ----

   A line, not a banner. It is asking for something, so it says so quietly and
   takes one click to be rid of; the visual weight of a callout would be the app
   raising its voice about its own convenience. */

.install-offer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);

  padding: var(--space-3) var(--space-4);
  margin-block-end: var(--space-4);

  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-panel);
}

.install-offer-words {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.install-offer-title {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--ink);
}

.install-offer-body {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.install-offer-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: none;
}
