/* CRM admin surface. Same chassis as the client portal (cream, linen, oxblood,
   hard borders, warm offset shadows) at operator density.

   Two deliberate departures from the client-facing stylesheet, both from the
   product register:

   1. The ochre #c08847 is NOT the body ground here. On a marketing page it carries
      the brand; behind eleven columns of dense data it fights every card for
      attention. It survives as structural accent: the rail's edge, the active-nav
      marker, column heads. The reading surfaces are cream and linen.

   2. Type is fixed-rem, not clamp(). Fluid type is for pages you scroll through
      once. A heading that shrinks because it happens to sit in a narrow panel is
      worse, not better, in a tool you work in all day.

   Depth is five stacked planes lit from the content outward, two-layer warm
   shadows, recessed column troughs, paper grain at 5%, and a real hover lift. The
   first pass used flat fills and single hard offsets and read flat and glaring,
   which it was: an offset with no falloff is a shape, not a shadow, and cream
   across most of the screen leaves nothing for cream to pop against. */

:root {
  /* FIVE PLANES, darkest to lightest. The order is the whole design: light falls
     from the content outward, so the surface you read is the brightest thing and
     the frame recedes. The first version made the canvas cream, which put the
     brightest value across 70% of the screen. Nothing could pop against it and it
     glared. Cream is now reserved for cards and panels, roughly a fifth of the
     surface, which is what makes it read as lit rather than blank. */
  --rail-bg: #4a3520;      /* 1. chrome. darkest, recedes, holds the brand */
  --rail-bg-2: #402d1b;
  /* The step between ground and well has to be big enough to read as a trough. At
     8% apart the columns dissolved into the canvas and looked like vague blocks. */
  --well: #bda574;         /* 3. recessed column trough */
  --well-2: #b09765;
  --ground: #dfcfac;       /* 2. canvas the columns sit on */
  --panel-bg: #efe6d3;     /* 4. topbar and column heads */
  --cream: #fffbed;        /* 5. cards and panels. the only near-white left */

  --bg: #c08847;
  --border-warm: #8a5e2c;
  --border-deep: #6d4a24;
  --linen: #efe6d3;
  --linen-soft: #e8dbc3;
  --linen-deep: #ddcdae;
  --ink: #1f1812;
  --ink-soft: #3a2a1a;
  --ink-muted: #5a4631;
  --rail-ink: #f4ead4;
  --rail-ink-muted: #bfa87f;
  --accent: #8a3324;
  --accent-bright: #a13d2a;
  --accent-warm: #c2542f;
  --forest: #3d4f3a;
  --ochre: #b07a3c;

  --font-display: 'Archivo Black', system-ui, sans-serif;
  --font-body: 'Inter', system-ui, sans-serif;
  --font-label: 'Oswald', system-ui, sans-serif;

  /* Warm-tinted, never gray: gray shadows on a warm ground read as dirt. Each is
     TWO layers, a hard offset for the brutalist edge plus a soft ambient underneath.
     The hard offset alone is what made the first pass look flat: an offset with no
     falloff is a shape, not a shadow. */
  --sh-1: 1px 2px 0 rgba(43, 30, 16, 0.2), 0 2px 5px rgba(43, 30, 16, 0.14);
  --sh-2: 2px 3px 0 rgba(43, 30, 16, 0.26), 0 4px 10px rgba(43, 30, 16, 0.18);
  --sh-3: 4px 6px 0 rgba(43, 30, 16, 0.3), 0 9px 22px rgba(43, 30, 16, 0.22);
  --sh-lift: 5px 9px 0 rgba(43, 30, 16, 0.32), 0 14px 30px rgba(43, 30, 16, 0.26);
  /* Recession. Columns are troughs pressed into the canvas, so cards have somewhere
     to sit rather than floating on a flat field. */
  --sh-well: inset 0 2px 6px rgba(43, 30, 16, 0.26), inset 0 -1px 0 rgba(255, 251, 237, 0.16);
  /* The lit top edge that makes a surface read as physical. */
  --edge-top: inset 0 1px 0 rgba(255, 251, 237, 0.55);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 130ms;
  --t-base: 190ms;

  --rail-w: 224px;
  --rail-w-collapsed: 60px;

  /* Semantic scale, in stacking order. Nothing in this file uses a bare number.
     The scrim sits BETWEEN the topbar and the rail on purpose: it has to cover the
     content it is dimming while staying underneath the panel it belongs to. Putting
     it above the rail (the first thing I did) dims the sidebar and swallows every
     tap on it, so the menu opens looking correct and does nothing. */
  --z-topbar: 30;
  --z-scrim: 35;
  --z-rail: 40;
  --z-drag: 60;
  --z-toast: 80;
  /* Above the toast: the grain is a property of the screen, so nothing sits outside
     it. It never intercepts a pointer, so being on top costs nothing. */
  --z-grain: 90;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: var(--rail-bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

/* Paper grain over the whole surface at 5%, multiply. Fixed rather than scrolling,
   so it behaves like the texture of the screen instead of a pattern glued to the
   content. pointer-events:none keeps it out of every hit test, including the drag's
   elementFromPoint lookup, which it would otherwise intercept on every move. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
svg { stroke: currentColor; fill: none; }
[hidden] { display: none !important; }

:focus-visible {
  outline: 2.5px solid var(--accent);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Money and counts must align down the column. This is why there is no mono
   family loaded: Inter already has the figures. */
.num { font-variant-numeric: tabular-nums; }

/* ---------- gate ---------- */
.gate { min-height: 100svh; display: grid; place-items: center; padding: 24px; }
.gate-card {
  background: var(--cream);
  border: 1.5px solid var(--ink);
  box-shadow: var(--sh-3);
  padding: 32px 28px;
  max-width: 27rem;
  width: 100%;
}
.gate-mark {
  font-family: var(--font-display);
  font-size: 1.5rem;
  letter-spacing: -0.03em;
  text-transform: lowercase;
}
.gate-mark span { color: var(--accent); }
.gate-title {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-top: 18px;
}
.gate-body { color: var(--ink-soft); margin-top: 8px; max-width: 62ch; }
.gate .btn { margin-top: 20px; }

/* ---------- buttons ---------- */
.btn, .act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 44px;
  padding: 10px 18px;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border: 1.5px solid var(--ink);
  border-radius: 2px;
  background: var(--cream);
  color: var(--ink);
  box-shadow: var(--sh-1);
  text-decoration: none;
  transition: background var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out),
              box-shadow var(--t-fast) var(--ease-out),
              transform var(--t-fast) var(--ease-out);
}
.btn:hover, .act:hover { background: var(--ink); color: var(--cream); box-shadow: var(--sh-2); transform: translate(-1px, -1px); }
.btn:active, .act:active { transform: translate(1px, 1px); box-shadow: none; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--cream); }
.btn-primary:hover { background: var(--ink); border-color: var(--ink); }
.btn:disabled, .act:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }
/* 44px, not the 36px this started at. A `pointer: coarse` override was the tempting
   answer (compact for a mouse, thumb-sized for a finger) but headless emulation does
   not report a coarse pointer, so it could never be verified, and an untestable fix
   is not a fix. The density lost is a few pixels in a toolbar. */
