/* ===========================================================================
   THE LOOK, AS SETTLED IN THE SANDBOXES -- Sep 4, 2026.

   Jenn, on the sandbox drawing: "I love the look that you built... It does
   not look like KB nor does it look like DBP, so it works completely."
   And on why the app's own look does not do the job: "I can't see everything
   when it's flat and looks like a document to me."

   That is the whole brief. Regions are separated by SURFACE and BORDER, not
   by whitespace, so the eye can find where one thing ends and the next
   begins. Labels are condensed uppercase; every number is monospaced and
   tabular so columns of figures line up; corners are square; borders are one
   pixel and everywhere.

   SCOPED, DELIBERATELY. Everything in this file lives under `body.k9-preview`
   and only the two preview pages carry that class. The app went live Sep 3
   and Jenn runs the kennel on it; a palette swap across forty pages would
   have her finding black-on-black text during a check-in. Her call, and it
   was the right one: "it seems like the safest way to go is to make two
   preview pages."

   WHEN THIS IS ADOPTED, the scope comes off and this becomes app.css. That
   unscoping is where things drift, so the rule to carry forward: no color
   is written as a literal outside the two blocks at the top of this file.

   DARK AND LIGHT BOTH, following the device, with a switch on the bar.
   Decided Sep 4 -- it follows the device, a person may override it, and no
   facility can force it. Jenn's reason for the last part, and it settles it:
   "especially if someone has accessibility colors on their system due to bad
   eyes, or being color blind or something."
   =========================================================================== */

body.k9-preview {
  --ground:#f5f4ef; --surface:#ffffff; --surface-2:#efeee7;
  --pk:#1b201c; --pk-2:#4d534d; --pk-3:#7d837c;
  --line:#dcdbd2; --line-2:#c8c8bd;
  --accent:#2f5d4a; --accent-soft:#e2ebe5;
  --red:#9f2b1f; --red-soft:#f7e6e3; --red-line:#e0b7b0;
  --amber:#8a5c0d; --amber-soft:#f7edd8; --ok:#356b47;
  --lock:#5d6570; --lock-soft:#e8eaed;
  --rail:#242b28; --rail-ink:#e4e7e2; --rail-line:#3a4340; --rail-2:#2e3733;
  --note:#7a5a12; --note-bg:#fbf3df; --note-line:#e6d3a6;
  --shadow:0 1px 0 rgba(27,32,28,.04), 0 1px 3px rgba(27,32,28,.06);
}

/* THE DEVICE DECIDES, unless the person has said otherwise on the bar. */
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) body.k9-preview {
    --ground:#13171a; --surface:#1b2124; --surface-2:#232a2e;
    --pk:#e7e9e4; --pk-2:#a8afab; --pk-3:#7d857f;
    --line:#2d3539; --line-2:#3c4649;
    --accent:#7fc0a2; --accent-soft:#1e2f28;
    --red:#e08375; --red-soft:#331f1c; --red-line:#5d332c;
    --amber:#d7a44c; --amber-soft:#2e2617; --ok:#79b98e;
    --lock:#9aa4b0; --lock-soft:#232a31;
    --rail:#0e1214; --rail-ink:#dfe3df; --rail-line:#293134; --rail-2:#171d20;
    --note:#d8b96a; --note-bg:#26210f; --note-line:#4a3f1c;
    --shadow:0 1px 0 rgba(0,0,0,.3), 0 1px 3px rgba(0,0,0,.35);
  }
}
html[data-theme="dark"] body.k9-preview {
  --ground:#13171a; --surface:#1b2124; --surface-2:#232a2e;
  --pk:#e7e9e4; --pk-2:#a8afab; --pk-3:#7d857f;
  --line:#2d3539; --line-2:#3c4649;
  --accent:#7fc0a2; --accent-soft:#1e2f28;
  --red:#e08375; --red-soft:#331f1c; --red-line:#5d332c;
  --amber:#d7a44c; --amber-soft:#2e2617; --ok:#79b98e;
  --lock:#9aa4b0; --lock-soft:#232a31;
  --rail:#0e1214; --rail-ink:#dfe3df; --rail-line:#293134; --rail-2:#171d20;
  --note:#d8b96a; --note-bg:#26210f; --note-line:#4a3f1c;
  --shadow:0 1px 0 rgba(0,0,0,.3), 0 1px 3px rgba(0,0,0,.35);
}

/* The two type families the sandbox used. Loaded from Google in the preview
   only. BEFORE THIS IS ADOPTED they get self-hosted: the provenance
   inventory for the lawyers says zero third-party CDN, and a font link is a
   third-party CDN. Flagged rather than quietly kept. */
