/*
 * Missing-utility patch for the prebuilt bundle.
 *
 * public/css/app.css is NOT compiled from this project's markup — it is a fixed
 * bundle produced from a snapshot of the views. Any class added to a Blade file
 * afterwards is simply absent, and an absent utility fails SILENTLY: no error,
 * no warning, the element just renders wrong. That is how the proposal form
 * ended up one-fifth of its intended width (md:col-span-3 was never in there).
 *
 * Everything below was found by auditing all 150 Blade files against the bundle
 * and verifying each class was genuinely missing. Values follow Tailwind's
 * default scale (1 unit = 0.25rem) so they behave exactly as the markup expects.
 *
 * Loaded AFTER app.css. If the bundle is ever rebuilt from current markup, this
 * file becomes redundant — check before deleting it.
 */

/* ── Klokee floating launcher ─────────────────────────────────────────────────
 * Written out in full rather than composed from utilities: this element is
 * rendered on every authenticated page, so a silently-missing class here would
 * misplace it app-wide rather than on one screen.
 *
 * z-40 puts it above the mobile bottom bar (z-35) and below dialogs (z-50) — it
 * must never cover the form someone is trying to fill in.
 *
 * Sizes are in px, not vh: the desktop shell sets body{zoom:0.85}, so viewport
 * units here would render at 85% of whatever they claim.
 */
.klokee-dock {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  max-width: calc(100vw - 2.5rem);
}
.klokee-panel {
  width: 520px;
  max-width: calc(100vw - 2.5rem);
  height: 560px;
  max-height: calc(100vh - 7rem);
}

/* Chat bubble widths. These were written as arbitrary Tailwind values
 * (max-w-[70%], max-w-[85%]) which the prebuilt bundle does not contain, so the
 * bubbles had no cap at all and Klokee's longer answers ran off the right edge.
 * overflow-wrap is belt and braces: a pasted URL or a long unbroken number
 * would otherwise push the bubble out regardless of the max-width.
 */
.max-w-\[70\%\] { max-width: 70%; }
.max-w-\[85\%\] { max-width: 85%; }
.chat-bubble, .klokee-panel .whitespace-pre-line { overflow-wrap: anywhere; }
/* ── AI routing rows (Super Admin → Settings → Keys) ──────────────────────────
 * One job per row, read left to right: what it is, who does it, which model,
 * what happens if that fails. The job column is fixed so the three controls
 * line up down the page — with equal fractions the descriptions pushed each
 * row's selects to a different place and the table stopped reading as a table.
 *
 * Stacks below 1024px, where four columns would be unreadable anyway. The
 * heading row hides there too: on a stacked layout the labels belong to
 * nothing, and each control is self-describing.
 */
/* ── Super Admin → Settings → Keys ────────────────────────────────────────────
 * One column of full-width cards, not two.
 *
 * The tab used to be a two-column grid with a hand-tuned `order:N` on each card
 * to balance the columns. Cards of very different heights (a one-field Geo key
 * beside a fifteen-field payments block) left half a screen of white space, and
 * every card then stacked its own fields down a half-width column — so a form
 * that fits on one screen ran to five. Full width plus fields laid across uses
 * the room the screen already has.
 */
.keys-stack { display: grid; grid-template-columns: 1fr; gap: 1rem; }

/* Field rows inside a card. All collapse to one column on narrow screens,
 * where side-by-side inputs are unreadable rather than compact. */