.act { min-height: 44px; padding: 9px 14px; font-size: 0.7rem; }

/* ---------- shell ---------- */
.app { min-height: 100svh; display: flex; }

/* Mobile-first: the rail is off-canvas and slides in. Desktop pins it. */
.rail {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--rail-w);
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  /* The dark plane. It stops competing with the data for attention, gives the eye
     somewhere to rest, and is what most operator tools do for the same reason. The
     gradient is barely there (about 4% across the width) and reads as the frame
     catching less light the further it gets from the content. */
  background-color: var(--rail-bg);
  background-image: linear-gradient(180deg, var(--rail-bg) 0%, var(--rail-bg-2) 100%);
  border-right: 1.5px solid #241809;
  color: var(--rail-ink);
  box-shadow: inset -8px 0 14px -10px rgba(0, 0, 0, 0.55);
  transform: translateX(-100%);
  transition: transform var(--t-base) var(--ease-out);
}
.rail.is-open { transform: none; box-shadow: var(--sh-3); }

.rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 16px 14px;
  border-bottom: 1px solid rgba(255, 251, 237, 0.14);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
  min-height: 60px;
}
.rail-mark {
  font-family: var(--font-display);
  font-size: 1.1rem;
  letter-spacing: -0.03em;
  text-transform: lowercase;
  color: var(--rail-ink);
  text-decoration: none;
  white-space: nowrap;
}
/* The period is the brand's one loud mark, and on the dark plane it needs to lift
   off rather than sink: oxblood on near-black is muddy, so it warms up. */