body.k9-preview {
  background: var(--ground);
  color: var(--pk);
  font-family: "Barlow", "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
body.k9-preview * { box-sizing: border-box; }

/* ---- the top bar, inside the scope ---- */
body.k9-preview .topbar {
  background: var(--rail); color: var(--rail-ink);
  border-bottom: 1px solid var(--rail-line); padding: 8px 20px;
}
body.k9-preview .topbar .brand {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 700;
  font-size: 15px; letter-spacing: .09em; text-transform: uppercase;
}
body.k9-preview .topbar .brand-logo { height: 34px; }
body.k9-preview .topbar .nav-links a,
body.k9-preview .topbar a.logout { color: var(--rail-ink); font-size: 13.5px; }
/* The client shell logs out with a form, because Django requires POST. */
body.k9-preview .topbar form.logout-form { display: inline; margin: 0; padding: 0; }
body.k9-preview .topbar form.logout-form button {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--rail-ink); font-size: 13.5px;
}
body.k9-preview .topbar form.logout-form button:hover { color: #fff; }
body.k9-preview .topbar .nav-links a:hover { color: #fff; }
body.k9-preview .view-as-bar { background: var(--amber-soft); color: var(--amber);
  border-bottom: 1px solid var(--line); }

/* The person's own light/dark switch. Sits on the bar because that is where
   Jenn put it: "control on the top bar". */
body.k9-preview .theme-pick {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 11.5px;
  letter-spacing: .07em; text-transform: uppercase;
  background: var(--rail-2); color: var(--rail-ink);
  border: 1px solid var(--rail-line); padding: 5px 11px; cursor: pointer;
  margin-right: 14px;
}
body.k9-preview .theme-pick:hover { border-color: var(--accent); color: #fff; }

body.k9-preview .container { max-width: 1180px; padding: 20px 20px 64px; }

/* ---- the read-only banner ---- */
body.k9-preview .pv-readonly {
  background: var(--note-bg); color: var(--note);
  border: 0; border-left: 2px solid var(--note-line); border-radius: 0;
  padding: 9px 13px; margin-bottom: 18px; font-size: 13px; line-height: 1.5;
}
body.k9-preview .pv-readonly a { color: var(--note); }

/* ⭐ A MESSAGE THE APP SAYS BACK TO SOMEBODY. Sep 6, 2026.

   `.msg` had no styling anywhere in this application -- not here, not in
   app.css -- so every "saved", "couldn't save" and "welcome" has been bare
   text floating above the page since the beginning. Nobody noticed because
   staff read them in passing and know what they mean.
   
   It was found the first time a stranger saw one: Fred Test signed himself
   up, and the sentence welcoming him to Kawa Farms rendered as an unstyled
   line hanging over the top of his account. That is the first thing a new
   client ever reads.
   
   ⭐ THE ERROR VARIANT IS THE ONE THAT MATTERS MOST. An error nobody can
   distinguish from body text is an error nobody reads -- which is the same
   defect as KennelBooker's "or sign in here" in really, really small
   letters, arriving from the other direction. */
body.k9-preview .msg {
  padding: 11px 14px; border-radius: 10px; margin-bottom: 12px;
  font-size: 14px; line-height: 1.45;
  background: var(--surface); border: 1px solid var(--line-2); color: var(--pk);
}
body.k9-preview .msg.success {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}
body.k9-preview .msg.error {
  background: var(--red-soft); border-color: var(--red-line); color: var(--red);
}
body.k9-preview .msg.warning { border-color: var(--accent); }

/* ⭐ THE GREETING NEEDS ROOM UNDER IT ON A CLIENT PAGE. On the staff pages
   the identity block is followed by its tab strip, which is why it carries no
   bottom padding. The client's home page puts a CARD straight after it, and
   the two collided along their shared border the first time anybody looked. */
body.k9-preview.my-portal .ident {
  padding-bottom: 16px; margin-bottom: 14px;
}

/* ---- identity ---- */
body.k9-preview .ident {
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow); padding: 18px 20px 0;
}
body.k9-preview .ident-top {
  display: flex; flex-wrap: wrap; gap: 14px 26px;
  align-items: flex-end; justify-content: space-between;
}
body.k9-preview .ident-who { display: flex; align-items: flex-end; gap: 16px; }
body.k9-preview h1 {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 700;
  font-size: 34px; line-height: 1; margin: 0; letter-spacing: -.01em;
}
body.k9-preview .sub { color: var(--pk-2); font-size: 13.5px; margin-top: 6px; }
body.k9-preview .sub a { color: var(--accent); }
/* ⭐ THE TEMPERAMENT, AT THE SIZE OF THE DOG'S NAME. Sep 5, 2026.
   Jenn: "the temperament needs to be as large as Kova's letters for her name.
   But on the right side above Service dog candidate." So the right-hand
   column becomes a stack: the temperament on top, the chips under it.

   THE COLOR IS THE BOX, NOT A ROW OF ITS OWN -- "the temperament color will
   actually change the box that the word temperament is in." The color comes
   off the record as an inline style because it is DATA, not a class: the
   facility picks from ten and decides what each one means, and no stylesheet
   gets to encode that.

   White type on a picked color, with a dark shadow behind it so it stays
   legible on yellow as well as on black. Yellow with white on it is the one
   combination that fails, and it is the one Jenn already called out on the
   run card. */
body.k9-preview .ident-right {
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
}
body.k9-preview .temperament {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 700;
  font-size: 34px; line-height: 1; letter-spacing: -.01em;
  padding: 6px 14px 8px; color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .55);
  max-width: 100%; text-align: right;
}
/* Nothing picked: the word still shows, in the page's own ink rather than in
   a color that would mean something it has not been given. */
body.k9-preview .temperament.untinted {
  background: none; color: var(--pk); text-shadow: none;
  border: 1px solid var(--line-2); padding: 5px 13px 7px;
}
@media (max-width: 700px) {
  body.k9-preview .ident-right { align-items: flex-start; }
  body.k9-preview .temperament { font-size: 26px; text-align: left; }
}

/* A NOTE, AND THE LINE UNDER IT. Sep 5, 2026 -- a dog's notes became dated
   entries with a name on them, the same shape the client page got that
   morning. The text reads first and the attribution sits under it in the
   quiet type, because the note is what somebody came to read. */
body.k9-preview .note-entry {
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
body.k9-preview .note-entry:last-child { border-bottom: 0; }
body.k9-preview .note-said { line-height: 1.55; }
body.k9-preview .note-entry .whocan { display: block; margin-top: 4px; }
/* One small word, and the history is behind it rather than on it. Jenn:
   "we just need the amended note and maybe a small footer that means it was
   amended." */
body.k9-preview .was-updated { font-style: italic; }
/* Folded by time. The summary is a heading you can press, so it reads as part
   of the page rather than as a control bolted onto it. */
body.k9-preview .notes-fold > summary {
  cursor: pointer; list-style: none; padding: 12px 16px 10px;
}
body.k9-preview .notes-fold > summary::-webkit-details-marker { display: none; }
body.k9-preview .notes-fold > summary:hover { color: var(--accent); }
body.k9-preview .notes-fold > summary::before { content: "▸ "; }
body.k9-preview .notes-fold[open] > summary::before { content: "▾ "; }

/* The facility's own legend, drawn only where they have written one. */
body.k9-preview .colorkey { display: inline-block; margin-right: 14px; white-space: nowrap; }
body.k9-preview .colorkey i {
  display: inline-block; width: 10px; height: 10px; margin-right: 5px;
  border: 1px solid rgba(0, 0, 0, .25); vertical-align: baseline;
}

body.k9-preview .ident-chips { display: flex; gap: 8px; flex-wrap: wrap; }
body.k9-preview .pchip {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 9px; border: 1px solid var(--line-2); color: var(--pk-2);
}
body.k9-preview .pchip.here { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
body.k9-preview .pchip.vip { background: var(--lock-soft); border-color: transparent; color: var(--lock); }

/* THE DOG'S PHOTO. Jenn, Sep 4: "on the dog page, we need a dog picture."
   And the other way on the client page -- names and runs in Here Now and in
   the dog list, no photos: "I think it is appropriate there not to have
   their pictures." */
body.k9-preview .ident-photo {
  width: 84px; height: 84px; object-fit: cover;
  border: 1px solid var(--line-2); display: block;
}

body.k9-preview .actions {
  display: flex; flex-wrap: wrap; margin: 16px -20px 0;
  border-top: 1px solid var(--line);
}
/* THE THREE STATES OF A DOOR -- see the door tag in templatetags/kawa.py.
   not built | designing | and nothing at all when the page is redrawn, because
   Jenn, Sep 4, 2026: "if it's built and redrawn, we don't need to have
   anything on it because it's done." */
body.k9-preview .door {
  font-weight: 500; color: var(--pk); border-right: 1px solid var(--line);
  padding: 11px 16px; text-decoration: none; font-size: 14.5px;
  display: inline-flex; align-items: baseline; gap: 7px;
}
body.k9-preview a.door:hover { background: var(--surface-2); }
body.k9-preview a.door.primary { color: var(--accent); font-weight: 600; }
body.k9-preview .door.off { color: var(--pk-3); cursor: default; }
body.k9-preview .door .mark {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 10.5px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--pk-3);
  border: 1px solid var(--line-2); padding: 1px 5px; white-space: nowrap;
}
/* Designing is work in progress, not a hole. Amber says "on its way". */
body.k9-preview .door .mark.designing { color: var(--amber); border-color: var(--amber); }

/* ---- the red strip ---- */
body.k9-preview .rules-strip {
  background: var(--red-soft); border: 1px solid var(--red-line); border-top: 0;
  padding: 12px 16px 14px;
}
body.k9-preview .rules-strip h2 {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 700;
  font-size: 12.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--red); margin: 0 0 8px;
}
body.k9-preview .rules-strip ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
body.k9-preview .rules-strip li { color: var(--red); font-size: 14px; }
body.k9-preview .rules-strip li b {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 15.5px; letter-spacing: .01em;
}
body.k9-preview .rules-strip .who { color: var(--pk-3); font-size: 12px; }

/* ---- at a glance ---- */
body.k9-preview .glance {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-top: 0;
  margin-bottom: 22px;
}
body.k9-preview .g { background: var(--surface); padding: 12px 16px 13px; }
body.k9-preview .g .k {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 11.5px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--pk-3);
}
body.k9-preview .g .v {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 19px;
  font-weight: 500; margin-top: 3px; font-variant-numeric: tabular-nums;
}
body.k9-preview .g .v small { font-family: "Barlow", sans-serif; font-size: 13px; color: var(--pk-2); font-weight: 400; }
body.k9-preview .g .v.warn { color: var(--amber); }
body.k9-preview .g .v.small { font-size: 15px; }

