/*
 * The feedback layer.
 *
 * Everything here is scoped under `.fb` and every class is prefixed, because this layer
 * is *not* the product: it sits over any screen, it must never inherit a screen's
 * styling, and — the point — a screenshot of the app with a note pinned to it has to be
 * unambiguous about which pixels are the app and which are the tool.
 *
 * That separation used to be a colour of its own, a coastal teal hard-coded here. It is
 * the app's `--orange` now: still not the Bordeaux the product wears, so the tool is
 * still obvious in a screenshot, but a token rather than a literal — which means the
 * layer follows the reader into morning, evening and dark instead of staying lit for one
 * of the three. Every colour below is a token or a mix of tokens, for the same reason:
 * `app.css` is where the palettes live and this file is not allowed a fourth.
 *
 * Sizes, radii and spacing are literals because that is how the editorial client is
 * written — it has no spacing scale to borrow.
 */

/* Defined on :root rather than on .fb, because the pins live in a second root of their
   own — outside .fb — and would otherwise resolve none of these. */
:root {
  --fb-accent: var(--orange);
  --fb-accent-soft: color-mix(in srgb, var(--orange) 12%, transparent);
  /* Every dim in here is mixed from `--slab`, the one token that is a dark plum in all
     three palettes. `--ink` inverts — it is nearly white in the dark appearance — so a
     scrim mixed from it lit the page up instead of standing the sheet out from it. */
  --fb-shadow: 0 10px 30px -12px color-mix(in srgb, var(--slab) 55%, transparent);
  --fb-shadow-card: 0 2px 10px color-mix(in srgb, var(--slab) 18%, transparent);
  --fb-scrim: color-mix(in srgb, var(--slab) 55%, transparent);
  /* Where the dock sits above the bottom edge. The mobile tab bar is 61px of chrome plus
     the safe area, and it only exists below 700px. */
  --fb-dock-bottom: 24px;
  --fb-radius: 6px;
  --fb-pill: 50px;
}

@media (max-width: 700px) {
  :root {
    --fb-dock-bottom: calc(73px + env(safe-area-inset-bottom, 0px));
  }
}

.fb {
  position: fixed;
  inset: 0;
  z-index: 60;
  /* Idle, the layer is invisible to the pointer — the app underneath is fully usable.
     Each piece that needs taps turns them back on for itself. */
  pointer-events: none;
  font-family: var(--sans);
  color: var(--ink);
}

.fb > * { pointer-events: auto; }

/* ---- The dock ------------------------------------------------------------ */

/*
 * Pinned to the right edge of the *page column* rather than the viewport, so on a wide
 * window it sits against the layout instead of floating alone in the margin. The column
 * is 1440px with a 64px gutter; below that the dock keeps 20px of air.
 */
/*
 * Above the picker's catcher, which is the whole point of the stack below: the catcher
 * is a transparent full-screen sheet with `z-index: 1`, and the dock had no z-index at
 * all — so in picking mode the sheet painted over the Cancel button and swallowed the
 * tap meant to leave the mode.
 */
.fb-dock {
  position: fixed;
  z-index: 4;
  right: max(20px, calc(50vw - 656px));
  bottom: var(--fb-dock-bottom);
  display: flex;
  align-items: center;
  gap: 8px;
}

.fb-fab {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  padding-inline: 16px;
  border-radius: var(--fb-pill);
  background: var(--white);
  border: 1px solid var(--line);
  box-shadow: var(--fb-shadow);
  color: var(--fb-accent);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: transform 0.2s var(--ease), background 0.2s var(--ease);
}
.fb-fab:active { transform: scale(.96); }
.fb-fab[data-active='true'] {
  background: var(--fb-accent);
  border-color: var(--fb-accent);
  color: var(--button-text);
}

/* The list button: square-ish, holding either the open count or a list glyph. */
.fb-fab--icon {
  width: 44px;
  padding-inline: 0;
  justify-content: center;
}

.fb-fab__count {
  display: grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding-inline: 5px;
  border-radius: var(--fb-pill);
  background: var(--fb-accent-soft);
  color: var(--fb-accent);
  font-size: var(--t-fine);
  letter-spacing: 0;
}
.fb-fab[data-active='true'] .fb-fab__count {
  background: color-mix(in srgb, var(--button-text) 22%, transparent);
  color: var(--button-text);
}

/*
 * Notes about this screen with nowhere to sit — their element was renamed, removed, or
 * the wine they pointed at is no longer in the list. Sits above the dock rather than
 * beside it, so it reads as a message rather than as another control.
 */