.rail-mark span { color: var(--accent-warm); }
.rail-toggle {
  display: none;
  width: 30px; height: 30px;
  flex: 0 0 30px;
  align-items: center; justify-content: center;
  border: 1.5px solid rgba(255, 251, 237, 0.3);
  border-radius: 2px;
  color: var(--rail-ink);
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
.rail-toggle:hover { background: rgba(255, 251, 237, 0.12); border-color: rgba(255, 251, 237, 0.55); }
.rail-toggle-glyph { width: 9px; height: 9px; border-left: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); margin-left: -2px; transition: transform var(--t-base) var(--ease-out); }

.rail-nav { padding: 10px 8px; display: flex; flex-direction: column; gap: 2px; flex: 1; overflow-y: auto; }

.rail-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  min-height: 44px;
  padding: 9px 11px;
  border-radius: 2px;
  color: var(--rail-ink-muted);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.86rem;
  letter-spacing: 0.03em;
  text-align: left;
  text-decoration: none;
  transition: background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.rail-item:hover { background: rgba(255, 251, 237, 0.09); color: var(--rail-ink); }
/* The active item is the one place the rail lets light through, which is why it
   reads as "you are here" without needing a label. */
.rail-item.is-active {
  background-color: var(--cream);
  background-image: linear-gradient(180deg, var(--cream) 0%, var(--panel-bg) 100%);
  color: var(--ink);
  font-weight: 600;
  box-shadow: var(--sh-2), var(--edge-top);
}
/* The active marker is a left bar, which is the one place a vertical accent is
   structural rather than the banned decorative side-stripe: it marks position in a
   list of peers, and it is on the nav item, not a card. */
.rail-item.is-active::before {
  content: '';
  position: absolute;
  left: -8px; top: 50%;
  width: 4px; height: 22px;
  background: var(--accent-warm);
  box-shadow: 0 0 10px rgba(194, 84, 47, 0.6);
  transform: translateY(-50%);
}
.rail-ico { flex: 0 0 16px; display: grid; place-items: center; color: currentColor; }
.rail-ico svg { stroke-width: 1.7; }
.rail-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail-count {
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  font-weight: 600;
  min-width: 20px;
  padding: 1px 6px;
  text-align: center;
  border: 1.2px solid rgba(255, 251, 237, 0.22);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.28);
  color: var(--rail-ink);
}
.rail-item.is-active .rail-count { background: var(--linen-deep); border-color: var(--border-warm); color: var(--ink); }
.rail-count:empty { display: none; }
.rail-count.is-hot { background: var(--accent); border-color: var(--accent); color: var(--cream); }