/* ---- columns and cards ---- */
body.k9-preview .cols {
  display: grid; grid-template-columns: minmax(280px, 1fr) minmax(0, 2.05fr);
  gap: 22px; align-items: start;
}
body.k9-preview .card {
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow); border-radius: 0; padding: 0; margin-bottom: 22px;
}
body.k9-preview .card > h2 {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 13px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--pk-2); margin: 0; padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
body.k9-preview .whocan {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 11px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--lock); margin: 0;
}
body.k9-preview .card-body { padding: 14px 16px; }
body.k9-preview dl.facts { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 9px 16px; }
body.k9-preview dl.facts dt {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 12px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--pk-3); padding-top: 2px;
}
body.k9-preview dl.facts dd { margin: 0; font-size: 15px; }
body.k9-preview dl.facts dd.mono { font-family: "IBM Plex Mono", monospace; font-size: 13.5px; font-variant-numeric: tabular-nums; }

body.k9-preview .here-card { border-color: var(--accent); }
body.k9-preview .here-card > h2 { background: var(--accent-soft); color: var(--accent); border-bottom-color: var(--accent); }

/* ---- tables ---- */
body.k9-preview table { width: 100%; border-collapse: collapse; font-size: 14px; }
body.k9-preview th {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--pk-3); text-align: left; padding: 9px 16px;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
body.k9-preview td { padding: 10px 16px; border-bottom: 1px solid var(--line); vertical-align: top; }
body.k9-preview tr:last-child td { border-bottom: 0; }
body.k9-preview td.mono { font-family: "IBM Plex Mono", monospace; font-size: 13.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
body.k9-preview a { color: var(--accent); }
body.k9-preview .subhead {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--pk-3); padding: 14px 16px 0; margin: 0;
}
body.k9-preview .empty { padding: 14px 16px; color: var(--pk-3); font-style: normal; }
body.k9-preview .state {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 11px;
  letter-spacing: .07em; text-transform: uppercase; padding: 2px 7px;
  border: 1px solid var(--line-2); color: var(--pk-3); white-space: nowrap;
  display: inline-block;
}
body.k9-preview .state.ok { color: var(--ok); border-color: var(--ok); }
body.k9-preview .state.un { color: var(--amber); border-color: var(--amber); }
body.k9-preview .state.bad { color: var(--red); border-color: var(--red); }
body.k9-preview .note {
  border-left: 2px solid var(--note-line); background: var(--note-bg);
  color: var(--note); font-size: 13px; line-height: 1.5; padding: 9px 13px;
  margin: 12px 16px 14px;
}

/* ---- the tabs, still radio buttons and labels ---- */
body.k9-preview .tab-strip {
  display: flex; flex-wrap: wrap; border-bottom: 1px solid var(--line);
  background: var(--surface-2); margin: 0; padding: 0;
}
body.k9-preview .tab-strip label {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 13.5px; letter-spacing: .05em; text-transform: uppercase;
  border: 0; border-right: 1px solid var(--line); border-bottom: 0;
  padding: 11px 15px; color: var(--pk-2); margin: 0;
}
body.k9-preview .tab-strip label:hover { color: var(--pk); }
body.k9-preview .tab-strip label .n {
  font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--pk-3); margin-left: 5px;
}
body.k9-preview .tab-strip label .n.warn { color: var(--amber); }
body.k9-preview .tabbed > .t1:checked ~ .tab-strip .l1,
body.k9-preview .tabbed > .t2:checked ~ .tab-strip .l2,
body.k9-preview .tabbed > .t3:checked ~ .tab-strip .l3,
body.k9-preview .tabbed > .t4:checked ~ .tab-strip .l4,
body.k9-preview .tabbed > .t5:checked ~ .tab-strip .l5,
body.k9-preview .tabbed > .t6:checked ~ .tab-strip .l6,
body.k9-preview .tabbed > .t7:checked ~ .tab-strip .l7,
body.k9-preview .tabbed > .t8:checked ~ .tab-strip .l8 {
  background: var(--surface); color: var(--pk);
  box-shadow: inset 0 2px 0 var(--accent); border-bottom-color: transparent;
}

@media (max-width: 900px) {
  body.k9-preview .glance { grid-template-columns: repeat(3, 1fr); }
  body.k9-preview .cols { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  body.k9-preview .glance { grid-template-columns: repeat(2, 1fr); }
  body.k9-preview h1 { font-size: 28px; }
  body.k9-preview dl.facts { grid-template-columns: 1fr; gap: 2px; }
  body.k9-preview dl.facts dd { margin-bottom: 8px; }
}


/* ---------------------------------------------------------------------------
   A STAY, DRAWN AS THE RUNS IT OCCUPIES. Sep 4, 2026 -- see
   _preview_stay_block.html for why this is not a table.
   --------------------------------------------------------------------------- */
body.k9-preview .stay-head {
  display: flex; flex-wrap: wrap; gap: 6px 20px; align-items: baseline;
  padding: 14px 16px 12px; border-bottom: 1px solid var(--line);
}
body.k9-preview .stay-head + .stay-head { border-top: 1px solid var(--line); }
body.k9-preview .stay-head .type {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 700; font-size: 20px;
}
body.k9-preview .stay-head .type a { color: var(--pk); text-decoration: none; }
body.k9-preview .stay-head .type a:hover { color: var(--accent); }
body.k9-preview .stay-head .when {
  font-family: "IBM Plex Mono", monospace; font-size: 13.5px; color: var(--pk-2);
  font-variant-numeric: tabular-nums;
}
body.k9-preview .stay-head .paid {
  margin-left: auto; font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600; font-size: 12px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ok);
}
body.k9-preview .runs {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line);
}
/* The red edge is the run card's stripe: this seat has something on it. */
body.k9-preview .run {
  background: var(--surface); padding: 11px 14px 12px;
  display: flex; gap: 11px; align-items: flex-start;
  box-shadow: inset 3px 0 0 var(--red);
}
body.k9-preview .run.clear { box-shadow: inset 3px 0 0 var(--line-2); }
body.k9-preview .run .plate {
  font-family: "IBM Plex Mono", monospace; font-size: 11px; font-weight: 600;
  border: 1px solid var(--line-2); color: var(--pk-2); padding: 3px 6px;
  white-space: nowrap; margin-top: 1px;
}
body.k9-preview .run .dog {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 17px; line-height: 1.15; color: var(--pk); text-decoration: none;
}
body.k9-preview .run .dog:hover { color: var(--accent); }
/* THE SPACE BEFORE THE CODE. Jenn, Sep 4: "the canine is running into the
   dog's name." A margin, not a space character, so it cannot be eaten by
   template whitespace trimming. */
body.k9-preview .run .k9 {
  font-family: "Barlow Semi Condensed", sans-serif; font-size: 11px;
  letter-spacing: .07em; color: var(--pk-3); margin-left: 7px;
}
body.k9-preview .run .flags { font-size: 12.5px; color: var(--red); margin-top: 2px; }

@media (max-width: 700px) { body.k9-preview .runs { grid-template-columns: 1fr; } }

/* THE CODES COLUMN. A badge that follows a name starts wherever that name
   ends, so a column of them lines up with nothing. Its own cell, left
   justified, narrow enough that it does not push the table around. */