.fb-orphans {
  position: fixed;
  z-index: 4;
  right: max(20px, calc(50vw - 656px));
  bottom: calc(var(--fb-dock-bottom) + 56px);
  max-width: calc(100vw - 40px);
  padding: 6px 12px;
  border-radius: var(--fb-pill);
  background: var(--white);
  border: 1px dashed var(--fb-accent);
  color: var(--fb-accent);
  font-size: var(--t-fine);
  box-shadow: var(--fb-shadow-card);
}

/* ---- Picking ------------------------------------------------------------- */

/*
 * A transparent sheet over the whole app that swallows the tap which chooses an element.
 * Without it, picking the "Sign out" button would sign you out.
 */
.fb-catcher {
  position: fixed;
  inset: 0;
  cursor: crosshair;
  background: color-mix(in srgb, var(--slab) 6%, transparent);
  /* Below the composer and the toggle, above everything the app draws. */
  z-index: 1;
}

.fb-highlight {
  position: fixed;
  z-index: 2;
  pointer-events: none;
  border: 2px solid var(--fb-accent);
  border-radius: var(--fb-radius);
  background: var(--fb-accent-soft);
  box-shadow: 0 0 0 9999px color-mix(in srgb, var(--slab) 20%, transparent);
  transition: all 90ms linear;
}

.fb-highlight__tag {
  position: absolute;
  left: -2px;
  top: -22px;
  max-width: 260px;
  padding: 2px 8px;
  border-radius: 5px;
  background: var(--fb-accent);
  color: var(--button-text);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.06em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Flip below the element when there is no room above it. */
.fb-highlight[data-flip='true'] .fb-highlight__tag { top: auto; bottom: -22px; }

/*
 * Centred with auto margins rather than `left: 50%` + a translate.
 *
 * A shrink-to-fit box positioned at `left: 50%` is laid out in the half-width left over
 * to the right of that edge — 195px on a 390px screen — so it wraps to two lines and is
 * only then translated back into place. The pill that says "tap something" was tall
 * enough to sit on top of the screen title. The sheets below can keep the translate:
 * their width is explicit, so nothing is being shrunk to fit.
 */
.fb-hint {
  position: fixed;
  inset-inline: 0;
  margin-inline: auto;
  width: fit-content;
  max-width: calc(100% - 40px);
  top: calc(env(safe-area-inset-top, 0px) + 16px);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px 8px 16px;
  border-radius: var(--fb-pill);
  /* The app's own toast pairing, inverted against the page: ink ground, paper ink. It
     inverts with the palette, so this is a dark pill in the morning and a light one in
     the dark — in both, the one thing on screen that is not the page. */
  background: var(--ink);
  color: var(--paper);
  font-size: var(--t-fine);
  box-shadow: var(--fb-shadow);
  /* It explains the mode; it must not eat the tap that uses it. */
  pointer-events: none;
  animation: fbDrop 0.2s var(--ease) both;
}
.fb-hint__esc {
  padding: 2px 8px;
  border-radius: var(--fb-pill);
  background: color-mix(in srgb, var(--paper) 18%, transparent);
  color: var(--paper);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.06em;
}

/* ---- Pins ---------------------------------------------------------------- */

/*
 * Positioned in *document* coordinates inside an absolutely-placed container, so pins
 * scroll with the page they are pinned to without a scroll handler.
 */
.fb-pins {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0;
  /* One below the chrome: a pin must never cover a sheet. */
  z-index: 59;
  pointer-events: none;
}

.fb-pin {
  position: absolute;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--fb-accent);
  color: var(--button-text);
  border: 2px solid var(--paper);
  box-shadow: var(--fb-shadow-card);
  font-family: var(--mono);
  font-size: var(--t-fine);
  line-height: 1;
  pointer-events: auto;
  animation: fbPop 0.2s var(--ease) both;
}
.fb-pin:active { transform: scale(.92); }
.fb-pin[data-kind='bug'] { background: var(--accent); color: var(--button-text); }
.fb-pin[data-kind='idea'] { background: var(--muted); color: var(--paper); }
/* A pin whose element could not be found with any confidence sits where the walk ended
   and says so, rather than pretending to point at something. */
.fb-pin[data-confidence='rough'] { opacity: .6; border-style: dashed; }

/*
 * A pin on a `position: fixed` element — the mobile tab bar, or anything inside an open
 * dialog, which scrolls its own content in the top layer — rides in the chrome instead
 * of the page container, so it stays put when the page scrolls underneath it.
 */
.fb-pin--fixed,
.fb-pin-halo--fixed { position: fixed; z-index: 3; }