.rail-foot { border-top: 1px solid rgba(255, 251, 237, 0.14); box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); padding: 8px; }
.rail-item.is-link { font-size: 0.8rem; }
.rail-who { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 11px 4px; }
.rail-who-name { font-size: 0.74rem; color: var(--rail-ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-who-out {
  /* Sized to the 44px floor rather than to the text. It ends a session, so it wants
     a deliberate press, and at 38x39 it was the one control on the surface you
     could miss with a thumb. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 0 10px;
  font-family: var(--font-label);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rail-ink-muted);
  transition: color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.rail-who-out:hover { color: var(--rail-ink); background: rgba(255, 251, 237, 0.1); }
.rail-who-out:active { background: rgba(0, 0, 0, 0.25); }

.scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  background: rgba(31, 24, 18, 0.44);
  border: none;
  cursor: pointer;
  animation: fade var(--t-base) var(--ease-out);
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; background: var(--ground); }

.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  min-height: 60px;
  background-color: var(--cream);
  background-image: linear-gradient(180deg, var(--cream) 0%, var(--panel-bg) 100%);
  border-bottom: 1.5px solid var(--border-deep);
  /* Sits above the canvas and casts onto it, so scrolled content passes underneath
     rather than butting into a line. */
  box-shadow: 0 2px 0 rgba(43, 30, 16, 0.22), 0 8px 18px -6px rgba(43, 30, 16, 0.3), var(--edge-top);
}
.topbar-burger {
  display: grid;
  gap: 4px;
  width: 44px; height: 44px;
  flex: 0 0 44px;
  place-content: center;
  border: 1.5px solid var(--ink);
  border-radius: 2px;
  padding: 0 9px;
  transition: background var(--t-fast) var(--ease-out);
}
.topbar-burger:hover { background: var(--linen); }
.topbar-burger span { display: block; height: 2px; background: var(--ink); }
.topbar-titles { flex: 1; min-width: 0; }
.topbar-title {
  font-family: var(--font-display);
  font-size: 1.28rem;
  letter-spacing: -0.025em;
  line-height: 1.15;
  text-wrap: balance;
}
.topbar-sub { font-size: 0.8rem; color: var(--ink-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

.canvas { flex: 1; padding: 18px 16px 64px; min-width: 0; }

/* ---------- shared bits ---------- */
.eyebrow {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.panel {
  background-color: var(--cream);
  background-image: linear-gradient(178deg, var(--cream) 0%, var(--panel-bg) 100%);
  border: 1.5px solid var(--ink);
  box-shadow: var(--sh-3), var(--edge-top);
  padding: 16px;
}
.panel + .panel { margin-top: 16px; }
.panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; padding-bottom: 10px; border-bottom: 1.5px solid var(--ink); }
.panel-title { font-family: var(--font-label); font-weight: 600; font-size: 0.9rem; letter-spacing: 0.06em; text-transform: uppercase; }
.panel-meta { font-size: 0.76rem; color: var(--ink-muted); }

.empty { padding: 26px 18px; text-align: left; border: 1.5px dashed var(--border-deep); background: var(--well); box-shadow: var(--sh-well); }
.empty-title { font-family: var(--font-label); font-weight: 600; font-size: 0.86rem; letter-spacing: 0.08em; text-transform: uppercase; }
.empty-body { font-size: 0.86rem; color: var(--ink-soft); margin-top: 6px; max-width: 62ch; }

/* Skeletons, not spinners: the shape of what is coming beats a spinner over
   nothing, and it stops the layout jumping when data lands. */
.skel { background: var(--linen-soft); border: 1.5px solid var(--linen-deep); position: relative; overflow: hidden; }
.skel::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 251, 237, 0.75), transparent);
  animation: sweep 1.15s ease-in-out infinite;
}
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.skel-row { height: 44px; margin-bottom: 8px; }
.skel-card { height: 96px; margin-bottom: 10px; }

.chip {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 3px 7px;
  border: 1.2px solid var(--border-warm);
  border-radius: 2px;
  background: var(--linen-soft);
  color: var(--ink-soft);
  white-space: nowrap;
}
.chip-paid { background: var(--forest); border-color: var(--forest); color: var(--cream); }
.chip-partial { background: var(--ochre); border-color: var(--border-warm); color: var(--cream); }
.chip-invoiced { background: var(--linen-deep); border-color: var(--ink); color: var(--ink); }
.chip-none { background: var(--linen-soft); }
.chip-hot { background: var(--accent); border-color: var(--accent); color: var(--cream); }

/* ---------- kanban ---------- */
.band { margin-bottom: 22px; }
.band-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 9px; }
.band-name { font-family: var(--font-label); font-weight: 600; font-size: 0.82rem; letter-spacing: 0.14em; text-transform: uppercase; }
.band-meta { font-size: 0.74rem; color: var(--ink-muted); }