body.k9-preview td.codes { white-space: nowrap; width: 1%; }
body.k9-preview td.codes .code-badge-sm { margin: 0 4px 0 0; }

/* The client's own code, beside her name. Jenn, Sep 4, 2026: "her name, and
   then right next to it... not touching her name, not twenty feet over from
   her name." The gap is a margin so template whitespace cannot eat it. */
body.k9-preview h1 .name-chip { margin-left: 12px; vertical-align: middle; }

/* MONEY'S OWN KINDS, INSIDE THE MONEY TAB.
   Jenn, Sep 4, 2026, on the first attempt: "this loads ugly... make invoices,
   payments and wallet lower so they don't take up or hit the tab above. Also,
   invoices is hanging off the edge."

   Both were the same mistake -- it was pulled out to the card's edges with
   negative margins, so it spanned the full width like a SECOND tab bar and
   sat flush against the first. Two bars of the same weight, touching, and the
   left-hand one running past the content under it.

   It is not a second bar. It is a choice made INSIDE one tab, so it is
   indented to the content, given air above it, and drawn as segments rather
   than as tabs. */
/* ⭐ ONE SUB-STRIP, DRAWN ONE WAY. Sep 5, 2026, Jenn on the Health tab: "the
   design look is going to be based off of, on the customer's page, how we did
   money -- not how it works, but how it looks." So Health's four kinds and
   Money's three kinds are the SAME component under two names, rather than a
   second strip that drifts a pixel a month. `.money-tabbed` is kept as a name
   the client page already uses. */
body.k9-preview .money-tabbed,
body.k9-preview .sub-tabbed { margin: 0; padding: 16px 16px 0; }
body.k9-preview .money-tabbed > .tab-strip,
body.k9-preview .sub-tabbed > .tab-strip {
  background: none; border-bottom: 0; gap: 6px; padding: 0; margin: 0 0 14px;
}
body.k9-preview .money-tabbed > .tab-strip label,
body.k9-preview .sub-tabbed > .tab-strip label {
  font-size: 12px; padding: 6px 13px; border: 1px solid var(--line-2);
  border-bottom: 1px solid var(--line-2); color: var(--pk-2);
  background: var(--surface-2);
}
body.k9-preview .money-tabbed > .tab-strip label:hover,
body.k9-preview .sub-tabbed > .tab-strip label:hover { border-color: var(--accent); }
/* The chosen one is filled, not underlined -- an underline is what the tabs
   above use, and two things must not say "selected" the same way. */
body.k9-preview .money-tabbed > .t1:checked ~ .tab-strip .l1,
body.k9-preview .money-tabbed > .t2:checked ~ .tab-strip .l2,
body.k9-preview .money-tabbed > .t3:checked ~ .tab-strip .l3,
body.k9-preview .sub-tabbed > .t1:checked ~ .tab-strip .l1,
body.k9-preview .sub-tabbed > .t2:checked ~ .tab-strip .l2,
body.k9-preview .sub-tabbed > .t3:checked ~ .tab-strip .l3,
body.k9-preview .sub-tabbed > .t4:checked ~ .tab-strip .l4 {
  background: var(--accent); border-color: var(--accent); color: var(--surface);
  box-shadow: none;
}
body.k9-preview .money-tabbed .subhead,
body.k9-preview .sub-tabbed .subhead { padding-left: 0; padding-right: 0; }
body.k9-preview .money-tabbed .card-body,
body.k9-preview .sub-tabbed .card-body { padding-left: 0; padding-right: 0; }
body.k9-preview .money-tabbed .table-scroll,
body.k9-preview .sub-tabbed .table-scroll { margin: 0 -16px; }
body.k9-preview .money-tabbed .note,
body.k9-preview .sub-tabbed .note { margin-left: 0; margin-right: 0; }

/* THE WEIGHT CARD, BORROWED. It is drawn for the live pages and brings its
   own box; inside a tab it is already in one, so the box comes off and only
   the contents stay. */
body.k9-preview .sub-tabbed .card {
  border: 0; border-radius: 0; box-shadow: none; background: none;
  margin: 0; padding: 0;
}
body.k9-preview .sub-tabbed .card > h3 { display: none; }

/* THE MONEY BAR, at the top of the Money tab. Four cells, and it is the same
   component as the strip at the top of a record -- one bar drawn one way,
   wherever it appears. Sep 4, 2026. */
body.k9-preview .money-bar {
  grid-template-columns: repeat(4, 1fr); border-top: 0; margin: 0 0 0;
}
body.k9-preview .money-bar .v small { font-size: 15px; color: var(--pk-2); }
@media (max-width: 700px) { body.k9-preview .money-bar { grid-template-columns: repeat(2, 1fr); } }

/* ---------------------------------------------------------------------------
   A CARD, OPEN. Sep 4, 2026 — Stacie's rule: a card is text until you press
   its Edit, so the editing state has to look unmistakably different from the
   reading state, not merely have boxes in it.
   --------------------------------------------------------------------------- */
body.k9-preview .card > h2 .edit {
  font-family: "Barlow", sans-serif; text-transform: none; letter-spacing: 0;
  font-size: 13.5px; font-weight: 500; color: var(--accent);
  border: 1px solid var(--line-2); background: none; padding: 3px 11px;
  text-decoration: none;
}
body.k9-preview .card > h2 .edit:hover { border-color: var(--accent); background: var(--accent-soft); }

body.k9-preview dl.facts.editing { gap: 10px 16px; align-items: center; }
body.k9-preview dl.facts.editing input[type="text"],
body.k9-preview dl.facts.editing input[type="email"],
body.k9-preview dl.facts.editing input[type="date"],
body.k9-preview dl.facts.editing select,
body.k9-preview dl.facts.editing textarea {
  font: inherit; width: 100%; background: var(--surface-2);
  border: 1px solid var(--line-2); color: var(--pk); padding: 5px 8px;
}
body.k9-preview dl.facts.editing textarea { resize: vertical; }
body.k9-preview dl.facts.editing input:focus,
body.k9-preview dl.facts.editing select:focus,
body.k9-preview dl.facts.editing textarea:focus {
  outline: 2px solid var(--accent); outline-offset: -2px;
}
/* ⭐ THE CODES: what she has, and a door to the rest.
   Jenn, Sep 4, 2026: "I don't want this, the picker, not like this — if I had
   20 codes it would extend down the page." So the ones she holds are ticks on
   the card, and everything else folds away behind "Add a code". */
body.k9-preview .code-tick {
  display: inline-flex; align-items: center; gap: 6px; font-size: 14px;
  margin: 0 14px 4px 0; white-space: nowrap;
}
body.k9-preview .code-tick input { width: auto; }
body.k9-preview .code-tick.on { font-weight: 500; }
body.k9-preview .code-more { margin-top: 6px; }
body.k9-preview .code-more > summary {
  cursor: pointer; font-family: "Barlow Semi Condensed", sans-serif;
  font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--accent); display: inline-block; padding: 3px 0;
}
body.k9-preview .code-more > summary::marker { color: var(--pk-3); }
body.k9-preview .code-tick-row {
  display: flex; flex-wrap: wrap; margin-top: 6px; padding: 9px 11px;
  background: var(--surface-2); border: 1px solid var(--line);
}

body.k9-preview .card-actions { display: flex; align-items: center; gap: 14px; margin-top: 16px; }
body.k9-preview .card-actions button {
  font: inherit; font-weight: 600; font-size: 14px; cursor: pointer;
  background: var(--accent); border: 1px solid var(--accent);
  color: var(--surface); padding: 7px 20px;
}
body.k9-preview .card-actions button:hover { filter: brightness(1.08); }
/* Cancel is a way out, not a second Save -- so it is a link, not a button. */
body.k9-preview .card-actions .cancel { color: var(--pk-2); font-size: 14px; }