.fb-pin-halo {
  position: absolute;
  border: 1.5px dashed var(--fb-accent);
  border-radius: 8px;
  background: var(--fb-accent-soft);
  pointer-events: none;
}

/* ---- Sheets and panels --------------------------------------------------- */

.fb-scrim {
  position: fixed;
  inset: 0;
  z-index: 5;
  background: var(--fb-scrim);
  animation: fbFade 0.2s var(--ease) both;
}

.fb-sheet {
  position: fixed;
  z-index: 6;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 100%;
  max-width: 430px;
  max-height: 88dvh;
  overflow-y: auto;
  padding: 24px 20px calc(32px + env(safe-area-inset-bottom, 0px));
  background: var(--paper);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -18px 46px -18px color-mix(in srgb, var(--slab) 55%, transparent);
  animation: fbRise 0.2s var(--ease) both;
}

.fb-panel {
  position: fixed;
  z-index: 6;
  left: 50%;
  top: 0;
  bottom: 0;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 430px;
  background: var(--paper);
  box-shadow: var(--fb-shadow);
  animation: fbSlide 0.2s var(--ease) both;
}

.fb-panel__head {
  flex: none;
  padding: calc(env(safe-area-inset-top, 0px) + 24px) 20px 12px;
  border-bottom: 1px solid var(--line);
}
.fb-panel__body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px calc(40px + env(safe-area-inset-bottom, 0px));
}

.fb-title {
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.6px;
}
.fb-eyebrow {
  font-family: var(--mono);
  font-size: var(--t-fine);
  font-weight: 500;
  letter-spacing: 0.178em;
  text-transform: uppercase;
  color: var(--fb-accent);
}
.fb-muted { color: var(--muted); font-size: 12px; }
.fb-caption { color: var(--muted); font-size: var(--t-fine); }

.fb-row { display: flex; align-items: center; gap: 12px; }
.fb-row--between { justify-content: space-between; }
.fb-stack { display: flex; flex-direction: column; gap: 12px; }
.fb-grow { flex: 1; min-width: 0; }

/* The hover disc stays 32px, which is what the sheet's top row is drawn for; the box a
   thumb has to find is 44px, which is what a close button owes anyone holding a phone. */
.fb-close {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: var(--fb-pill);
  color: var(--muted);
}
.fb-close:before {
  content: "";
  position: absolute;
  inset: -6px;
}
.fb-close:hover { background: var(--surface); }
.fb-close--danger { color: var(--accent); }

/* ---- Kind picker --------------------------------------------------------- */

.fb-kinds { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }

.fb-kind {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 12px 4px;
  border-radius: var(--fb-radius);
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--muted);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.063em;
  text-transform: uppercase;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.fb-kind[aria-pressed='true'] {
  background: var(--fb-accent);
  border-color: var(--fb-accent);
  color: var(--button-text);
}

/* ---- Fields -------------------------------------------------------------- */

.fb-field { display: block; }
.fb-field__label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.178em;
  text-transform: uppercase;
  color: var(--muted);
}

.fb-input,
.fb-textarea {
  width: 100%;
  padding: 12px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--fb-radius);
  color: var(--ink);
  font-size: 16px; /* below 16px iOS zooms the page on focus */
  line-height: 1.45;
}
/* The accent border is the design; the ring is the accessibility. Until now the second
   line of this rule was `outline: none`, and because it is more specific than app.css's
   `input:focus-visible` it was the one place in the whole product where the global focus
   ring did not draw. The offset is tighter than the app's 5px because these fields are
   the full width of a sheet with 16px of padding around it. */
.fb-input:focus,
.fb-textarea:focus { border-color: var(--fb-accent); }
.fb-input:focus-visible,
.fb-textarea:focus-visible { outline: 2px solid var(--fb-accent); outline-offset: 2px; }
.fb-textarea { min-height: 84px; resize: vertical; }

/* The line being corrected, shown as it currently reads. Struck through, because the
   whole point of the field below it is that this is the version being replaced. */
.fb-was {
  padding: 12px;
  border-radius: var(--fb-radius);
  /* The recessed wash, and the page ink dimmed on it rather than a lighter grey — which
     keeps the quiet-ink hierarchy and invents no new colour. */
  background: var(--surface);
  color: color-mix(in srgb, var(--ink) 76%, transparent);
  font-size: 12px;
  text-decoration: line-through;
  text-decoration-color: var(--muted);
}

.fb-target {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--fb-radius);
  background: var(--fb-accent-soft);
  color: var(--fb-accent);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.057em;
}
.fb-target__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Buttons ------------------------------------------------------------- */