/* Horizontal scroll is the honest answer for 7 stages on a phone. The columns keep
   their width and you swipe; squeezing them to fit makes every card unreadable. */
/* align-items: flex-start, not the flex default. Stretched columns all inherit the
   height of the fullest one, so a Handled board with four cards sitting in "Client"
   gave every empty column 600px of dead beige. Each column now takes its own
   height. */
.board { display: flex; align-items: flex-start; gap: 12px; overflow-x: auto; padding-bottom: 10px; scroll-snap-type: x proximity; }
.col {
  flex: 0 0 268px;
  display: flex;
  flex-direction: column;
  background: var(--well);
  border: 1.5px solid var(--border-deep);
  box-shadow: var(--sh-well);
  scroll-snap-align: start;
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
.col.is-won { background: #b6bd96; }
.col.is-lost { background: var(--well-2); opacity: 0.66; }
/* Won and lost scroll sooner than the open stages. They only ever grow (nothing ages
   off the board yet), and since a band is as tall as its tallest column, the Client
   column was setting the height of the whole Handled board and leaving a 300px void
   beside the stages you actually work. Reference material, not work. */
.col.is-won .col-body, .col.is-lost .col-body { max-height: 26svh; }
/* Drop target. Reads as "this column will take it" without moving anything, so the
   cursor does not chase a shifting layout. */
.col.is-over { background: var(--panel-bg); border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent), 0 0 22px -4px rgba(138, 51, 36, 0.55); }
.col-head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 11px;
  background-color: var(--panel-bg);
  background-image: linear-gradient(180deg, var(--panel-bg) 0%, var(--linen-deep) 100%);
  border-bottom: 1.5px solid var(--border-deep);
  box-shadow: 0 2px 5px rgba(43, 30, 16, 0.22), var(--edge-top);
}
.col.is-won .col-head { background-color: #dbe2cb; background-image: linear-gradient(180deg, #dbe2cb 0%, #c6cfb2 100%); }
.col-name { font-family: var(--font-label); font-weight: 600; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; }
.col-sum { font-size: 0.7rem; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
/* Capped and scrolled internally so a column that accumulates deals (the won column
   grows forever, by design) cannot push the board off the bottom of the screen. The
   sticky column head stays put while the cards scroll under it. */
.col-body { padding: 9px; display: flex; flex-direction: column; gap: 9px; min-height: 78px; max-height: 42svh; overflow-y: auto; }
.col-empty { font-size: 0.76rem; color: var(--ink-soft); padding: 8px 4px; }

.deal {
  position: relative;
  text-align: left;
  width: 100%;
  padding: 11px 12px;
  /* Barely a gradient (cream to panel, about 4% of value) but it is what stops the
     card reading as a flat rectangle. Paired with the lit top edge it looks like a
     card catching light from above. */
  background-color: var(--cream);
  background-image: linear-gradient(170deg, var(--cream) 0%, var(--panel-bg) 100%);
  border: 1.5px solid var(--ink);
  box-shadow: var(--sh-2), var(--edge-top);
  cursor: grab;
  touch-action: none;
  transition: box-shadow var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out);
}
.deal:hover { box-shadow: var(--sh-lift), var(--edge-top); transform: translate(-2px, -3px); }
.deal:active { cursor: grabbing; }
.deal.is-dragging { opacity: 0.36; box-shadow: none; transform: none; cursor: grabbing; }
/* The floating copy under the finger. Fixed-position so it escapes the column's
   overflow, which would otherwise clip it the moment you drag sideways. */
.deal.is-ghost {
  position: fixed;
  z-index: var(--z-drag);
  width: 246px;
  pointer-events: none;
  box-shadow: var(--sh-lift);
  transform: rotate(-1.4deg);
  opacity: 0.97;
}
.deal.is-saving { border-style: dashed; }
.deal-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.deal-name { font-weight: 700; font-size: 0.94rem; line-height: 1.25; }
.deal-contact { font-size: 0.78rem; color: var(--ink-muted); margin-top: 1px; }
.deal-money { font-family: var(--font-label); font-weight: 600; font-size: 1rem; margin-top: 8px; font-variant-numeric: tabular-nums; }
.deal-money .per { font-size: 0.68rem; font-weight: 400; color: var(--ink-muted); }
.deal-money.is-unset { font-size: 0.78rem; font-weight: 400; color: var(--ink-muted); font-family: var(--font-body); }
.deal-next { font-size: 0.8rem; color: var(--ink-soft); line-height: 1.4; margin-top: 8px; padding-top: 7px; border-top: 1px dashed rgba(31, 24, 18, 0.2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.deal-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.deal-quiet { font-size: 0.7rem; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.deal-quiet.is-warm { color: var(--ochre); font-weight: 600; }
.deal-quiet.is-cold { color: var(--accent); font-weight: 700; }
.deal-flag { font-family: var(--font-label); font-weight: 600; font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); }

.dragging-active .deal:not(.is-ghost) { cursor: grabbing; }

/* ---------- table ---------- */
.tools { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; margin-bottom: 14px; }
.search {
  flex: 1 1 220px;
  min-height: 44px;
  padding: 10px 13px;
  background: var(--cream);
  border: 1.5px solid var(--ink);
  border-radius: 2px;
  /* Inputs are recessed, not raised: you type into them. Everything you press has
     an outer shadow, everything you fill in has an inner one. */
  box-shadow: inset 0 2px 4px rgba(43, 30, 16, 0.2);
  font-size: 0.92rem;
}
.search::placeholder { color: var(--ink-muted); opacity: 1; }
.search:focus { outline: none; box-shadow: var(--sh-2), 0 0 0 2.5px rgba(138, 51, 36, 0.28); }

.table-wrap { border: 1.5px solid var(--ink); box-shadow: var(--sh-3), var(--edge-top); background: var(--cream); overflow-x: auto; }
table.grid { width: 100%; border-collapse: collapse; min-width: 720px; }
.grid thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background-color: var(--panel-bg);
  background-image: linear-gradient(180deg, var(--panel-bg) 0%, var(--linen-deep) 100%);
  box-shadow: 0 2px 4px rgba(43, 30, 16, 0.18);
  border-bottom: 1.5px solid var(--ink);
  padding: 0;
  text-align: left;
  white-space: nowrap;
}
.grid th button {
  display: flex;
  align-items: center;
  gap: 5px;
  width: 100%;
  padding: 10px 12px;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.68rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink);
  transition: background var(--t-fast) var(--ease-out);
}
.grid th button:hover { background: var(--linen-soft); }
.grid th .dir { font-size: 0.62rem; color: var(--accent); }
.grid th.is-num button { justify-content: flex-end; }
.grid tbody tr { border-bottom: 1px solid rgba(31, 24, 18, 0.14); transition: background var(--t-fast) var(--ease-out); }
.grid tbody tr:last-child { border-bottom: none; }
.grid tbody tr:hover { background: var(--linen); }
.grid tbody tr.is-clickable { cursor: pointer; }
.grid tbody tr:focus-visible { outline: 2.5px solid var(--accent); outline-offset: -2px; }
.grid td { padding: 11px 12px; vertical-align: middle; font-size: 0.88rem; }
.grid td.is-num { text-align: right; font-variant-numeric: tabular-nums; }
.grid .cell-name { font-weight: 600; }
.grid .cell-sub { font-size: 0.76rem; color: var(--ink-muted); }
.grid .owed { color: var(--accent); font-weight: 700; }

/* ---------- record page ---------- */
.rec-head { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; justify-content: space-between; padding-bottom: 14px; margin-bottom: 16px; border-bottom: 2px solid var(--ink); }
.rec-id { font-size: 0.76rem; color: var(--ink-muted); margin-top: 3px; }
.rec-money { display: flex; flex-wrap: wrap; gap: 18px; }
.rec-money-item { min-width: 84px; }
.rec-money-val { font-family: var(--font-label); font-weight: 600; font-size: 1.18rem; font-variant-numeric: tabular-nums; line-height: 1.1; }
.rec-money-val.owed { color: var(--accent); }
.rec-money-key { font-family: var(--font-label); font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted); margin-top: 2px; }