/* An open card says so from across the page. */
body.k9-preview .card:has(dl.facts.editing) { border-color: var(--accent); }

/* WALLET'S FOUR BOXES. Points, Credit and Wallet are set by a person; Lifetime
   is the door to the money from before this system. Drawn as boxes because
   Jenn drew them as boxes -- "I don't want them just looking like text boxes,
   I want them in their own little boxes." Sep 4, 2026. */
body.k9-preview .money-boxes {
  grid-template-columns: repeat(5, 1fr); border-top: 0; margin: 0 0 18px;
}
body.k9-preview .money-boxes .box { text-decoration: none; color: inherit; display: block; }
body.k9-preview .money-boxes .box:hover { background: var(--surface-2); }
body.k9-preview .money-boxes .box:hover .k { color: var(--accent); }
body.k9-preview .money-boxes .v .none {
  font-family: "Barlow", sans-serif; font-size: 14px; color: var(--accent);
}
@media (max-width: 700px) { body.k9-preview .money-boxes { grid-template-columns: repeat(2, 1fr); } }

/* A box, opened. */
body.k9-preview .opened {
  border: 1px solid var(--accent); background: var(--surface);
  padding: 0 16px 16px; margin: 0 0 18px;
}
body.k9-preview .opened .subhead { padding-left: 0; }
body.k9-preview .opened .note { margin: 0 0 14px; }


/* --- The write doors, and what they open. Sep 5, 2026. ------------------
 * The form opens under the button row, never inside the tab that shows what
 * it made -- redesign doc SS 4c.
 */
.door.on { border-color: var(--accent); color: var(--accent); }
.opened.writing { margin-top: 12px; }
.opened.writing .facts.editing { margin-bottom: 10px; }

/* A list of names you click, never a document drawn into the page.
 * Jenn: "They'll be named, and you can click on the name, and that'll open
 * the document for you."
 */
.named-list { list-style: none; margin: 6px 0 0; padding: 0; }
.named-list li { padding: 7px 0; border-bottom: 1px solid var(--line); }
.named-list li:last-child { border-bottom: 0; }
.named-list a { font-weight: 600; }
.named-list .whocan { margin-left: 10px; }

/* A note is a record: what was said, then who said it and when. */
ul.notes { list-style: none; margin: 6px 0 0; padding: 0; }
ul.notes li { padding: 10px 0; border-bottom: 1px solid var(--line); }
ul.notes li:last-child { border-bottom: 0; }
.note-said { margin-bottom: 4px; }

/* The wording somebody agreed to, read on a screen. Long, and read once --
 * so it gets reading measure and room to breathe rather than table density.
 */
.waiver-text { max-width: 68ch; line-height: 1.6; }

/* --- Stays, folded by time. Sep 5, 2026. ------------------------------
 * A month is a month for everybody; ten stays is right for one client and
 * absurd for the next. Closed by default, opens in place.
 */
details.folded { border-top: 1px solid var(--line); }
details.folded > summary {
  cursor: pointer; padding: 10px 2px; list-style: none;
  display: flex; align-items: center; gap: 8px;
}
details.folded > summary::-webkit-details-marker { display: none; }
details.folded > summary::before {
  content: "\25B8"; font-size: 11px; opacity: .6; transition: transform .12s;
}
details.folded[open] > summary::before { transform: rotate(90deg); }
details.folded.inner { border-top: 0; margin-left: 14px; }

/* ===========================================================================
   THE CLIENT'S FRONT DOOR  (body.my-door)  Sep 5, 2026

   Deliberately quiet. This page has one job -- get a client into their
   account -- and everything on it that is not that job is competing with it.

   The background image Jenn asked for lands here later: one photograph, with
   a wash between it and the text. The wash is a layer rather than an edit to
   the photo, so it can be tuned in seconds and the original stays original --
   and dark mode gets its own wash over the same file rather than a second
   picture.
   =========================================================================== */
/* ⭐ THE CARD SITS LEFT, NOT CENTER. Sep 5, 2026, and it is Jenn's correction
   after seeing it live -- the kind of rework she called fair: "sometimes the
   idea initially is great, and then you see it in reality."

   The first version centered the card, which put it straight over the dog:
   "most of his body ended up behind the sign in screen." Moving the card is
   the fix rather than moving the photograph, because it is also the better
   layout -- a card on one side and the picture breathing on the other.

   Her reason for LEFT specifically, and it decides nothing else: "so that you
   can see all four feet are off the ground."

   On a phone the card is full width whatever this says, so the rule only
   applies once there is room for both. */
/* The door page was a flex box that centered the card over a full-page
   photograph. That whole idea was replaced by the band below, and leaving the
   old rule here meant two rules fighting -- the later one winning by accident
   rather than by intent. */
body.k9-preview .door-page { max-width: 460px; width: 100%; padding: 32px 20px 64px; }

/* ⭐⭐ THE PHOTOGRAPH IS A BAND ACROSS THE TOP, NOT A BACKGROUND BEHIND
   EVERYTHING -- and getting here took four looks at the live page.

   1. CENTERED card: "most of his body ended up behind the sign in screen."
   2. LEFT: head and chest clear, "but that back foot is being covered."
   3. LOW, frame lifted: right on one window and wrong on the next -- Jenn's
      screen is much wider than tall, mine was nearly square, and the crop
      moved him under the card again.

   THE LESSON, AND IT IS THE ONLY REASON THIS COMMENT IS LONG: he runs the
   FULL WIDTH of that frame, tail at one edge and nose near the other. On a
   full-bleed background there is NO window shape where a centered card misses
   him. Three rounds were spent nudging percentages at a problem that had no
   solution in that shape. Tuning it for one screen guaranteed breaking it on
   the next.

   So the picture stopped being a background. It is a band across the top and
   the card sits on solid ground beneath it, which means the dog is never
   behind anything -- on any window, on any phone, at any zoom. The wash on
   the band drops to 0.28 because nothing is written over it any more.

   ⭐ THE GENERAL RULE: when a fix has to be re-tuned for each viewport, the
   layout is wrong, not the numbers. */
body.k9-preview.my-door { display: block; min-height: 100vh; }

/* ⭐⭐ THE BAND TAKES THE PICTURE'S OWN SHAPE, CAPPED. Sep 6, 2026, and
   it is the fifth arrangement of this one photograph.

   WHAT WAS WRONG. The band used to take whatever height was left over after
   the card's room was reserved: max(180px, 100vh - 700px). On a tall window
   that left about 450px and Moose fitted. On Jenn's laptop it collapsed onto
   the 180px floor -- and because the photograph still filled the WIDTH, a
   180px window onto a 576px-tall picture cut off everything above it. His
   whole head and shoulders. Her words, Sep 6: "if I have it open on my
   laptop, it kinda cuts off his head a little bit."

   ⭐ WHY THE FOCAL POINT WAS NOT THE FIX. background-position only chooses
   WHICH slice of the picture a too-short band shows. He fills that frame nose
   to tail, so moving it up would have bought his head by losing his feet --
   the same trade the three earlier rounds kept making. THE HEIGHT WAS THE
   FAULT, NOT THE FRAMING.

   WHAT IT IS NOW. The band is a real <img> in the flow at its own aspect
   ratio, so the browser does the arithmetic and the whole animal is there at
   every width. Nothing in this file knows or cares that Kawa's photograph is
   2.5:1 -- a facility that uploads a square one gets a square band. There is
   no number here to get wrong for the next facility, which is the same reason
   the temperament list and the play areas are data and not code.

   ⭐ THE CAP IS THE ONLY JUDGMENT ON THIS PAGE, and Jenn made it looking at
   both: 55vh, so a big picture can never push the sign-in form off the bottom
   of a short window. When the cap bites it crops from the BOTTOM -- his head,
   his collar and his tail stay, and his back feet go. She chose that over the
   whole dog with the email box below the fold. */