.fb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 13px 24px;
  border-radius: var(--fb-pill);
  font-size: 13px;
  font-weight: 600;
  /* A two-word label wrapping mid-button is what "Won't fix" did in a row of four. */
  white-space: nowrap;
  transition: transform 0.2s var(--ease), opacity 0.2s var(--ease);
}
.fb-btn:active { transform: scale(.98); }
.fb-btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.fb-btn--primary {
  background: var(--fb-accent);
  color: var(--button-text);
  box-shadow: var(--fb-shadow);
}
.fb-btn--ghost { background: var(--white); color: var(--ink); border: 1px solid var(--line); }
.fb-btn--quiet { background: none; color: var(--muted); font-weight: 500; width: auto; padding: 8px; }
.fb-btn--sm {
  width: auto;
  padding: 8px 12px;
  font-size: var(--t-fine);
  font-weight: 500;
}
.fb-btn--danger { color: var(--accent); }

/* ---- Note cards ---------------------------------------------------------- */

.fb-card {
  padding: 16px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 7px;
  box-shadow: var(--fb-shadow-card);
}
.fb-card + .fb-card { margin-top: 12px; }
.fb-card[data-status='resolved'] { opacity: .62; }

.fb-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  padding: 3px 8px;
  border-radius: var(--fb-pill);
  background: var(--fb-accent-soft);
  color: var(--fb-accent);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.168em;
  text-transform: uppercase;
}
.fb-tag--bug { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.fb-tag--idea { background: color-mix(in srgb, var(--muted) 14%, transparent); color: var(--muted); }
.fb-tag--quiet { background: var(--surface); color: var(--muted); }
.fb-tag--good { background: var(--surface); color: var(--ink); }

.fb-note { font-size: 12px; line-height: 1.6; white-space: pre-wrap; }

/* The row of things you can do to a note. Wraps rather than squeezing its labels. */
.fb-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.fb-diff { font-size: 12px; line-height: 1.5; }
.fb-diff__was { color: var(--muted); text-decoration: line-through; }
.fb-diff__now { color: var(--ink); }

.fb-filters { display: flex; gap: 8px; margin-top: 12px; }
.fb-filter {
  padding: 5px 12px;
  border-radius: var(--fb-pill);
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--muted);
  font-family: var(--mono);
  font-size: var(--t-fine);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.fb-filter[aria-pressed='true'] {
  background: var(--fb-accent);
  border-color: var(--fb-accent);
  color: var(--button-text);
}

.fb-empty {
  padding: 40px 24px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
}

.fb-error {
  margin-top: 8px;
  color: var(--accent);
  font-size: var(--t-fine);
}

/* ---- Making room for the layer ------------------------------------------- */

/*
 * The app's toast sits bottom-centre — on a phone, exactly where the dock sits — so the
 * dock clipped the end of "Saved to your wines" every time. Rather than moving product
 * chrome for good, the layer steps it up only while the layer is mounted: `FEEDBACK=0`,
 * or a deployment that never loads this file, gets the original placement back with
 * nothing to undo.
 *
 * The stack from the bottom: tab bar, dock, orphan chip, the app's toast, ours.
 */
body.fb-on .toast {
  bottom: calc(var(--fb-dock-bottom) + 104px);
}

/* ---- Toast --------------------------------------------------------------- */

/*
 * The layer's own. The app's toast sits under this layer and would be covered by a
 * sheet, which is precisely the moment this layer has something to say.
 */
.fb-toast {
  position: fixed;
  z-index: 7;
  inset-inline: 0;
  margin-inline: auto;
  width: fit-content;
  /* Top of the stack: above the dock, the orphan chip and the app's own toast. */
  bottom: calc(var(--fb-dock-bottom) + 152px);
  max-width: calc(100% - 40px);
  padding: 12px 24px;
  border-radius: var(--fb-pill);
  background: var(--ink);
  color: var(--paper);
  font-size: 12px;
  text-align: center;
  box-shadow: var(--fb-shadow);
  /* Nothing to tap, and it sits over the app for two and a half seconds. */
  pointer-events: none;
  animation: fbLift 0.2s var(--ease) both;
}

/* ---- Motion -------------------------------------------------------------- */

@keyframes fbRise {
  from { opacity: 0; transform: translate(-50%, 18px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes fbSlide {
  from { opacity: 0; transform: translate(-50%, 0) scale(.99); }
  to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
@keyframes fbFade { from { opacity: 0; } to { opacity: 1; } }
/* The auto-centred pieces animate on the Y axis alone: their horizontal placement is
   done with margins, so a translate here would knock them off centre. */
@keyframes fbDrop {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fbLift {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fbPop {
  from { opacity: 0; transform: scale(.6); }
  to   { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .fb *, .fb { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