.kf-2, .kf-3, .kf-4 { display: grid; grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .kf-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kf-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .kf-4 { grid-template-columns: 180px repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .kf-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Full width inside the two-column keys tab. Named rather than lg:col-span-2,
 * which cannot be verified against the prebuilt bundle — and a missing utility
 * here would silently put four columns back into a half-width card. */
.ai-route-card { grid-column: 1 / -1; }

.ai-route-row { display: grid; grid-template-columns: 1fr; }
.ai-route-head { display: none; }
@media (min-width: 1024px) {
  .ai-route-row { grid-template-columns: 260px 1fr 1.15fr 1fr; }
  .ai-route-head { display: grid; }
}

/* Klokee's mark, unboxed: the robot IS the button, with its name above its
 * head. No pill, because a container drawn around an already-distinct mark is
 * furniture. Named classes rather than arbitrary text-[40px] values, which the
 * prebuilt bundle would not contain.
 *
 * The drop-shadow is what keeps it legible: with no filled background behind
 * it, the glyph has to hold up over a white card, a grey page and a table row
 * alike. line-height 1 stops the tall glyph adding dead space under the icon.
 */
.klokee-fab-icon {
  font-size: 40px;
  line-height: 1;
  filter: drop-shadow(0 2px 4px rgba(15, 118, 110, .28));
}
.klokee-fab-label {
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1;
  margin-bottom: 2px;
  letter-spacing: .01em;
  /* Sits over page content, so it carries its own backing rather than
     relying on whatever happens to be underneath. */
  background: rgba(255, 255, 255, .92);
  border-radius: 9999px;
  padding: 3px 8px;
  box-shadow: 0 1px 3px rgba(16, 24, 40, .12);
  white-space: nowrap;
}
.klokee-fab { transition: transform .12s ease; }
.klokee-fab:hover { transform: translateY(-1px); }

@media (max-width: 1023px) {
  /* Clear the bottom app bar and the Punch button that overhangs it. */
  .klokee-dock { bottom: 5.25rem; right: 1rem; }
  .klokee-panel { height: 420px; max-height: calc(100vh - 12rem); }
}

/* ── document review rows ─────────────────────────────────────────────────────
 * Named rather than composed from grid-cols-* utilities, because the widths are
 * not equal fractions: the date columns only ever hold a date picker, and giving
 * them a fifth of the row each starves the document title. Stacks on small
 * screens, which is where a phone camera upload lands.
 */
.doc-row-4, .doc-row-5 { grid-template-columns: 1fr; }
@media (min-width: 640px) {
  .doc-row-5 { grid-template-columns: 1fr 1.4fr 1fr 150px 150px; }
  .doc-row-4 { grid-template-columns: 1.4fr 1fr 150px 150px; }
}

/* ── position ─────────────────────────────────────────────────────────────── */
.left-0   { left: 0; }
.top-full { top: 100%; }          /* blog dropdown sat over its trigger without this */

/* ── sizing ───────────────────────────────────────────────────────────────── */
.w-auto    { width: auto; }
.max-w-7xl { max-width: 80rem; }
.max-h-44  { max-height: 11rem; }  /* keeps the long checkbox list scrollable */
.max-h-52  { max-height: 13rem; }
.h-14\.5   { height: 3.625rem; }

/* ── spacing ──────────────────────────────────────────────────────────────── */
.py-9  { padding-top: 2.25rem; padding-bottom: 2.25rem; }
.py-11 { padding-top: 2.75rem; padding-bottom: 2.75rem; }
.pt-9  { padding-top: 2.25rem; }
.pt-12 { padding-top: 3rem; }
.pb-9  { padding-bottom: 2.25rem; }
.mt-7  { margin-top: 1.75rem; }
.my-6  { margin-top: 1.5rem; margin-bottom: 1.5rem; }
.mt-px { margin-top: 1px; }

/* ── responsive ───────────────────────────────────────────────────────────── */
@media (min-width: 640px) {
    .sm\:flex-row { flex-direction: row; }
    .sm\:p-4      { padding: 1rem; }
    .sm\:p-5      { padding: 1.25rem; }
    .sm\:px-9     { padding-left: 2.25rem; padding-right: 2.25rem; }
    .sm\:px-10    { padding-left: 2.5rem; padding-right: 2.5rem; }
    .sm\:py-6     { padding-top: 1.5rem; padding-bottom: 1.5rem; }
    .sm\:py-8     { padding-top: 2rem; padding-bottom: 2rem; }
    .sm\:py-10    { padding-top: 2.5rem; padding-bottom: 2.5rem; }
    .sm\:w-14     { width: 3.5rem; }
}

@media (min-width: 1280px) {
    .xl\:w-52 { width: 13rem; }
}


/* Punch screen — the prebuilt bundle has no border-4 or transform variants,
   and a missing utility fails silently, so the check-out ring disappeared. */
.border-4 { border-width: 4px; }
.active\:scale-95:active { transform: scale(.95); }
.group:hover .group-hover\:scale-105 { transform: scale(1.05); }
.punch-shadow { box-shadow: 0 10px 30px -8px rgba(15,118,110,.55); }
.punch-shadow-soft { box-shadow: 0 10px 30px -12px rgba(15,118,110,.45); }

/* Month calendar grid */
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal-cell { border: 1px solid #eef2f1; border-radius: 10px; padding: 6px 8px; min-height: 62px; }

/* Filled dark check-out button. The outlined ring it replaced read as a
   disabled control — on a screen whose whole job is one action, the action
   must look pressable. */
.punch-shadow-dark { box-shadow: 0 10px 30px -8px rgba(17,24,39,.45); }

/* ── Modal sheets ──────────────────────────────────────────────────────
   Dialogs were capped at 85–88vh, but the desktop shell sets body{zoom:.85},
   so a vh height renders at 85% of what it claims — an "88vh" dialog filled
   about three quarters of the screen and every long form scrolled inside it.
   Same compensation the app shell already uses. Mobile has no zoom, so the
   plain value is correct there. */
.modal-sheet { max-height: 92vh; overflow-y: auto; }
@media (min-width: 1024px) { .modal-sheet { max-height: calc(92vh / 0.85); } }

/* Header/tabs/footer pinned, body scrolls — so on a five-tab form the tab bar
   and the Save button cannot scroll out of reach while you fill the last tab.
   The shell owns the height; the body just takes what is left, which means no
   second magic number to keep in sync with the header's size. */
.modal-shell { display: flex; flex-direction: column; max-height: 92vh; overflow: hidden; }
@media (min-width: 1024px) { .modal-shell { max-height: calc(92vh / 0.85); } }
.modal-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

/* Employee form pill tabs — two utilities the prebuilt bundle lacks.
   brand-200 derived between brand-50 (245 250 249) and brand (12 104 95). */
.border-brand-200 { border-color: rgb(178 214 209); }
.gap-1\.5 { gap: 0.375rem; }
.pe-8 { padding-inline-end: 2rem; }
.py-2\.5 { padding-top: 0.625rem; padding-bottom: 0.625rem; }
.px-2\.5 { padding-left: 0.625rem; padding-right: 0.625rem; }
/* Drawer header: action buttons take their own full row on phones. */
@media (min-width: 640px) {
  .sm\:w-auto { width: auto; }
  .sm\:flex-none { flex: none; }
}
.p-0\.5 { padding: 0.125rem; }

/* Candidate-panel colour pass (2026-07-31): stage chips and timeline dots.
   Values are Tailwind's own slate/violet/sky, verified absent from app.css. */
.bg-slate-100{background-color:#f1f5f9}
.text-slate-700{color:#334155}
.bg-violet-500{background-color:#8b5cf6}
.bg-sky-400{background-color:#38bdf8}
.hover\:bg-white\/20:hover{background-color:rgb(255 255 255/.2)}

/* Form focus ring (2026-07-31). Tailwind's ring utilities are absent from the
   prebuilt bundle, so box-shadow is written directly — an invisible focus
   state is an accessibility problem, not a cosmetic one. */
.focus\:ring-2:focus{box-shadow:0 0 0 2px var(--tw-ring-color,rgb(15 118 110/.15))}
.focus\:ring-brand\/15:focus{--tw-ring-color:rgb(15 118 110/.15)}
.max-w-\[170px\]{max-width:170px}
@media (min-width:640px){.sm\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}}
@media (min-width:640px){.sm\:col-span-1{grid-column:span 1/span 1}}
@media (min-width:640px){.sm\:w-2\/3{width:66.666667%}}
.hover\:bg-emerald-700:hover{background-color:#047857}
.border-sky-200{border-color:#bae6fd}
.text-sky-800{color:#075985}
.break-words{overflow-wrap:break-word}
.text-red-800{color:#991b1b}
.text-\[44px\]{font-size:44px}
.text-\[14\.5px\]{font-size:14.5px}
.text-\[13\.5px\]{font-size:13.5px}
.space-y-1\.5>:not([hidden])~:not([hidden]){margin-top:.375rem}
.bg-red-500\/25{background-color:rgba(239,68,68,.25)}
.border-red-300\/40{border-color:rgba(252,165,165,.4)}

/* CRM pipeline — gaps the prebuilt bundle never emitted. */
.text-left{text-align:left}
.my-5{margin-top:1.25rem;margin-bottom:1.25rem}
.my-10{margin-top:2.5rem;margin-bottom:2.5rem}
.-mt-1{margin-top:-0.25rem}
.-mt-2{margin-top:-0.5rem}
.bg-black\/10{background-color:rgba(0,0,0,.1)}
.border-white{border-color:#fff}
.\[\&\>svg\]\:w-full>svg{width:100%}
.\[\&\>svg\]\:h-auto>svg{height:auto}

/* Vendor kind block. */
.self-end{align-self:flex-end}

.min-w-\[560px\]{min-width:560px}

.max-h-48{max-height:12rem}

/* The six-digit code box. */
.tracking-\[0\.4em\]{letter-spacing:0.4em}

.first\:border-0:first-child{border-width:0}

.min-w-\[620px\]{min-width:620px}
.min-w-\[680px\]{min-width:680px}

/* Visually hidden, still read aloud. Its absence is why the attendance chart
   printed a status word under every icon. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}

/* Alpine hides these until it has initialised. Nothing shipped the rule. */
[x-cloak]{display:none !important}

/* A paging arrow at the end of a list is not clickable, and should not look it. */
.disabled\:opacity-40:disabled{opacity:0.4}
.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}

/* Added for the front-desk dashboard. Tailwind is not rebuilt on this host,
   so a class that is not compiled here simply does not exist at runtime. */
.items-baseline { align-items: baseline; }
.transition-colors {
    transition-property: color, background-color, border-color, fill, stroke;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-duration: 150ms;
}

/* Divider utilities for the dashboard overview card. Tailwind is not rebuilt
   on this host, so the lg: variants of divide-x / divide-y-0 were never
   compiled — the dividers would have rendered as nothing at all. */
@media (min-width: 1024px) {
    .lg\:divide-y-0 > :not([hidden]) ~ :not([hidden]) {
        border-top-width: 0;
        border-bottom-width: 0;
    }
    .lg\:divide-x > :not([hidden]) ~ :not([hidden]) {
        border-right-width: 0;
        border-left-width: 1px;
    }
}

/* Form Control: the field matrix is wider than any phone, so it scrolls
   inside its own container rather than pushing the page sideways. */
.min-w-\[900px\] { min-width: 900px; }
.w-\[240px\] { width: 240px; }

/* Two columns once there is room — the field list is 16 rows now. */
@media (min-width: 640px) { .sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ── The form sheet ──────────────────────────────────────────────────────
   Every dialog in the app already carries .modal-sheet, so the frame is
   defined once here instead of in twenty Blade files — and a form added
   next month gets it without anyone remembering to.

   The teal edge is the brand green; the header band is the palest tint of
   it, so the title reads as a header without turning the dialog into a
   coloured box. Tailwind is not rebuilt on this host, which is why this is
   plain CSS rather than utility classes. */
.modal-sheet {
    /* One even border. A 3px top against 1px sides mitres at the corner and
       leaves a pale wedge — and the dark band above needs no underline. */
    border: 1px solid #99f6e4;              /* teal-200 */
    box-shadow: 0 24px 50px -24px rgba(15, 118, 110, .45);
}

/* The band cancels the sheet's own p-5 to reach the edges, so it is only
   applied to sheets that HAVE that padding — an unpadded sheet keeps the
   frame and skips the band rather than tearing its own header off. The
   first child is either the heading itself or the row holding the heading
   and its close button; :has() picks out the second case, and a browser
   without it simply shows no band. */
.p-5.modal-sheet > :first-child:is(h2, h3, h4),
.p-5.modal-sheet > :first-child:has(> h2, > h3, > h4) {
    /* One pixel past the padding, to cover the sheet's own border — a
       hairline of white at the corners reads as a box that does not fit. */
    margin: calc(-1.25rem - 1px) calc(-1.25rem - 1px) 1.15rem;
    padding: .8rem 1.25rem;
    /* The brand green, not a tint of it: a dialog should announce itself
       across a room, and the gate PC is never looked at closely. */
    background: #0f766e;
    border-bottom: 1px solid #0f766e;
    color: #ffffff;
    /* One pixel wider than the sheet's own 1rem, because the band sits one
       pixel outside it — inherit left a hairline of white on the curve. */
    border-top-left-radius: 17px;
    border-top-right-radius: 17px;
}

/* Everything sitting in the band is on dark green now, whatever colour a
   utility class gave it for the white one. */
.p-5.modal-sheet > :first-child:is(h2, h3, h4),
.p-5.modal-sheet > :first-child:has(> h2, > h3, > h4) h2,
.p-5.modal-sheet > :first-child:has(> h2, > h3, > h4) h3,
.p-5.modal-sheet > :first-child:has(> h2, > h3, > h4) h4,
.p-5.modal-sheet > :first-child:has(> h2, > h3, > h4) button,
.p-5.modal-sheet > :first-child:has(> h2, > h3, > h4) p {
    color: #ffffff;
}

/* ── The one grid class the build never emitted ──────────────────────────
   Tailwind is not rebuilt on this host, so a class is only available if the
   fixed app.css already contains it. It has sm:grid-cols-4 and sm:col-span-2
   and -3, but not sm:col-span-4 — eight elements across the app ask for it,
   including the visitor's Address, which is why that field sat one column
   wide inside a four-column row while everything beside it lined up.

   Written the way the build writes it, so the day app.css is rebuilt this
   simply becomes a duplicate rather than a conflict. */
@media (min-width: 640px) {
    .sm\:col-span-4 { grid-column: span 4 / span 4; }
    .sm\:col-span-1 { grid-column: span 1 / span 1; }
}

/* ── The rest of the grid classes the build never emitted ────────────────
   Same story as sm:col-span-4. app.css carries grid-cols-1/2/3/5 and
   col-span-1/2/3 only, but the views ask for grid-cols-4, -6, -7, -12 and
   col-span-4 through -12.

   The material gate's item line is the visible casualty: it is a
   twelve-column row, so with grid-cols-12 missing it collapsed to one column
   and the pick, item, qty and unit each took a line of their own.

   Written exactly as Tailwind writes them, so a future rebuild of app.css
   makes these duplicates rather than conflicts. */
.grid-cols-4  { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-cols-6  { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid-cols-7  { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.grid-cols-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }

.col-span-4  { grid-column: span 4 / span 4; }
.col-span-5  { grid-column: span 5 / span 5; }
.col-span-6  { grid-column: span 6 / span 6; }
.col-span-7  { grid-column: span 7 / span 7; }
.col-span-8  { grid-column: span 8 / span 8; }
.col-span-12 { grid-column: span 12 / span 12; }

/* ── The rest of what the build never emitted ────────────────────────────
   Found by auditing every view against the compiled CSS. None of these
   announced themselves: an uncompiled class is silently nothing, which is
   how a truncation stops truncating and a seven-column calendar becomes one
   column. */
.max-w-\[10rem\] { max-width: 10rem; }
.max-w-\[16rem\] { max-width: 16rem; }
.min-w-\[15rem\] { min-width: 15rem; }
.min-w-\[180px\] { min-width: 180px; }
.min-w-\[200px\] { min-width: 200px; }
.min-w-\[220px\] { min-width: 220px; }
.min-w-\[240px\] { min-width: 240px; }
.min-w-\[280px\] { min-width: 280px; }
.min-w-\[960px\] { min-width: 960px; }

@media (min-width: 640px) {
    .sm\:max-w-md { max-width: 28rem; }
    .sm\:grid-cols-\[auto\2c 1fr\] { grid-template-columns: auto 1fr; }
}
@media (min-width: 768px) {
    .md\:col-span-3 { grid-column: span 3 / span 3; }
}
@media (min-width: 1024px) {
    .lg\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .lg\:grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
    .lg\:grid-cols-\[280px_1fr\] { grid-template-columns: 280px 1fr; }
}

/* The GatePass designer's live preview column. Tailwind is not rebuilt on this
   host, so a class the build never emitted does nothing at all — these four are
   written by hand for that reason. */
.h-\[420px\] { height: 420px; }

@media (min-width: 1024px) {
    .lg\:grid-cols-\[1fr_320px\] { grid-template-columns: 1fr 320px; }
    .lg\:border-s { border-inline-start-width: 1px; border-inline-start-style: solid; }
    .lg\:ps-5 { padding-inline-start: 1.25rem; }
}

/* The GatePass designer: lines, controls, card. An even split gave the
   controls width they had no use for and the card less than it needed. */
.designer-grid { display: grid; gap: 1.25rem; }

@media (min-width: 1024px) {
    .designer-grid { grid-template-columns: minmax(0, 1fr) 250px 380px; }
}


/* ---------------------------------------------------------------
   lg: grid columns. app.css carries no lg:grid-cols-* at all, so any
   view asking for one silently kept the sm: column count — the pricing
   cards overlapped because of exactly this.
   --------------------------------------------------------------- */
@media (min-width: 1024px) {
  .lg\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .lg\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}


/* ---------------------------------------------------------------
   Horizontal centring for absolutely positioned badges. Neither of
   these is in app.css, so "absolute start-1/2 -translate-x-1/2" —
   the standard centre-on-the-edge recipe — placed the pricing page's
   MOST POPULAR badge at its card's left edge, overhanging the card
   before it.
   --------------------------------------------------------------- */
.start-1\/2 { inset-inline-start: 50%; }
.left-1\/2  { left: 50%; }
.-translate-x-1\/2 { transform: translateX(-50%); }

/* ---------------------------------------------------------------
   Filter utilities. app.css ships neither, so the footer's white-
   silhouette logo (brightness-0 invert) silently never applied and
   the coloured logo sat on the dark ground as-is.
   --------------------------------------------------------------- */
.brightness-0 { filter: brightness(0); }
.invert { filter: invert(1); }
.brightness-0.invert { filter: brightness(0) invert(1); }


/* ── A dialog that holds its own header and footer ───────────────────────
   .modal-sheet caps the height AND draws the frame, so a dialog wanting
   the frame outside and the scrolling inside carries it twice — and gets
   two scrollbars, one moving the sheet and one moving the fields.

   Adding .modal-frame beside it says: this panel is the frame, not the
   scroller. The child that still carries .modal-sheet does the scrolling
   and fills what is left, so the buttons stay with the form. */
.modal-sheet.modal-frame {
    display: flex;
    flex-direction: column;
    overflow: hidden;                 /* the frame itself never scrolls */
}

.modal-sheet.modal-frame > .modal-sheet {
    flex: 1 1 auto;
    min-height: 0;                    /* without this a flex child refuses to shrink */
    max-height: none;                 /* the frame already caps the height */
    border: 0;                        /* one frame, not two */
    box-shadow: none;
}

/* Used by five views; never in the shipped Tailwind build, so line breaks
   in a WhatsApp preview and a plain-text email ran together. */
.whitespace-pre-wrap { white-space: pre-wrap; }
.whitespace-pre-line { white-space: pre-line; }