body.k9-preview.my-door .door-band {
  position: relative; max-height: 55vh; overflow: hidden;
}
body.k9-preview.my-door .door-band img {
  display: block; width: 100%; height: auto;
}
/* The card sits close under the band -- Jenn: "I think you can bring the card
   up a little bit higher." The band is in the flow now, so "under it" needs
   no arithmetic and the two can no longer drift apart at all. */
body.k9-preview.my-door .door-page {
  margin: 0 auto; padding-top: 10px; padding-bottom: 16px;
}
body.k9-preview.my-door .door-logo { max-height: 52px; }
body.k9-preview.my-door .door-brand { margin: 0 0 10px; }
body.k9-preview.my-door .door-brand h1 { margin-top: 4px; font-size: 21px; }

body.k9-preview .door-brand { text-align: center; margin-bottom: 22px; }
body.k9-preview .door-logo { max-height: 96px; max-width: 100%; }
body.k9-preview .door-mark { font-size: 44px; line-height: 1; }
body.k9-preview .door-brand h1 { margin: 10px 0 0; font-size: 26px; }

body.k9-preview .door-card { margin-bottom: 16px; }
body.k9-preview .door-card .field { margin-bottom: 14px; }
body.k9-preview .door-card label {
  display: block; margin-bottom: 5px; font-size: 13px; color: var(--pk-2);
}
/* ⚠️ EVERY TYPE THE DOORS ACTUALLY USE, and it is a list because CSS cannot
   ask. It was email and password only until Sep 6, when the second door
   arrived with names and a phone number -- and those three boxes rendered
   stark white on the dark card, because an unlisted type gets the browser's
   own styling and nothing else.

   The suite could not see it: every test asserted the fields were THERE, and
   they were. It was found by rendering the live page and looking at it, which
   is the standing rule for anything about how something looks.

   `NoUnstyledBoxOnADoor` now walks both door forms and fails if a widget
   renders a type this rule does not name. */
body.k9-preview .door-card input[type="email"],
body.k9-preview .door-card input[type="password"],
body.k9-preview .door-card input[type="text"],
body.k9-preview .door-card input[type="tel"] {
  width: 100%; padding: 10px 12px; font: inherit;
  border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); color: var(--pk);
}
body.k9-preview .door-go {
  width: 100%; padding: 11px 14px; font: inherit; font-weight: 600;
  border: 0; border-radius: 8px; cursor: pointer;
  background: var(--accent); color: #fff;
}
body.k9-preview .door-go:hover { filter: brightness(1.08); }

/* The second door's button on the sign-in page. Same shape, less shout --
   it is an alternative, not the thing most people came here to press. */
body.k9-preview .door-go-quiet {
  display: block; text-align: center; text-decoration: none;
  margin-top: 4px; background: transparent; color: var(--accent);
  border: 1px solid var(--accent);
}

/* ⛔ THE FIELD NOBODY SEES, AND WHY IT IS NOT display:none.
   Some robots skip a hidden input and fill one that is merely moved away, so
   this is positioned off the page instead. aria-hidden and tabindex keep it
   away from a screen reader and from anybody working by keyboard, which is
   the difference between a trap for robots and an obstacle for people. */
body.k9-preview .door-card input[name="website"] {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

/* A REFUSAL IS NOT FINE PRINT. The whole reason this page exists is that
   KennelBooker put the useful sentence in "really, really small letters". */
body.k9-preview .door-problem {
  margin: 10px 0 0; padding: 10px 12px; border-radius: 8px;
  font-size: 14px; line-height: 1.45;
  background: var(--red-soft); color: var(--red);
  border: 1px solid var(--red-line);
}
body.k9-preview .door-quiet { opacity: 0.92; }

/* THE WASH OVER THE PHOTOGRAPH. Sep 5, 2026; moved inside the band Sep 6.

   Jenn asked for a picture behind the sign-in page "so it isn't so plain",
   and her own dogs are black Labradors -- her instinct was to lighten the
   photographs themselves: "the pictures would have to be lightened a whole
   bunch." That bakes a choice into the files and cannot be taken back without
   re-editing every one of them.

   ⭐ SO THE WASH IS A LAYER AND NEVER AN EDIT. The file on disk is untouched,
   this value can be tuned in a second, and dark mode reverses over the SAME
   picture rather than needing a second set. It is its own element sitting on
   top of the image -- never a filter on the image -- so either can change
   without the other.

   It moved from the page to the band because the picture did. Same layer,
   same file, same value; it just belongs to the photograph now, which means
   it can never be a different height from the thing it is washing. */
body.k9-preview.my-door .door-band::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(19, 23, 26, 0.28);
}




/* The cards lift off the photograph rather than floating on it. */
body.k9-preview.my-door .door-card { box-shadow: 0 2px 14px rgba(0,0,0,.10); }

/* The facility's copyright, on every client page. Quiet, and readable over
   the photograph on the sign-in door as well as over a plain page. */
body.k9-preview .my-footer {
  padding: 18px 20px 26px; text-align: center;
  font-size: 12.5px; color: var(--pk-3);
}
body.k9-preview.my-door .my-footer { padding: 6px 20px 18px; }


/* ---------------------------------------------------------------------
   REQUEST SENT. Sep 6, 2026.

   ⭐ THE ANSWER HAS TO BE UNMISSABLE, and the reason is operational rather
   than decorative. Jenn, watching a client hit Send on a form that refused
   silently: "if I was anybody else, I'd be like, well, fuck. It didn't work.
   And I'd hit that send request about ten times." Ten presses is ten requests
   for somebody to sort out at the other end.
   --------------------------------------------------------------------- */
body.k9-preview .sent-card { text-align: center; }
body.k9-preview .sent-tick {
  width: 56px; height: 56px; margin: 4px auto 0;
  border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid var(--accent);
  font-size: 30px; line-height: 54px;
}
body.k9-preview .sent-card .door-go { margin-top: 16px; }


/* ---------------------------------------------------------------------
   ONE PRESS IS ONE REQUEST. Sep 6, 2026.

   The confirmation page above answers a client who waited. This answers the
   one who did not: between the press and the new page there was nothing at
   all, so the button still looked pressable and a slow connection turned one
   request into several. A pressed button must stop looking like a button.
   --------------------------------------------------------------------- */
body.k9-preview button[disabled],
body.k9-preview input[type="submit"][disabled] {
  opacity: 0.55;
  cursor: default;
  filter: none;
}
body.k9-preview .door-go[disabled]:hover { filter: none; }


/* ---------------------------------------------------------------------
   THE BOOKINGS PAGE. Sep 6, 2026.

   ⭐ Jenn asked for this page in this stylesheet by name -- "I want our style
   sheet" -- with the layout taken from the KennelBooker page she sent as a
   reference and nothing else taken from it. Her standing rule, Sep 4: "I
   don't give a hoot on how they did it ... what I want you to look at is the
   container that everything sits in and how it's laid out."
   --------------------------------------------------------------------- */