.rec-grid { display: grid; gap: 16px; }
.stack { display: flex; flex-direction: column; gap: 9px; }
.line { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px dashed rgba(31, 24, 18, 0.2); }
.line:last-child { border-bottom: none; }
.line-main { min-width: 0; }
.line-title { font-weight: 600; font-size: 0.9rem; }
.line-sub { font-size: 0.78rem; color: var(--ink-muted); margin-top: 2px; }
.line-side { flex: 0 0 auto; text-align: right; font-size: 0.78rem; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.line-link { color: var(--accent); font-weight: 600; text-decoration: none; border-bottom: 1.2px solid currentColor; }
.line-link:hover { color: var(--ink); }

.tl { list-style: none; }
.tl-item { display: grid; grid-template-columns: 72px 1fr; gap: 11px; padding: 9px 0; border-bottom: 1px dashed rgba(31, 24, 18, 0.18); }
.tl-item:last-child { border-bottom: none; }
.tl-kind { font-family: var(--font-label); font-weight: 600; font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); padding-top: 3px; }
.tl-body { font-size: 0.86rem; line-height: 1.45; color: var(--ink-soft); white-space: pre-wrap; }
.tl-when { font-size: 0.68rem; color: var(--ink-muted); margin-top: 3px; font-variant-numeric: tabular-nums; }