body.k9-preview .page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 0 0 14px;
}
body.k9-preview .page-head h1 {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 700;
  font-size: 34px; line-height: 1; letter-spacing: -.01em; margin: 0;
  color: var(--pk);
}
body.k9-preview .page-head-sub {
  font-family: "Barlow Semi Condensed", sans-serif; text-transform: uppercase;
  letter-spacing: .07em; font-size: 12.5px; color: var(--pk-3);
  margin: 6px 0 0;
}

/* ---- the kind tabs. Links, because each one is its own query ---- */
body.k9-preview .kind-tabs {
  display: flex; flex-wrap: wrap; gap: 0;
  border-bottom: 1px solid var(--line); background: var(--surface-2);
}
body.k9-preview .kind-tab {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 13.5px; letter-spacing: .05em; text-transform: uppercase;
  padding: 11px 15px; color: var(--pk-2); text-decoration: none;
  border-right: 1px solid var(--line);
}
body.k9-preview .kind-tab:hover { color: var(--pk); }
body.k9-preview .kind-tab.on {
  background: var(--surface); color: var(--pk);
  box-shadow: inset 0 2px 0 var(--accent);
}

/* ---- and the second strip: which of them, not which kind ---- */
body.k9-preview .view-strip {
  display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 0 14px;
}
body.k9-preview .view-pill {
  font-size: 13px; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--pk-2);
  text-decoration: none; background: var(--surface);
}
body.k9-preview .view-pill:hover { border-color: var(--accent); color: var(--pk); }
body.k9-preview .view-pill.on {
  background: var(--accent); border-color: var(--accent); color: #fff;
}

/* ---- the rows ---- */
body.k9-preview .booking-rows td { vertical-align: top; }
body.k9-preview .booking-row { cursor: pointer; }
body.k9-preview .booking-row:hover { background: var(--surface-2); }
body.k9-preview .booking-rows .num { text-align: right; white-space: nowrap; }
body.k9-preview .booking-rows .who a { font-weight: 600; }
body.k9-preview .booking-rows .when-time { color: var(--pk-3); font-size: 12.5px; }
body.k9-preview .booking-rows .due { color: var(--pk-2); }

body.k9-preview .dogs-count {
  font-family: "Barlow Semi Condensed", sans-serif; text-transform: uppercase;
  letter-spacing: .06em; font-size: 12px; color: var(--pk-3); margin-bottom: 5px;
}

/* ⭐ ONE GRID, SO THE COLUMNS LINE UP DOWN THE PAGE. Sep 3, 2026, and the
   reason is hers: "The names all need to start from a left justified. The
   canines all need to be from a left justified ... otherwise, my OCD is gonna
   kill me because they're not lined up." Ragged, you have to read every line;
   aligned, you can run your eye down it and check six dogs are in six runs. */
body.k9-preview .dog-row {
  display: grid;
  grid-template-columns: 4px 26px minmax(0, max-content) minmax(0, 1fr)
                         minmax(0, max-content) auto;
  align-items: center; gap: 0 9px; padding: 2px 0;
}
body.k9-preview .dog-row .dog-line-room {
  font-family: "IBM Plex Mono", monospace;
  color: var(--pk-2); font-size: 12px; white-space: nowrap;
}
/* The bar is the dog's temperament color and the color arrives inline,
   because what each of the ten means is the facility's to write down. */
body.k9-preview .temp-bar {
  width: 4px; align-self: stretch; min-height: 20px; border-radius: 2px;
}
body.k9-preview .temp-bar.untinted { background: var(--line-2); }
body.k9-preview .dog-row .dog-photo img {
  width: 26px; height: 26px; border-radius: 50%; object-fit: cover;
  display: block; border: 1px solid var(--line);
}
body.k9-preview .dog-row .pet-chip-noimg {
  width: 26px; height: 26px; border-radius: 50%; display: block;
  background: var(--surface-2); border: 1px solid var(--line);
  text-align: center; line-height: 24px; font-size: 13px;
}
body.k9-preview .dog-row .dog-name { font-weight: 600; }
body.k9-preview .dog-row .dog-line-breed {
  color: var(--pk-3); font-size: 13px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
body.k9-preview .dog-row .dog-codes { display: flex; gap: 5px; align-items: center; }

body.k9-preview .rows-note { margin: 12px 0 2px; }

@media (max-width: 800px) {
  body.k9-preview .dog-row { grid-template-columns: 4px 26px 1fr auto auto; }
  body.k9-preview .dog-row .dog-line-breed { display: none; }
}


/* ---- what a search turns up, when it is not one thing ---- */
body.k9-preview .found-rows tr { cursor: pointer; }
body.k9-preview .found-rows tr:hover { background: var(--surface-2); }
body.k9-preview .found-rows a { font-weight: 600; }
body.k9-preview .put-away {
  font-family: "Barlow Semi Condensed", sans-serif; text-transform: uppercase;
  letter-spacing: .06em; font-size: 11px; color: var(--pk-3);
  border: 1px solid var(--line-2); border-radius: 3px; padding: 1px 5px;
  margin-left: 6px;
}


/* =========================================================================
   ⭐⭐ THE PAINT LAYER — Sep 6, 2026.

   Jenn, on the pages staff open every morning: "we need to get it in our
   style sheet or at least our colors and stuff." And on the calendar
   specifically: "you've already worked the calendar exactly how I want it. It
   really doesn't need to change other than the colors."

   ⭐ A PAINT JOB IS NOT A REDESIGN, and this block is what makes that true.
   The old look is drawn with app.css's variable names -- --ink, --muted,
   --bg, --card, --border, --warn-bg. The new look defines its own -- --pk,
   --pk-3, --ground, --surface, --line, --amber-soft -- and never touched the
   old ones. So a page that got the new shell kept app.css's LIGHT values on
   the new dark ground: black text on a black card, which is exactly the
   failure Jenn named on the very first preview -- "a dark record under a blue
   bar is two products stitched together."

   ⭐ SO THE OLD NAMES ARE POINTED AT THE NEW PALETTE, once, here. A page joins
   the design language by adding two lines -- the body class and the head
   include -- and every card, border, muted line and warning box on it follows
   the theme, in light and dark, without touching its markup.

   ⚠️ THIS IS A BRIDGE, NOT A DESTINATION. A page that has been properly
   redrawn uses the new names directly and needs none of this. What it buys is
   that a page nobody has redrawn yet stops looking like a different product
   the moment it is asked to.
   ========================================================================= */
body.k9-preview {
  --ink: var(--pk);
  --muted: var(--pk-3);
  --bg: var(--ground);
  --card: var(--surface);
  --border: var(--line);
  --warn-bg: var(--amber-soft);
  --warn-text: var(--amber);
  /* The brand family. The bar keeps its own treatment; everything else that
     reached for green now reaches for the accent, which is theme-aware. */
  --green-dark: var(--accent);
  --green: var(--accent);
  --green-light: var(--accent-soft);
  --on-brand: #fff;
}

/* ===========================================================================
   ⭐⭐ THE BOARD — 06 Sep 2026. The dashboard, redrawn from the sandbox Jenn
   worked through card by card: "I really like this sandbox design."

   Everything here is scoped to `.board`, which only the preview dashboard
   draws, so the live board staff open at seven in the morning is untouched
   until she says to swap it.

   THE BRIEF, in her words: "when I'm talking about the style sheet, yes, I'm
   talking about the colors and everybody being able to change their colors
   from light to dark. But I'm talking about the cards and the boxes. I really
   like that look. It keeps it so clean."
   =========================================================================== */
body.k9-preview .board {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px; align-items: start;
}
/* A card carrying a table takes the whole width. Half a column is not enough
   for nine columns of booking, and a table that has to scroll sideways to
   show the money is the defect the bookings page was fixed for. */
body.k9-preview .board > .wide { grid-column: 1 / -1; }
@media (max-width: 900px) {
  body.k9-preview .board { grid-template-columns: 1fr; }
}

/* Two cards, one cell. Staged stacks directly beneath Quick Checkin instead
   of spanning the page — Jenn: "they both have their own cards." */
body.k9-preview .cell {
  display: flex; flex-direction: column; gap: 14px; min-width: 0;
}

body.k9-preview .board .card {
  margin: 0; padding: 14px 16px; border-radius: 0;
}
body.k9-preview .board .card > h3 {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 13px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--pk-2); margin: -14px -16px 14px; padding: 12px 16px;
  background: var(--surface-2); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
body.k9-preview .board .card > h3 .n {
  font-family: "IBM Plex Mono", monospace; font-size: 12px;
  letter-spacing: 0; color: var(--pk-3); font-variant-numeric: tabular-nums;
}
/* Amber, not red: a request waiting and a dog staged are both somebody's
   turn to act, and neither one is a fault. */
body.k9-preview .board .card.attn { border-color: var(--amber); }
body.k9-preview .board .card.attn > h3 {
  background: var(--amber-soft); color: var(--amber);
  border-bottom-color: var(--amber);
}
body.k9-preview .board .card.attn > h3 .n { color: var(--amber); }

/* Things that run to the card's own edges: the tile grids, and any table
   that is a direct child of the card. */
body.k9-preview .board .card > .occ,
body.k9-preview .board .card > .tiles-top,
body.k9-preview .board .card > .slot-cards,
body.k9-preview .board .card > .table-scroll { margin-left: -16px; margin-right: -16px; }
body.k9-preview .board .card > .occ,
body.k9-preview .board .card > .slot-cards { margin-bottom: -14px; }
body.k9-preview .board .card > .tiles-top { margin-bottom: 14px; }

/* ---- the tiles. One headline, then the kinds in rows of three ---- */
body.k9-preview .occ { display: grid; gap: 1px; background: var(--line); }
body.k9-preview .occ-rows { display: grid; gap: 1px; background: var(--line); }
body.k9-preview .occ-rows.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
body.k9-preview .tile { background: var(--surface); padding: 12px 14px; }
body.k9-preview .tile .v {
  font-family: "IBM Plex Mono", monospace; font-size: 23px; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--pk);
}
body.k9-preview .tile .k {
  font-family: "Barlow Semi Condensed", sans-serif; text-transform: uppercase;
  letter-spacing: .07em; font-size: 10.5px; color: var(--pk-3); margin-top: 5px;
}
body.k9-preview .tile.lead .v { color: var(--accent); font-size: 29px; }
/* ⭐ THE WAITLIST NUMBER IS THE LARGEST THING ON THE CARD. Jenn: "we need to
   have some place where we have the word waitlisted and a large number in it,
   so that it's staring at your face every time you open the dashboard." */
body.k9-preview .tile.hot { background: var(--amber-soft); }
body.k9-preview .tile.hot .v { color: var(--amber); font-size: 34px; }
body.k9-preview .tile.hot .k { color: var(--amber); }

/* ---- feeding and medications: a box per dog, edge to edge ---- */
body.k9-preview .board .slot-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 1px; background: var(--line);
}
body.k9-preview .board .slot-card {
  border: 0; border-radius: 0; background: var(--surface); padding: 11px 14px 13px;
}
body.k9-preview .board .slot-card-room {
  border-radius: 0; border-color: var(--line-2); color: var(--pk-3);
  font-family: "IBM Plex Mono", monospace; font-size: 11.5px;
}
body.k9-preview .board .slot-card-slots .slot { border-top-color: var(--line-2); }

/* ---- which way the dog is going ---- */
body.k9-preview .dir { font-size: 15px; line-height: 1; font-weight: 600; }
body.k9-preview .dir.up { color: var(--ok); }
body.k9-preview .dir.down { color: var(--red); }
body.k9-preview .dir.same,
body.k9-preview .dir.none { color: var(--pk-3); }

/* ---- the find bar, on the head rather than under it ---- */
body.k9-preview .page-head .find-bar {
  display: flex; gap: 8px; align-items: center; margin: 0;
  flex: 1 1 240px; max-width: 360px;
}
body.k9-preview .page-head .find-bar input[type="search"] {
  flex: 1; min-width: 0; padding: 8px 12px; font: inherit; font-size: 14px;
  border: 1px solid var(--line-2); border-radius: 0;
  background: var(--surface); color: var(--pk);
}

/* The weighing header — date, occasion, who held the scale — laid out as a
   row that wraps rather than three stacked fields. Sep 6, 2026: Weights sits
   beside Medications now, so the room it does not need is room the card does
   not take. */
body.k9-preview .board .card > form > .inline {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
}
body.k9-preview .board .card > form > .inline .field { flex: 1 1 120px; min-width: 0; }
body.k9-preview .board .card > form > .inline .field select,
body.k9-preview .board .card > form > .inline .field input { width: 100%; }

/* ---------------------------------------------------------------------------
   ⭐ THE WAITING ROOM — 06 Sep 2026. Waitlisted requests, above Pending on the
   bookings page, drawn deliberately UNLIKE the table beneath them.

   Jenn: "it sits under pending as a request. It does not convert until a
   booking unless we convert it." A row in that table is a booking and holds a
   run; nothing here does. If the two ever look alike, somebody will read one
   as the other on a busy morning — so this is a list of asks, not rows.
   --------------------------------------------------------------------------- */
body.k9-preview .waiting-room {
  border: 1px solid var(--amber); background: var(--amber-soft);
  margin: 0 0 16px;
}
body.k9-preview .waiting-room-head {
  font-family: "Barlow Semi Condensed", sans-serif; font-weight: 600;
  font-size: 12.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--amber); margin: 0; padding: 10px 14px;
  border-bottom: 1px solid var(--amber);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
body.k9-preview .waiting-room-head .n {
  font-family: "IBM Plex Mono", monospace; font-size: 12px; letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
body.k9-preview .waiting-ask { padding: 11px 14px; border-top: 1px solid var(--note-line); }
body.k9-preview .waiting-ask:first-of-type { border-top: 0; }
body.k9-preview .waiting-who {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px;
}
body.k9-preview .waiting-who a { font-weight: 600; }
body.k9-preview .waiting-when {
  font-family: "IBM Plex Mono", monospace; font-size: 13px; color: var(--pk-2);
  font-variant-numeric: tabular-nums;
}
body.k9-preview .waiting-dogs { font-size: 13.5px; color: var(--pk-2); }
body.k9-preview .waiting-said { font-size: 13.5px; color: var(--pk-2); margin-top: 3px; }
body.k9-preview .waiting-doors {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 8px;
}
body.k9-preview .waiting-doors form { margin: 0; }
body.k9-preview .waiting-doors details > summary {
  cursor: pointer; font-size: 13px; color: var(--pk-2); list-style: none;
}
body.k9-preview .waiting-doors details > summary::-webkit-details-marker { display: none; }
body.k9-preview .waiting-doors details > summary::before { content: "\25B8 "; }
body.k9-preview .waiting-doors details[open] > summary::before { content: "\25BE "; }
body.k9-preview .waiting-doors details form {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 7px;
}
body.k9-preview .waiting-doors details input[type="text"] {
  min-width: 240px; padding: 6px 10px; font: inherit; font-size: 14px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--pk);
}
body.k9-preview .waiting-room .rows-note { margin: 0; padding: 0 14px 12px; }