/* ---------- tasks ---------- */
.task { display: grid; grid-template-columns: 36px 1fr auto; gap: 11px; align-items: start; padding: 11px 0; border-bottom: 1px solid rgba(31, 24, 18, 0.14); }
.task:last-child { border-bottom: none; }
.task.is-done { opacity: 0.55; }
.task.is-done .task-title { text-decoration: line-through; }
.task-box {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 1.5px solid var(--ink);
  border-radius: 2px;
  background-color: var(--cream);
  background-image: linear-gradient(180deg, var(--cream) 0%, var(--panel-bg) 100%);
  font-family: var(--font-label);
  font-weight: 700;
  font-size: 0.9rem;
  box-shadow: var(--sh-1), var(--edge-top);
  transition: background var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
.task-box:hover { background: var(--linen-deep); }
.task-box:active { transform: translate(1px, 1px); box-shadow: none; }
.task-box.doing { background: var(--ochre); color: var(--cream); }
.task-box.done { background: var(--forest); color: var(--cream); }
.task-box.blocked { background: var(--accent); color: var(--cream); }
.task-title { font-weight: 600; font-size: 0.9rem; line-height: 1.35; }
.task-meta { font-size: 0.76rem; color: var(--ink-muted); margin-top: 2px; }
.task-due { font-size: 0.76rem; color: var(--ink-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.task-due.is-overdue { color: var(--accent); font-weight: 700; }

/* ---------- forms ---------- */
.form-row-crm { margin-bottom: 14px; }
.form-label-crm {
  display: block;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 5px;
}
.input-crm {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  background: var(--cream);
  border: 1.5px solid var(--ink);
  border-radius: 2px;
  /* Recessed, like .search: everything you fill in presses in, everything you press
     stands out. */
  box-shadow: inset 0 2px 4px rgba(43, 30, 16, 0.18);
  font-size: 0.92rem;
  font-family: var(--font-body);
}
textarea.input-crm { min-height: 0; line-height: 1.45; resize: vertical; }
.input-crm:focus { outline: none; box-shadow: inset 0 2px 4px rgba(43, 30, 16, 0.18), 0 0 0 2.5px rgba(138, 51, 36, 0.3); }
.form-hint { font-size: 0.76rem; color: var(--ink-muted); margin-top: 4px; line-height: 1.4; max-width: 62ch; }
.form-actions { display: flex; gap: 9px; justify-content: flex-end; padding-top: 14px; margin-top: 4px; border-top: 1.5px solid var(--ink); }

/* Two columns once there is room. Fields stay full width on a phone, where a
   half-width text input is just a smaller text input. */
@media (min-width: 760px) {
  .panel .form-row-crm { display: grid; grid-template-columns: 190px 1fr; gap: 14px; align-items: start; }
  .panel .form-label-crm { margin: 12px 0 0; text-align: right; }
  .panel .form-hint { grid-column: 2; margin-top: 0; }
}

/* ---------- toasts ---------- */
.toasts { position: fixed; right: 14px; bottom: 14px; left: 14px; z-index: var(--z-toast); display: flex; flex-direction: column; gap: 8px; align-items: stretch; pointer-events: none; }
.toast {
  background: var(--ink);
  color: var(--cream);
  border: 1.5px solid var(--ink);
  box-shadow: var(--sh-3);
  padding: 12px 14px;
  animation: toastIn var(--t-base) var(--ease-out) both;
}
.toast.is-bad { background: var(--accent); border-color: var(--accent); }
.toast-title { font-family: var(--font-label); font-weight: 600; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; }
.toast-body { font-size: 0.84rem; margin-top: 3px; opacity: 0.92; }
@keyframes toastIn { from { opacity: 0; transform: translateY(9px) scale(0.97); } to { opacity: 1; transform: none; } }

/* ---------- breakpoints. Structural, not fluid type. ---------- */
@media (min-width: 700px) {
  .canvas { padding: 22px 24px 72px; }
  .topbar { padding: 12px 24px; }
  .rec-grid { grid-template-columns: 1fr 1fr; }
  .toasts { left: auto; width: 25rem; }
}

@media (min-width: 1000px) {
  /* Rail pins open and stops being an overlay. */
  .rail { position: sticky; height: 100svh; top: 0; transform: none; }
  .scrim, .topbar-burger { display: none !important; }
  .rail-toggle { display: flex; }
  .app.is-collapsed .rail { width: var(--rail-w-collapsed); }
  .app.is-collapsed .rail-label,
  .app.is-collapsed .rail-count,
  .app.is-collapsed .rail-mark span,
  .app.is-collapsed .rail-who-name { display: none; }
  .app.is-collapsed .rail-mark { font-size: 1.35rem; }
  .app.is-collapsed .rail-item { justify-content: center; padding: 9px; }
  .app.is-collapsed .rail-toggle-glyph { transform: rotate(-135deg); margin-left: 2px; }
  .app.is-collapsed .rail-who { justify-content: center; padding: 8px 0 4px; }
  .rail { transition: width var(--t-base) var(--ease-out); }
}

@media (min-width: 1240px) {
  .rec-grid { grid-template-columns: 1.15fr 1fr; }
  .col { flex: 0 0 284px; }
}

/* Any control sized for a mouse gets thumb-sized on a touch device. The rail toggle
   is the only one: it lives at >=1000px, which is usually a trackpad but is also
   every tablet in landscape. */
@media (pointer: coarse) {
  .rail-toggle { width: 44px; height: 44px; flex-basis: 44px; }
}

/* Reduced motion: keep the state changes, drop the movement. The skeleton sweep and
   the drag ghost's tilt are the only things that go entirely. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; animation-iteration-count: 1 !important; }
  .skel::after { display: none; }
  .deal.is-ghost { transform: none; }
  .deal:hover { transform: none; }
  .btn:hover, .act:hover { transform: none; }
}
