@charset "UTF-8";
/* 00: Runtime CSS variables first */
/* App chrome / layout knobs (runtime CSS variables) */
:root {
  /* Forms */
  --date-input-width: 12rem;
  /* Header */
  --app-header-height: 4rem;
  /* Main Content */
  --main-content-width-when-dock-open: 48vw;
  --main-content-width-when-dock-closed: 100%;
  /* Sales chrome */
  --sales-menu-width: 20vw;
  /* Dock sizing */
  --dock-transition-duration: 500ms;
  --dock-transition-ease: ease;
  --dock-width-closed: 48vw; /* when menu is CLOSED */
  --dock-width-open: 28vw; /* when menu is OPEN   */
  /* Computed offsets */
  --dock-offset-when-menu-open: calc(-1 * var(--sales-menu-width));
  /* Notification dock */
  --notif-dock-width: 28vw;
  /* Z-index scale (single source of truth) */
  --z-modal: 1200;
  --z-header: 1100;
  --z-menu: 1002;
  --z-dock: 1001;
}
@media (min-width: 1280px) {
  :root :root {
    --dock-width-closed: 48vw;
  }
}

:root {
  /* Brand swatches, straight from the guideline's Colors page */
  --color-forest-blue: #105151;
  --color-flora-green: #1c723b;
  --color-growth-green: #caf35b;
  --color-fir-cone-red-light: #d56856;
  --color-fir-cone-red-dark: #5d091f;
  --color-cream: #fff5e0;
  /* Core palette */
  --color-bg: #faf7ee;
  --color-bg-light: #fffdf7;
  --color-bg-dark: #ece5d3;
  --color-text-dark: #1f3d3d;
  --color-text-light: #ffffff;
  --color-text-faint: #527070;
  --color-border: #e3dccb;
  --color-primary: #105151;
  --color-primary-bright: #166b6b;
  --color-accent: #caf35b;
  --color-accent-light: rgb(215.25, 246, 132);
  --color-success: #1c723b;
  --color-warning: #ca8a04;
  --color-warning-light: #e5c786;
  --color-warning-deep: rgb(151.5, 103.5, 3);
  --color-danger: rgb(177, 75.5, 69.5);
  --color-danger-bright: #d56856;
  --color-danger-dark: #5d091f;
  --color-danger-light: rgb(240.3, 202.15, 195.85);
  --color-blue-highlight: #c6e2ff;
  --color-menu-bg: #0a5454;
  --color-menu-bg-light: rgb(19.7361702128, 165.7838297872, 165.7838297872);
  --color-menu-bg-trans: rgba(10, 84, 84, 0.97);
  /* Inputs */
  --input-bg: #fff;
  --input-border: #e3dccb;
  --input-focus-border: #105151;
  --input-focus-ring: rgba(16, 81, 81, 0.22);
  /* Buttons (mirror your semantic Sass tokens) */
  --btn-radius: 8px;
  --btn-primary-bg: #105151;
  --btn-primary-text: #ffffff;
  --btn-primary-border: #105151;
  --btn-primary-bg-hover: rgb(18.7249484536, 94.7950515464, 94.7950515464);
  --btn-primary-bg-hover-on-dark: #166b6b;
  --btn-secondary-bg: #fff;
  --btn-secondary-text: #1f3d3d;
  --btn-secondary-border: #e3dccb;
  --btn-secondary-bg-hover: #fffdf7;
}

html[data-theme=dark] {
  filter: invert(1) hue-rotate(180deg);
  background-color: #050811;
}
html[data-theme=dark] body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flow-root;
}
html[data-theme=dark] img,
html[data-theme=dark] video,
html[data-theme=dark] picture,
html[data-theme=dark] canvas,
html[data-theme=dark] iframe,
html[data-theme=dark] #Navbar,
html[data-theme=dark] #LeftMenu,
html[data-theme=dark] #SalesMenu {
  filter: invert(1) hue-rotate(180deg);
}
html[data-theme=dark] :is(#Navbar, #LeftMenu, #SalesMenu) :is(img, video, picture, canvas, iframe) {
  filter: none;
}

/* 01: Sass design tokens & mixins */
@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/work-sans-latin-1c0ad417.woff2") format("woff2");
}
@font-face {
  font-family: "Albert Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/albert-sans-latin-c08eb95b.woff2") format("woff2");
}
:root {
  --font-heading: "Work Sans", system-ui, sans-serif;
  --font-body: "Albert Sans", system-ui, sans-serif;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.Wordmark {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* 02: Global styles */
.flash {
  position: fixed;
  top: calc(var(--app-header-height) + 0.5rem);
  left: 50%;
  background-color: rgb(215.25, 246, 132);
  padding: 0.75rem 1.25rem;
  border-left: 4px solid #105151;
  border-radius: 4px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  z-index: 2000;
  opacity: 0;
  transform: translateX(-50%) translateY(-10px);
  transition: opacity 0.4s ease, transform 0.4s ease;
  pointer-events: none;
  animation: flashFade 5s ease-out forwards;
}

.notice--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* A refusal, in the two keys the app spells it with. Color only — the
   position, the fade and the spacing are the base `.flash`'s, which this used
   to fight with a stack of margins from before the banner was fixed. */
.flash--alert,
.flash--error {
  background-color: rgb(177, 75.5, 69.5);
  color: white;
  border-left-color: rgb(140.3793103448, 59.8793103448, 55.1206896552);
}

@keyframes flashFade {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(-10px);
  }
  10%, 90% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-10px);
  }
}
table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
}
table th, table td {
  border: 1px solid #e3dccb;
  padding: 0.5rem;
  text-align: left;
}
table th.description, table td.description {
  width: 70%;
}
table th {
  background-color: rgb(231.1, 237.6, 237.6);
  color: #1f3d3d;
  border-bottom: 2px solid rgba(16, 81, 81, 0.35);
}

.FlashedRow {
  animation: flashRowHighlight 1.5s ease-out;
}

@keyframes flashRowHighlight {
  0% {
    background-color: #c6e2ff;
  }
  100% {
    background-color: transparent;
  }
}
.field_with_errors input,
.field_with_errors select,
.field_with_errors textarea {
  border-color: rgb(177, 75.5, 69.5);
  background-color: rgb(240.3, 202.15, 195.85);
}

.field_with_errors input:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(176, 73, 73, 0.2);
}

.FieldErrorMessage {
  color: rgb(177, 75.5, 69.5);
  font-size: 0.9em;
  margin-top: 0.25rem;
}

/* ============================================
   ROW & COLUMN HIGHLIGHTING
   ============================================ */
/* CSS Variables — hover highlights use the Growth Green accent at low
   strength so tables tie into the brand instead of bootstrap amber/blue */
.HighlightRows,
.HighlightColumns {
  --row-highlight-color: rgb(239.1, 251.4, 205.8);
  --col-highlight-color: rgba(16, 81, 81, 0.1);
  --cell-highlight-color: rgb(223.2, 247.8, 156.6);
}

/* Row Highlighting */
.HighlightRows tbody tr:hover td:not(.NoHighlight),
.HighlightRows tbody tr:hover th:not(.NoHighlight) {
  background-color: var(--row-highlight-color) !important;
  cursor: pointer;
}

/* Column Highlighting */
.HighlightColumns td:not(.NoHighlight):hover::after,
.HighlightColumns th:not(.NoHighlight):hover::after {
  content: "";
  position: absolute;
  top: -5000px;
  left: 0;
  width: 100%;
  height: 10000px;
  background-color: var(--col-highlight-color);
  pointer-events: none;
  z-index: -1;
}

.HighlightColumns td:not(.NoHighlight),
.HighlightColumns th:not(.NoHighlight) {
  position: relative;
}

/* Cell Intersection (Both Row & Column) */
.HighlightRows.HighlightColumns tbody tr:hover td:not(.NoHighlight):hover {
  background-color: var(--cell-highlight-color) !important;
}

.TableActions {
  white-space: nowrap;
  text-align: right;
  width: 1%;
}

.DisabledAction {
  opacity: 0.35;
  cursor: not-allowed;
}

/* Locked Row Highlighting */
.HighlightRows tbody tr.LockedRow td:not(.NoHighlight),
.HighlightRows tbody tr.LockedRow th:not(.NoHighlight) {
  background-color: var(--row-highlight-color) !important;
}

.HighlightRows tbody tr.LockedRow {
  outline: 2px solid #ca8a04;
  outline-offset: -1px;
}

label {
  display: block;
  font-weight: bold;
}

/* Text-entry baseline. The button-ish input types are excluded, not just
   checkbox: this rule is 0,1,1, which outranks a component class like .Button
   (0,1,0), so a <input type="submit" class="Button"> was taking its fill and
   ink from here — white background, $text-dark text — and never looked primary
   at rest. Hover then made it unreadable, because .Button:hover (0,2,0) is
   specific enough to repaint the background while the text color stayed behind.
   Excluded via a :not() selector LIST rather than chained :not()s so the rule
   keeps its 0,1,1 specificity and the cascade for real text inputs is unchanged. */
input:not([type=checkbox], [type=radio], [type=submit], [type=button], [type=reset]), select, textarea {
  width: 100%;
  padding: 0.5rem;
  margin-top: 0.25rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  background: #fff;
  color: #1f3d3d;
  outline: none;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
input:not([type=checkbox], [type=radio], [type=submit], [type=button], [type=reset]):focus, select:focus, textarea:focus {
  border-color: #105151;
  box-shadow: 0 0 0 3px rgba(16, 81, 81, 0.22);
}

/* The field a refusal was about. The message itself goes to the flash — this is
   only the pointer back to where it landed, so it has to outrank the baseline
   above (0,1,1): hence the doubled class on the .FormControl selector. */
.FormControl.is-invalid,
input.is-invalid,
select.is-invalid,
textarea.is-invalid {
  border-color: rgb(177, 75.5, 69.5);
  background-color: rgb(240.3, 202.15, 195.85);
}
.FormControl.is-invalid:focus,
input.is-invalid:focus,
select.is-invalid:focus,
textarea.is-invalid:focus {
  border-color: rgb(177, 75.5, 69.5);
  box-shadow: 0 0 0 3px rgba(176, 73, 73, 0.2);
}

/* Fields you cannot type in.

   There was no baseline for this at all, so a disabled <select> or <input> got
   only the browser's own treatment — on a white field that is a barely visible
   shift of the text, and the locked Stock Type / Species selects on a saved sale
   line read as perfectly live controls that simply refused to open. State that
   cannot be changed has to look like it before it is clicked, not after.

   Placed after .is-invalid deliberately: the two can coincide (SaleItem's
   immutable-identity validation refuses a changed species, and that field is
   also the disabled one), and "you cannot edit this" is the more useful of the
   two facts — the red is what you get for editing it, and you can't.

   readonly rides along with disabled. It is a different mechanism (a readonly
   field still posts, which is why price-lock uses it) but the same promise to
   the reader, and the pair should never look like two different things. */
input:not([type=checkbox], [type=radio], [type=submit], [type=button], [type=reset]):disabled,
input:not([type=checkbox], [type=radio], [type=submit], [type=button], [type=reset])[readonly],
select:disabled,
textarea:disabled,
textarea[readonly] {
  background: rgba(82, 112, 112, 0.1);
  border-color: rgba(82, 112, 112, 0.25);
  color: #527070;
  cursor: not-allowed;
  /* iOS Safari fades disabled controls on its own, on top of whatever we set —
     which would take the value below AA. Both of these are needed to stop it. */
  opacity: 1;
  -webkit-text-fill-color: #527070;
}

/* The baseline's focus ring is the app's "you may type here" signal, in the
   primary teal — on an uneditable field it undoes everything above. A disabled
   field cannot be focused at all, so its ring is simply dropped; a readonly one
   can be (tab into a locked price and copy it), so it keeps an indicator, in the
   same faint ink as the rest of the field rather than the live color. */
input:not([type=checkbox], [type=radio], [type=submit], [type=button], [type=reset]):disabled:focus,
select:disabled:focus,
textarea:disabled:focus {
  border-color: rgba(82, 112, 112, 0.25);
  box-shadow: none;
}

input:not([type=checkbox], [type=radio], [type=submit], [type=button], [type=reset])[readonly]:focus,
textarea[readonly]:focus {
  border-color: #527070;
  box-shadow: 0 0 0 3px rgba(82, 112, 112, 0.18);
}

/* The native dropdown arrow does not take `color`, so a disabled select kept a
   full-strength black chevron over a grayed-out field — the one part of it still
   advertising a menu that will not open. Swapping in our own is the only way to
   fade it, and `appearance: none` is scoped to :disabled so every live select in
   the app keeps the platform control untouched. The chevron is $text-faint,
   URL-encoded (a raw # ends the data URI). */
select:disabled {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 1.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23527070' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 0.6rem;
}

/* Checkboxes and radios.

   Drawn by hand rather than left to the platform. The native control keeps the
   OS's own box, border and focus treatment even under accent-color, so on
   Windows a blue square with a dotted outline sat beside a teal-ringed text
   field. Every OS now gets the same control, and it is kin to the text-entry
   baseline above — same border, radius and fill at rest, the same $primary
   border on hover and the same ring on focus — so a live box reads as something
   you can act on rather than as decoration. Checked fills $primary under a white
   glyph, an SVG data URI like the disabled select's chevron (the fill is
   url-encoded; a raw # ends the URI). The image fills the box and the paths
   leave their own margin inside the 12x12 viewBox, so the glyph spans about
   three-quarters of the box.

   Sized in em so a box inside .7rem table chrome scales with its row. The UA's
   own margin (3px 3px 3px 4px) is left alone so inline-flow labels keep their
   spacing, and vertical-align sits the box on the text's optical centre rather
   than the baseline. Held at (0,0,1) with :where so the components that already
   size their boxes (the users form's 1rem, the customer order table's 1.1rem)
   and the ones that hide them (.FilterToggleCheckbox, the print view) keep
   winning without change. */
input:where([type=checkbox], [type=radio]) {
  appearance: none;
  -webkit-appearance: none;
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  padding: 0;
  flex: 0 0 auto;
  vertical-align: -0.2em;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  background: #fff center/100% no-repeat;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
  /* Nothing to gray out but the control itself. */
}
input:where([type=checkbox], [type=radio]):hover:not(:disabled) {
  border-color: #105151;
}
input:where([type=checkbox], [type=radio]):focus-visible {
  outline: none;
  border-color: #105151;
  box-shadow: 0 0 0 3px rgba(16, 81, 81, 0.22);
}
input:where([type=checkbox], [type=radio]):checked, input:where([type=checkbox], [type=radio]):indeterminate {
  border-color: #105151;
  background-color: #105151;
}
input:where([type=checkbox], [type=radio]):disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

input:where([type=checkbox]):checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.2 6.5 5 9.3 9.8 3'/%3E%3C/svg%3E");
}

/* The "some of these" box a select-all control shows from JS. Nothing sets it
   yet; the state costs one rule and stops it falling back to the OS drawing. */
input:where([type=checkbox]):indeterminate {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M2.5 6h7'/%3E%3C/svg%3E");
}

input:where([type=radio]) {
  border-radius: 50%;
}
input:where([type=radio]):checked {
  background-image: radial-gradient(circle, #fff 0 30%, transparent 36%);
}

/* The label belongs to the same fact as the field. Without this a full-strength
   bold "Stock Type" sits over an obviously dead select, and the pair argues with
   itself about whether the row is editable — visibly so on a saved sale line,
   where the grayed Stock Type label used to sit two fields away from a bold
   "Per ($)" over an equally gray locked price. */
.Field:has(> select:disabled) > label,
.Field:has(> input:disabled) > label,
.Field:has(> input[readonly]) > label,
.Field:has(> textarea:disabled) > label,
.Field:has(> textarea[readonly]) > label,
.Field:has(> input:where([type=checkbox], [type=radio]):disabled) label {
  color: #527070;
  cursor: not-allowed;
}

/* Chrome, Safari, Edge, Opera */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Firefox */
input[type=number] {
  -moz-appearance: textfield;
}

input[type=color] {
  width: 2rem;
  height: 2rem;
  padding: 0.2rem;
}

/* Primary button baseline (submit + generic buttons).

   Wrapped in :where() so the whole block carries zero specificity — it is a
   default, not a competitor. Unwrapped it was 0,1,1, high enough to beat any
   component class (0,1,0) and paint transparent icon buttons with the primary
   fill on hover; the chevron in the sales list and the notification
   "mark unread" button both vanished into it, and a dozen other buttons carry a
   defensive hover background whose only job was to cancel this rule. At zero
   specificity any class- or id-level background wins automatically, so bare
   <button> still gets the primary look and styled buttons keep their own.

   The zero specificity has one casualty, handled by the rule below: it loses to
   the base reset. Everything color-related here is safe, because the reset
   declares only box-sizing/margin/padding. */
:where(input[type=submit], button) {
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  background-color: #105151;
  color: #ffffff;
  border: 1px solid #105151;
}
:where(input[type=submit], button):hover {
  background-color: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}

/* Button padding, carried at element specificity (0,0,1) rather than in the
   :where() block above.

   `* { margin: 0; padding: 0 }` in application.scss is emitted after every @use,
   so a zero-specificity padding ties it and loses on source order — which is why
   every bare <button> (the .VoggleToggle "Add User" / "New Task" toggles and
   friends) had its label pressed against the border. 0,0,1 clears the reset and
   still loses to any component class, so .RowExpand and .NotifMarkUnreadBtn keep
   their own tighter padding.

   Padding only. Do NOT fold the color declarations in here: this selector's
   generated :hover would land at 0,1,1 and repaint transparent icon buttons that
   declare a resting background but no hover one. */
button, input:where([type=submit], [type=button], [type=reset]) {
  padding: 0.5rem 1rem;
}

/* Press feedback for every button in the app — the depress is feedback about the
   click itself, not a signal about a button's importance, so it is not reserved
   for the big customer-facing CTAs.

   Deliberately untransitioned: a real button snaps down and snaps back. The
   :active outside the :where() puts this at 0,1,0, and nothing else in the app
   sets transform on a button, so no component rule can strand it in the pressed
   position. Disabled buttons never match :active, and .Button.is-disabled kills
   pointer-events, so neither depresses. */
:where(input[type=submit], button):active {
  transform: translateY(1px);
}

/* Buttons with a real surface additionally press *into* that surface: a soft
   shadow cast down-and-right from the top and left edges (positive offsets on an
   inset shadow land the shadow along those two edges), over a flat tint that
   deepens the whole face. The second shadow's huge spread collapses its inner
   hole so it fills the padding box edge to edge, which is what makes the tint
   work on any fill — green primary, white secondary, red danger alike.

   Scoped to the .Button family on purpose. This is NOT in the :where() base with
   the transform above: a 1px nudge is background-agnostic, but a dark inset on a
   transparent button paints a smudge across the glyph instead of a press, and the
   app has ~18 ghost buttons (.RowExpand, .CancelEditButton, .Button--link, the
   .Notif*Btn set, .SegmentButton …) that reset the base fill. Those keep the
   nudge alone. Anything that @extends .Button — .ConfirmButton, .CheckoutButton,
   .SubmitButton, .BackButton — is folded into these selectors by Sass and needs
   no rule of its own; a new ghost button needs no opt-out.

   Untransitioned to match the transform, and safe to state unconditionally: no
   button anywhere else in the app declares box-shadow, and focus rings here are
   drawn with outline, so a focused button keeps its ring while pressed. */
.Button:active, .BackButton:active, .SubmitButton:active, .CheckoutButton:active, .ConfirmButton:active,
.Button--secondary:active,
.Button--danger:active,
.ButtonSecondary:active,
.ButtonSuccess:active,
.ButtonDanger:active {
  box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.3), inset 0 0 0 100vmax rgba(0, 0, 0, 0.06);
}

.InputWithSuffix {
  position: relative;
  display: inline-block;
}

.InputWithSuffix input[type=number] {
  padding-right: 3.25em; /* default; JS will tighten this */
}

.InputWithSuffix .Suffix {
  position: absolute;
  right: 0.5rem;
  top: 58%;
  transform: translateY(-50%);
  pointer-events: none;
  white-space: nowrap;
  opacity: 0.7; /* “placeholder-ish” */
  font-variant-numeric: tabular-nums;
}

/* The suffix is a sibling of the input, not inside it, so it does not inherit
   the grayed-out ink when the field goes uneditable — the locked quantity on a
   sale line sat under a full-strength "qts". */
.InputWithSuffix:has(> input:disabled) .Suffix,
.InputWithSuffix:has(> input[readonly]) .Suffix {
  color: #527070;
}

/* Aliases for semantic button classes you can use anywhere */
.Button, .BackButton, .SubmitButton, .CheckoutButton, .ConfirmButton {
  background-color: #105151;
  color: #ffffff;
  border: 1px solid #105151;
  padding: 0.5rem 0.9rem;
  border-radius: var(--btn-radius);
  cursor: pointer;
  white-space: nowrap;
}
.Button:hover, .BackButton:hover, .SubmitButton:hover, .CheckoutButton:hover, .ConfirmButton:hover {
  background-color: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}

.Button--secondary, .BackButton {
  background-color: #fff;
  color: #1f3d3d;
  border: 1px solid #e3dccb;
  padding: 0.5rem 0.9rem;
  border-radius: var(--btn-radius);
}
.Button--secondary:hover, .BackButton:hover {
  background-color: #fffdf7;
}

.Button--danger {
  background-color: rgb(177, 75.5, 69.5);
  color: #ffffff;
  border: 1px solid rgb(177, 75.5, 69.5);
  padding: 0.5rem 0.9rem;
  border-radius: var(--btn-radius);
}
.Button--danger:hover {
  background-color: rgb(185.0206896552, 82.8206896552, 76.7793103448);
}

.Button:hover, .BackButton:hover, .SubmitButton:hover, .CheckoutButton:hover, .ConfirmButton:hover, .Button--secondary:hover, .Button--danger:hover {
  text-decoration: none;
}

/* Button size modifiers */
.ButtonSmall {
  font-size: 0.875rem;
  padding: 0.3rem 0.6rem;
}

/* The standard box for a button whose whole label is one glyph — ✏️, 💬, 🗑️.
   Every one of these in the app should be this tall, so a row of them lines up
   no matter which component each came from (the task row's edit button and its
   comments button were 4px apart before this existed).

   Height is fixed and width is not: min-width holds the square, and anything
   that needs more room — a two-glyph label, say —
   widens on its own rather than being clipped or squashed. --icon-btn-size is
   the escape hatch for a spot that genuinely needs a bigger hit target; set it
   on the instance, don't re-declare height.

   Size only. Pair it with a color modifier for the surface (.Button.ButtonIcon,
   .ButtonDanger.ButtonIcon), or with a component class that brings its own
   (.btn-comments). Don't combine it with .ButtonSmall — both set font-size and
   padding, and which one wins depends on source order. */
.ButtonIcon {
  --icon-btn-size: 30px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--icon-btn-size);
  min-width: var(--icon-btn-size);
  padding: 0 0.35rem;
  /* Emoji ignore font-weight and most inherited text styling, so the glyph's
     own size is the only lever on how big it reads. 1rem sits between the two
     sizes this replaced (0.875rem and 1.4rem). */
  font-size: 1rem;
  line-height: 1;
}

/* The round check-off button. Tasks own the pattern — mark complete, click
   again to reopen — and pull lists reuse it for Pull All and for pulling a
   single item, so one glyph in one place means the same thing app-wide.

   The ✓ is transparent at rest: the empty circle is the affordance, and the
   check inks in on hover (a preview of what the tap does) or once the thing is
   actually done. Done-and-hovered goes $danger, because the next tap undoes it.

   $danger ink on a $danger-light fill is only 3.50:1, and this glyph is 0.7rem
   bold. $danger-dark is the pairing the rest of the app already uses on
   $danger-light and clears AA at 9.17:1. */
.CompleteToggleBtn {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid #e3dccb;
  background: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 700;
  color: transparent;
  padding: 0;
  flex-shrink: 0;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.CompleteToggleBtn:hover {
  border-color: #1c723b;
  color: rgb(152.85, 191.55, 166.8);
}
.CompleteToggleBtn.is-complete {
  border-color: #1c723b;
  background: #1c723b;
  color: #ffffff;
}
.CompleteToggleBtn.is-complete:hover {
  border-color: rgb(177, 75.5, 69.5);
  background: rgb(240.3, 202.15, 195.85);
  color: #5d091f;
}

/* Nobody may flip every one of these: a floor hand on a list with nothing left
   to pull, a cancelled row. The state still has to read, so the same circle
   renders as a plain span with the interaction stripped rather than vanishing
   and letting the column lose its left edge. */
.CompleteToggleBtn.is-static {
  cursor: default;
}
.CompleteToggleBtn.is-static:hover {
  border-color: #e3dccb;
  color: transparent;
}
.CompleteToggleBtn.is-static.is-complete:hover {
  border-color: #1c723b;
  background: #1c723b;
  color: #ffffff;
}

/* `button_to` wraps its button in a form, and that form — not the button — is
   the flex item in a row. Without this the circle takes a line of its own. */
.CompleteToggleForm {
  display: flex;
}

/* Button color modifiers (composable with .Button) */
.ButtonPrimary { /* inherits from .Button — green by default */ }

.ButtonSecondary {
  background-color: #fff;
  color: #1f3d3d;
  border: 1px solid #e3dccb;
}
.ButtonSecondary:hover {
  background-color: #fffdf7;
}

.ButtonSuccess {
  background-color: #105151;
  color: #ffffff;
  border: 1px solid #105151;
}
.ButtonSuccess:hover {
  background-color: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}

.ButtonDanger {
  background-color: rgb(177, 75.5, 69.5);
  color: #ffffff;
  border: 1px solid rgb(177, 75.5, 69.5);
}
.ButtonDanger:hover {
  background-color: rgb(185.0206896552, 82.8206896552, 76.7793103448);
}

.ButtonBlock {
  display: block;
  width: 100%;
  text-align: center;
}

/* A heading's controls are chrome, not headline — they get a control's size back
   rather than the <h1>'s. Link buttons need this most: a real <button> ignores
   inherited font-size by default, but an <a class="Button"> takes the full
   headline scale and renders roughly twice the size of the <button> beside it
   (the pricing page's "Import from season"). inline-flex gives the anchor a box
   that can honor min-height and centers its label the way a button does, and
   align-self stops it stretching to the row's height as a flex item. */
h1 input[type=submit], h1 button, h1 a.Button, h1 a.BackButton, h1 a.SubmitButton, h1 a.CheckoutButton, h1 a.ConfirmButton {
  min-height: 3em;
  font-size: 0.85rem;
}

h1 a.Button, h1 a.BackButton, h1 a.SubmitButton, h1 a.CheckoutButton, h1 a.ConfirmButton {
  display: inline-flex;
  align-items: center;
  align-self: center;
}

.FilterForm {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: self-end;
  margin-bottom: 1rem;
}
.FilterForm input, .FilterForm select {
  flex: 1 1 140px;
  min-width: 0;
  max-width: 200px;
  padding: 0.3rem;
  font-size: 0.9rem;
}
.FilterForm button {
  padding: 0.3rem 0.75rem;
  font-size: 0.9rem;
  white-space: nowrap;
  background-color: #1f3d3d;
  color: #ffffff;
  border: 1px solid #1f3d3d;
  border-radius: 6px;
}
.FilterForm button:hover {
  background-color: rgb(17.252173913, 33.947826087, 33.947826087);
}
.FilterForm .DateSelect {
  max-width: 120px;
}

.FilterToggleCheckbox {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0;
  height: 0;
}

.FilterToggleLabel {
  cursor: pointer;
  padding: 0.3rem 0.4rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  display: flex;
  align-items: center;
  color: #527070;
  flex-shrink: 0;
}
.FilterToggleLabel:has(.FilterToggleCheckbox:checked) {
  color: rgb(161.9922330097, 110.667961165, 3.2077669903);
  border-color: #ca8a04;
  background: rgb(248.64, 240.96, 224.88);
}

.FormCompact {
  display: flex;
  flex-direction: column;
  gap: 0.75rem; /* was -1.5rem; negative gaps can be glitchy */
}
.FormCompact fieldset {
  border: none;
  padding: 0;
}
.FormCompact fieldset legend {
  font-weight: bold;
  margin-bottom: 0.5rem;
}
.FormCompact fieldset div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.FormCompact fieldset div input {
  flex: 1 1 150px;
  padding: 0.5rem;
  font-size: 0.95rem;
}
.FormCompact .CheckboxGroup {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  /* Box and text are separate flex items so a label that wraps (narrow
     screens, long names like "View Aggregates") keeps its second line
     under the text rather than centered beneath the checkbox. */
}
.FormCompact .CheckboxGroup label {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  text-align: left;
  line-height: 1.2;
  /* .FormCompact fieldset div input above would otherwise stretch the
     box to 150px now that the label is a flex container. */
}
.FormCompact .CheckboxGroup label input[type=checkbox] {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  margin: 0.1rem 0 0;
  padding: 0;
}
.FormCompact .CheckboxGroup.Vertical {
  flex-direction: column;
  gap: 0.5rem;
  justify-content: flex-start;
}
.FormCompact .CheckboxGroup.TwoColumn {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem 1.5rem;
  justify-items: start;
}
@media (max-width: 767px) {
  .FormCompact .CheckboxGroup.TwoColumn {
    grid-template-columns: 1fr;
    gap: 0.6rem;
  }
}
.FormCompact .SubmitRow {
  display: flex;
  justify-content: flex-end;
}
.FormCompact .UserForm-avatar {
  display: flex;
  align-items: center;
  gap: 1rem;
  border: none;
  padding: 0;
}
.FormCompact .UserForm-avatarPreview {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.FormCompact .UserForm-avatarPreview--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--user-color);
  color: #fff;
  font-size: 1.5rem;
  font-weight: 600;
}
.FormCompact .UserForm-avatarField {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  width: 100%;
}
.FormCompact .UserForm-avatarField input {
  max-height: 2.5rem;
}
.FormCompact .UserForm-avatarField label {
  font-weight: 600;
  font-size: 0.85rem;
}
.FormCompact .UserForm-colorField {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.FormCompact .UserForm-colorField label {
  font-weight: 600;
  font-size: 0.85rem;
}
.FormCompact .UserForm-colorField input[type=color] {
  width: 40px;
  height: 40px;
  max-height: 40px;
  padding: 2px;
  border: 1px solid #e3dccb;
  border-radius: 6px;
  cursor: pointer;
  background: none;
}

.InlineForm {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Inline row for fields that should share a line (e.g., Customer + Wanted date) */
.FormRow {
  display: flex;
  align-items: end; /* aligns inputs along their bottoms */
  gap: 0.75rem;
  flex-wrap: wrap; /* wrap on small screens */
}

.FormRow.Spaced {
  align-items: center;
  place-content: space-between;
}

/* Default field flex behavior inside a FormRow */
.FormRow > .Field {
  flex: 1 1 220px; /* grow, shrink, reasonable min */
}

/* Narrow date field */
.Field--date {
  flex: 0 0 var(--date-input-width, 12rem); /* fixed basis, no grow */
  max-width: 100%;
}

/* You can also tag the input directly if you prefer */
.Input--date {
  inline-size: var(--date-input-width, 12rem);
  max-width: 100%;
}

/* Small nicety: date digits align better */
input[type=date] {
  font-variant-numeric: tabular-nums;
}

/* Keep the remote user picker dropdown positioned correctly */
.RemoteUserPicker {
  position: relative;
}

.RemoteUserPicker .DropdownResults {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 1100;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  max-height: 240px;
  overflow: auto;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
}

/* Two names for one thing: the older forms say .ErrorSummary, the newer ones
   .ErrorMessages, and an error block that inherited no styling at all read as
   ordinary prose above a long form — exactly where a reader skims past it. */
.ErrorSummary,
.ErrorMessages {
  border: 1px solid rgb(177, 75.5, 69.5);
  background: rgb(240.3, 202.15, 195.85);
  color: #1f3d3d;
  padding: 0.6rem 0.75rem;
  border-radius: 8px;
  margin-bottom: 0.5rem;
}

.ErrorSummary h3,
.ErrorMessages h3 {
  margin: 0 0 0.35rem;
  font-size: 0.95rem;
}

.ErrorSummary li,
.ErrorMessages li {
  margin-left: 1rem;
}

.ErrorMessage {
  margin-top: 0.25rem;
  font-size: 12px;
  color: rgb(177, 75.5, 69.5);
}

/* Segmented group (row 1) */
.SegmentGroup {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--color-border, #ddd);
  border-radius: 9999px; /* rounded ends */
  overflow: hidden; /* hide child corners */
  background: #fff; /* was var(--bg-color, #fff) — that var is never defined */
}

/* Each segment looks like a button, touches neighbors */
.SegmentButton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.35rem 0.7rem;
  text-decoration: none;
  border: 0;
  background: transparent;
  color: var(--color-text-dark);
  line-height: 1.2;
  white-space: nowrap;
}

/* faint separators between segments */
.SegmentGroup > .SegmentButton + .SegmentButton {
  border-radius: 0px;
  border-left: 1px solid color-mix(in srgb, var(--color-border, #ddd) 70%, transparent);
}

/* hover / focus */
.SegmentButton:hover,
.SegmentButton:focus {
  background: color-mix(in srgb, var(--color-border, #ddd) 15%, transparent);
  outline: none;
}

/* active (already stamped) */
.SegmentButton.is-active {
  background: color-mix(in srgb, var(--color-border, #ddd) 25%, transparent);
  font-weight: 600;
}

/* disabled look (for helper’s span fallback or disabled links) */
.SegmentButton.is-disabled,
.Button.is-disabled,
.is-disabled.BackButton,
.is-disabled.SubmitButton,
.is-disabled.CheckoutButton,
.is-disabled.ConfirmButton {
  opacity: 0.5;
  pointer-events: none;
}

/* A natively disabled button is the same fact as .is-disabled and has to look
   like it. Without this a blocked "Cancel" renders full-strength danger red and
   reads as live — the pull list page had two of them. `cursor` rather than
   `pointer-events: none`, so the `title` explaining *why* still shows. */
button.Button:disabled, button.BackButton:disabled, button.SubmitButton:disabled, button.CheckoutButton:disabled, button.ConfirmButton:disabled,
input[type=submit].Button:disabled,
input[type=submit].BackButton:disabled,
input[type=submit].SubmitButton:disabled,
input[type=submit].CheckoutButton:disabled,
input[type=submit].ConfirmButton:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.Button--pill {
  border-radius: 9999px;
}

.Button--sm {
  font-size: 0.9rem;
  padding: 0.35rem 0.6rem;
}

/* ── Account settings form ───────────────────────────────────────────────── */
.AccountForm {
  max-width: 860px;
}
.AccountForm__section {
  margin-bottom: 2rem;
}
.AccountForm__section-title {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: #527070;
  border-bottom: 1px solid #e3dccb;
  padding-bottom: 0.35rem;
  margin: 0 0 1rem;
}
.AccountForm__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}
.AccountForm__field {
  display: flex;
  flex-direction: column;
}
.AccountForm__field label {
  margin-bottom: 0.2rem;
}
.AccountForm__field .hint {
  margin-top: 0.25rem;
}
.AccountForm__field[hidden] {
  display: none;
}
.AccountForm__field--full {
  grid-column: 1/-1;
}
.AccountForm__field--wide {
  grid-column: span 2;
}
.AccountForm__checks {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.AccountForm__check {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: normal;
  cursor: pointer;
}
.AccountForm__check input[type=checkbox] {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  margin: 0;
}
.AccountForm__tooltip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: #527070;
  color: #ffffff;
  font-size: 0.65rem;
  font-weight: bold;
  cursor: help;
  vertical-align: middle;
  margin-left: 0.25rem;
}
.AccountForm__actions {
  margin-top: 0.5rem;
}

.AppDialog {
  border: none;
  padding: 0;
  background: #fff;
  max-height: 80vh;
  overflow: hidden;
  margin: auto;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
  white-space: normal;
  font-style: normal;
}
.AppDialog::backdrop {
  background: rgba(0, 0, 0, 0.5);
}
.AppDialog[open] {
  display: flex;
  flex-direction: column;
}

.AppDialog-inner {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  overflow: hidden;
}

.Icon {
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  max-width: none;
  min-width: 12px;
  min-height: 12px;
  vertical-align: -0.22em;
  flex-shrink: 0;
  overflow: visible;
}

:is(.ButtonIcon, .IconButton, .CompleteToggleBtn, .IconText) > .Icon,
:is(.ButtonIcon, .IconButton) > * > .Icon {
  vertical-align: middle;
}

.IconText {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
}

.Icon--primary {
  color: #105151;
}

.Icon--success {
  color: #1c723b;
}

.Icon--danger {
  color: rgb(177, 75.5, 69.5);
}

.Icon--warning {
  color: rgb(151.5, 103.5, 3);
}

.Icon--muted {
  color: #527070;
}

.Icon--accent {
  color: #caf35b;
}

.PriceLockButton[aria-pressed=true] .PriceLockButton__unlocked,
.PriceLockButton:not([aria-pressed=true]) .PriceLockButton__locked,
.LeftMenuThemeToggle[aria-pressed=true] .ThemeToggle__toDark,
.LeftMenuThemeToggle:not([aria-pressed=true]) .ThemeToggle__toLight {
  display: none;
}

.CompleteToggleBtn > .Icon {
  width: 14px;
  height: 14px;
  stroke-width: 2.6;
}

:is(.HeaderButton, .Button, .DocsMenu__button, .DocsMenu__item, .SaleQbo__badge, .Badge, .PrintLink):has(> .Icon) {
  column-gap: 0.35em;
}

/* 03: Components */
#Navbar {
  position: fixed;
  top: 0;
  left: 0;
  height: var(--app-header-height);
  width: 100%;
  background: #0a5454;
  z-index: 1010;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1rem;
  color: #ffffff;
}
#Navbar a {
  color: #ffffff;
}
#Navbar.DemoMode {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cg stroke='rgb(202,138,4)' stroke-opacity='0.16'%3E%3Cpath fill='none' stroke-width='1' d='M-1 1L1 -1M0 12L12 0M11 13L13 11'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 12px 12px;
  background-attachment: scroll;
}
@media print {
  #Navbar.DemoMode {
    background-image: none;
  }
}

.NavbarLeft,
.NavbarCenter,
.NavbarRight {
  display: flex;
  align-items: center;
  padding-right: 1rem;
}

.NavbarLeft,
.NavbarLeft > *,
.NavbarRight > * {
  flex-shrink: 0;
}

.NavbarCenter {
  flex-shrink: 100;
}

.NavbarRight {
  flex: 0 1 auto;
  min-width: 0;
}

.NavbarRight > .HeaderRecentSales {
  flex-shrink: 1;
  min-width: 0;
}

.NavbarProfileName {
  white-space: nowrap;
}

@media (max-width: 991px) {
  .NavbarProfileName {
    display: none;
  }
}
#NavbarTitle {
  line-height: 1.5rem;
  margin: 0;
  color: #ffffff;
}

.NavbarAvatarImg {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: middle;
}

#NavbarProfileLink {
  font-size: 1.125rem;
  display: flex;
  align-items: center;
  padding: 0.25rem 0.5rem;
  border-radius: 0.375rem;
  text-decoration: none;
  color: inherit;
}
#NavbarProfileLink a:hover {
  text-decoration: none;
}
#NavbarProfileLink:hover {
  background-color: rgba(255, 255, 255, 0.08);
  text-decoration: none;
}

@media (max-width: 767px) {
  .NavbarProfileName {
    display: none;
  }
  .NavbarCenter {
    width: min-content;
    padding-right: 1rem;
  }
}
#LeftMenuToggle {
  background: none;
  border: none;
  font-size: 1.5rem;
  margin-right: 1rem;
  cursor: pointer;
  color: #ffffff;
  padding: 0;
}

#LeftMenu {
  font-size: 1.2rem;
  width: 200px;
  position: fixed;
  top: 0;
  left: -250px;
  transition: left 0.3s ease;
  height: 100%;
  height: 100dvh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  background: rgba(10, 84, 84, 0.97);
  color: white;
  z-index: 1003;
  padding-top: var(--app-header-height);
  border-right: 1px solid rgba(255, 255, 255, 0.2);
}
#LeftMenu.open {
  left: 0;
}
#LeftMenu ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
#LeftMenu ul li {
  padding: 0.45rem 1rem;
}
#LeftMenu > ul {
  padding-top: 0.5rem;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
}
#LeftMenu::before,
#LeftMenu .LeftMenuFooter::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 2.5rem;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}
#LeftMenu::before {
  top: var(--app-header-height);
  height: 1.5rem;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.45), transparent);
  z-index: 1;
}
#LeftMenu .LeftMenuFooter::before {
  bottom: 100%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.25) 45%, transparent);
}
#LeftMenu[data-scroll-cues-more-above]::before, #LeftMenu[data-scroll-cues-more-below] .LeftMenuFooter::before {
  opacity: 1;
}
#LeftMenu .LeftMenuFooter {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.6rem 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
}
#LeftMenu .LeftMenuNewSale {
  padding-bottom: 0.6rem;
}
#LeftMenu .LeftMenuNewSale a {
  display: inline-flex;
  padding: 0.3rem 0.85rem 0.3rem 0.6rem;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  font-size: 1.05rem;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
#LeftMenu .LeftMenuNewSale a:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.45);
}
#LeftMenu .LeftMenuShop {
  font-size: 1rem;
  font-weight: bold;
  text-decoration: none;
  white-space: nowrap;
}
#LeftMenu a {
  color: white;
}
#LeftMenu .LeftMenuGroup {
  padding: 0;
}
#LeftMenu .LeftMenuGroup > ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
#LeftMenu .LeftMenuGroup > ul li {
  padding: 0.3rem 1rem 0.3rem 2rem;
  font-size: 1rem;
}
#LeftMenu .LeftMenuGroupToggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.45rem 1rem;
  background: none;
  border: none;
  color: white;
  font-size: 1.2rem;
  font-weight: bold;
  cursor: pointer;
  text-align: left;
}
#LeftMenu .LeftMenuGroupToggle:hover {
  background: rgba(255, 255, 255, 0.08);
}
#LeftMenu .LeftMenuGroupToggle:focus {
  outline: none;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.3);
}
#LeftMenu .LeftMenuMyInfo {
  font-size: 1rem;
  opacity: 0.85;
  text-decoration: none;
  white-space: nowrap;
}
#LeftMenu .LeftMenuMyInfo:hover {
  opacity: 1;
}
#LeftMenu .LeftMenuThemeToggle {
  padding: 0;
  background: none;
  border: none;
  color: white;
  font-size: 1rem;
  cursor: pointer;
  opacity: 0.85;
  white-space: nowrap;
}
#LeftMenu .LeftMenuThemeToggle:hover {
  opacity: 1;
}
#LeftMenu .LeftMenuChevron {
  font-size: 0.7em;
  transition: transform 0.2s ease;
  display: inline-flex;
}
#LeftMenu .LeftMenuChevron.is-open {
  transform: rotate(90deg);
}

.HeaderButton {
  display: inline-flex;
  align-items: center;
  height: 34px;
  background: #0a5454;
  color: #ffffff;
  border: 1px solid rgba(15.4255319149, 129.5744680851, 129.5744680851, 0.97);
  border-radius: 6px;
  padding: 0.4rem 0.8rem;
  font-size: 0.85rem;
  font-weight: bold;
  cursor: pointer;
  transition: background 0.2s, border 0.2s;
  white-space: nowrap;
  flex: 0 0 auto;
}
.HeaderButton:hover {
  background: rgba(12.7127659574, 106.7872340426, 106.7872340426, 0.97);
  border-color: rgb(33.4008510638, 228.6191489362, 228.6191489362);
}
.HeaderButton:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
  text-decoration: none;
}

.HeaderRecentSales {
  display: inline-flex;
  gap: 0.4rem;
  align-items: center;
}

.RecentSaleButton {
  gap: 0.35rem;
  max-width: 14rem;
  overflow: hidden;
  white-space: nowrap;
  flex: 0 0 auto;
}
.RecentSaleButton:has(.RecentSaleCustomer) {
  flex: 0 1 auto;
  min-width: 7.5rem;
}
.RecentSaleButton .SaleDockGlyph {
  flex: 0 0 auto;
  font-size: 0.9em;
  line-height: 1;
}
.RecentSaleButton .RecentSaleNumber {
  flex: 0 0 auto;
}
.RecentSaleButton .RecentSaleNumber:not(:only-child)::after {
  content: "•";
  margin-left: 0.35rem;
  opacity: 0.6;
}
.RecentSaleButton .RecentSaleCustomer {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: normal;
}

@media (max-width: 1399px) {
  .RecentSaleButton {
    max-width: 10rem;
  }
}
@media (max-width: 1199px) {
  .RecentSaleButton,
  .RecentSaleButton:has(.RecentSaleCustomer) {
    max-width: none;
    flex: 0 0 auto;
    min-width: 0;
  }
  .RecentSaleButton .RecentSaleCustomer,
  .RecentSaleButton:has(.RecentSaleCustomer) .RecentSaleCustomer {
    display: none;
  }
  .RecentSaleButton .RecentSaleNumber:not(:only-child)::after,
  .RecentSaleButton:has(.RecentSaleCustomer) .RecentSaleNumber:not(:only-child)::after {
    content: none;
  }
}
@media (max-width: 1099px) {
  .HeaderRecentSales > .RecentSaleButton:nth-child(n+3) {
    display: none;
  }
}
@media (max-width: 949px) {
  .HeaderRecentSales > .RecentSaleButton:nth-child(n+2) {
    display: none;
  }
}
@media (max-width: 849px) {
  .HeaderRecentSales {
    display: none;
  }
}
.NavbarLoading {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  overflow: hidden;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.15s, visibility 0s 0.15s;
}
.NavbarLoading::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  border-radius: 3px;
  background: #caf35b;
  animation: NavbarLoading-sweep 1.1s ease-in-out infinite;
}

html[aria-busy=true] .NavbarLoading,
html:has([aria-busy=true]) .NavbarLoading {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.15s 0.15s, visibility 0s 0.15s;
}

@keyframes NavbarLoading-sweep {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(250%);
  }
}
@media (prefers-reduced-motion: reduce) {
  .NavbarLoading::before {
    animation: none;
    width: 100%;
    opacity: 0.7;
  }
}
.LoginPage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  background-color: #faf7ee;
}

.LoginBox {
  width: 100%;
  max-width: 400px;
  background: white;
  border-radius: 0.5rem;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  padding: 2rem;
  box-sizing: border-box;
  color: #1f3d3d;
  text-align: center;
}

.LoginTitle {
  font-size: 1.8rem;
  color: #105151;
  margin-bottom: 0.5rem;
}

.LoginBox .Logo,
.LoginBox .LoginTitle {
  display: inline-block;
  margin-bottom: 1rem;
}

.LoginSubtitle {
  font-size: 1rem;
  color: #527070;
  margin-bottom: 1rem;
}

.LoginBox .DemoText {
  margin-bottom: 1rem;
}

.LoginBox label {
  display: block;
  margin-bottom: 0.25rem;
  font-weight: 600;
  color: #1f3d3d;
}

.LoginBox input[type=email],
.LoginBox input[type=password] {
  width: 100%;
  padding: 0.5rem 0.75rem;
  margin-bottom: 1.25rem;
  border: 1px solid #e3dccb;
  border-radius: 0.375rem;
  background-color: #fffdf7;
  box-sizing: border-box;
  font-size: 1rem;
}

.LoginBox input[type=submit] {
  width: 100%;
  padding: 0.75rem;
  background-color: #105151;
  color: #ffffff;
  border: none;
  border-radius: 0.375rem;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  transition: background-color 0.2s ease-in-out;
}
.LoginBox input[type=submit]:hover {
  background-color: rgb(11.793814433, 59.706185567, 59.706185567);
}

.FormGroup {
  margin-bottom: 1rem;
  text-align: left;
}
.FormGroup label {
  margin-bottom: 0.25rem;
}

.HeaderFilterFlexContainer {
  display: flex;
  align-items: unset;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.HeaderFilterFlexContainer select {
  background-color: #faf7ee;
  color: #105151;
  font-size: 1.6rem;
  padding: 0.25rem;
}

.HeaderFilterYearLabel {
  font-weight: 500;
  white-space: nowrap;
}

.HeaderFilterYearSelect {
  min-width: 10rem;
  max-width: 11rem;
}

.HeaderFilterStockTypeSelect {
  min-width: 16rem;
  max-width: 16rem;
}

.HeaderFilterSalesFilterSelect {
  min-width: 15rem;
  max-width: 15rem;
}

.HeaderFilterSalesSortSelect {
  min-width: 20rem;
  max-width: 20rem;
}

.HeaderFilterSpeciesDropdown {
  position: relative;
}

.HeaderFilterSpeciesButton {
  min-height: unset;
  font-size: 1.6rem;
  font-family: inherit;
  font-weight: normal;
  border-radius: 4px;
  background-color: #faf7ee;
  color: #105151;
  padding: 0 0.5rem;
  margin-top: 0.5rem;
  border: 1px solid #e3dccb;
  cursor: default;
  min-width: 26rem;
  max-width: 26rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
}
.HeaderFilterSpeciesButton::after {
  content: "↓";
  flex-shrink: 0;
}
.HeaderFilterSpeciesButton:hover {
  background-color: initial;
}

.HeaderFilterSpeciesPanel {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 200;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  max-height: 28rem;
  min-width: 26rem;
  overflow-y: auto;
  padding: 0.4rem 0;
}

.HeaderFilterSpeciesOption {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.8rem;
  font-size: 1.4rem;
  cursor: default;
  white-space: nowrap;
}
.HeaderFilterSpeciesOption:hover {
  background-color: #faf7ee;
}
.HeaderFilterSpeciesOption input[type=checkbox] {
  cursor: pointer;
}

.SpeciesTableWrapper {
  flex: 1;
  min-width: 0;
  overflow-x: auto;
}

.SpeciesTable {
  min-width: 28rem;
}
.SpeciesTable .SpeciesColumn {
  min-width: 8rem;
}
@media (max-width: 767px) {
  .SpeciesTable {
    min-width: 0;
  }
}

.EditColumn .SpeciesInfoBtn-trigger {
  font-size: 1.15rem;
}

.SpeciesTable__letterAnchor {
  scroll-margin-top: calc(var(--app-header-height) + 0.5rem);
}
.SpeciesTable__letterAnchor td {
  padding: 0;
  height: 0;
  line-height: 0;
  font-size: 0;
  border: none;
}

.SpeciesShow {
  max-width: 70rem;
  margin: 0 auto;
  padding: 1rem;
}

.SpeciesShow-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.SpeciesShow-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.SpeciesShow-latin {
  font-style: italic;
  margin-left: 0.5rem;
}

.SpeciesShow-section {
  overflow-wrap: anywhere;
  margin-top: 1.5rem;
}

.SpeciesGallery {
  margin-top: 0.5rem;
}

.SpeciesGallery-empty {
  padding: 1rem 0;
}

.SpeciesGallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  gap: 1rem;
  margin-top: 1rem;
}

.SpeciesGallery-card {
  border: 1px solid #e3dccb;
  border-radius: 6px;
  padding: 0.5rem;
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.SpeciesGallery-card.is-primary {
  border-color: #ca8a04;
  box-shadow: 0 0 0 2px rgba(202, 138, 4, 0.2);
}

.SpeciesGallery-thumbWrap {
  position: relative;
  aspect-ratio: 1/1;
  background: #fffdf7;
  border-radius: 4px;
  overflow: hidden;
}
.SpeciesGallery-thumbWrap--clickable {
  cursor: zoom-in;
}
.SpeciesGallery-thumbWrap--clickable:hover .SpeciesGallery-thumb {
  opacity: 0.88;
}

.SpeciesGallery-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.SpeciesGallery-thumb--missing {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #527070;
  font-size: 0.85rem;
}

.SpeciesGallery-primaryBadge {
  position: absolute;
  top: 0.25rem;
  left: 0.25rem;
  background: rgba(151.5, 103.5, 3, 0.95);
  color: #fff;
  font-size: 0.85rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
}

.SpeciesGallery-descForm {
  margin: 0;
}

.SpeciesGallery-descInput {
  width: 100%;
  font-size: 0.85rem;
  resize: vertical;
}

.SpeciesGallery-cardActions {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.SpeciesGallery-cardActions form {
  margin: 0;
}

.SpeciesGallery-actionBtn {
  font-size: 0.8rem;
  padding: 0.25rem 0.5rem;
}

.SpeciesGallery-meta {
  font-size: 0.7rem;
  color: #527070;
  text-align: center;
}

.SpeciesGallery-deleteLink {
  font-size: 1rem;
  line-height: 1;
  text-decoration: none;
  opacity: 0.6;
}
.SpeciesGallery-deleteLink:hover {
  opacity: 1;
}

.SpeciesGallery-caption {
  font-size: 0.85rem;
  margin: 0;
  color: #1f3d3d;
}

.SpeciesUploader {
  margin-bottom: 1rem;
}

.SpeciesUploader-form {
  margin: 0;
}

input.SpeciesUploader-hiddenFile {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

.SpeciesUploader-dropzone {
  border: 2px dashed #e3dccb;
  border-radius: 6px;
  padding: 1rem;
  text-align: center;
  background: #fffdf7;
  transition: background 0.15s, border-color 0.15s;
}
.SpeciesUploader-dropzone.is-dragging {
  background: rgba(16, 81, 81, 0.06);
  border-color: #105151;
}

.SpeciesUploader-prompt {
  margin: 0 0 0.5rem;
  color: #527070;
  font-size: 0.9rem;
}

.SpeciesUploader-buttons {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  flex-wrap: wrap;
}

@media (hover: hover) and (pointer: fine) {
  .SpeciesUploader-cameraBtn {
    display: none;
  }
}

.SpeciesUploader-status {
  margin: 0.5rem 0 0;
  min-height: 1.2em;
  font-size: 0.85rem;
  color: #1f3d3d;
}
.SpeciesUploader-status.is-error {
  color: rgb(177, 75.5, 69.5);
}

.SpeciesUploader-cropDialog {
  border: none;
  border-radius: 8px;
  padding: 0;
  max-width: 95vw;
  width: 40rem;
  max-height: 95vh;
}
.SpeciesUploader-cropDialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

.SpeciesUploader-cropBody {
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.SpeciesUploader-cropContainer {
  max-height: 70vh;
  overflow: hidden;
}
.SpeciesUploader-cropContainer img {
  display: block;
  max-width: 100%;
}

.SpeciesUploader-cropActions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

.PhotoHub-uploaderSpecies {
  margin-bottom: 0.75rem;
}
.PhotoHub-uploaderSpecies label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
  color: #1f3d3d;
}

.PhotoHub-uploaderSpeciesSelect {
  max-width: 24rem;
}

.PhotoHub-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.75rem 0;
}
.PhotoHub-filter select {
  min-width: 0;
}

.PhotoHub-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.85rem;
  white-space: nowrap;
}

.PhotoHub-clear {
  font-size: 0.85rem;
}

.PhotoCard.is-unassigned {
  border-style: dashed;
  border-color: #527070;
}

.PhotoCard-needsSpecies {
  position: absolute;
  bottom: 0.25rem;
  left: 0.25rem;
  background: rgba(40, 40, 40, 0.8);
  color: #fff;
  font-size: 0.7rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
}

.PhotoCard-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.PhotoCard-assignForm {
  margin: 0;
}

.PhotoCard-speciesSelect {
  width: 100%;
  font-size: 0.85rem;
}

.PhotoCard-species {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  color: #1f3d3d;
}

.Pagination {
  margin-top: 1.5rem;
}

#SpeciesPhotosLink {
  justify-content: center;
  padding: 0 0.6rem;
  font-size: 1.4rem;
  line-height: 1;
}

.SpeciesCategoryBadge {
  display: inline-block;
  padding: 0 0.4em;
  border-radius: 999px;
  border: 1px solid #e3dccb;
  font-size: 0.8em;
  line-height: 1.5;
  color: rgb(59.1695652174, 116.4304347826, 116.4304347826);
  background: rgb(243.8, 241, 234.2);
  white-space: nowrap;
}

.LotForm {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 100%;
  justify-content: end;
}
@media (min-width: 520px) {
  .LotForm {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.25rem;
  }
}

.LotForm__inputs {
  display: flex;
  flex-direction: row;
  gap: 0.5rem;
}

.LotForm__field {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1;
}

.LotForm__label {
  font-size: 0.72rem;
  color: #527070;
  line-height: 1;
}

.LotForm__notesRow {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  width: 100%;
}
@media (min-width: 700px) {
  .LotForm__notesRow {
    flex-direction: row;
    gap: 0.5rem;
  }
  .LotForm__notesRow .LotForm__notesLabel {
    flex: 1;
    min-width: 0;
  }
}

.LotForm__notesLabel {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  width: 100%;
}

.LotForm__footer {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.LotField {
  font-size: 0.9rem;
}

.LotInput {
  width: 100%;
  text-align: right;
}
@media (min-width: 520px) {
  .LotInput {
    width: 7rem;
  }
}

.LotNotes {
  width: 100%;
  resize: vertical;
}
@media (min-width: 520px) {
  .LotNotes {
    flex: 1;
    min-width: 6rem;
    width: auto;
  }
}

.LotSubmit {
  width: 4rem;
  padding: 0.25rem 0.5rem;
}

.LotsPageLayout {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

.AlphaBar {
  position: sticky;
  top: var(--app-header-height);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  width: 1.4rem;
  max-height: calc(100vh - var(--app-header-height));
  overflow-y: auto;
  scrollbar-width: none;
}
.AlphaBar::-webkit-scrollbar {
  display: none;
}

.AlphaBar__letter {
  display: block;
  text-align: center;
  font-size: 0.85rem;
  line-height: 1.65;
  border-radius: 3px;
  text-decoration: none;
  color: #527070;
}
.AlphaBar__letter:not(.AlphaBar__letter--missing):hover {
  background-color: #105151;
  color: white;
}
.AlphaBar__letter--missing {
  color: #e3dccb;
  cursor: default;
}

.LotsGrid__letterAnchor {
  scroll-margin-top: calc(var(--app-header-height) + 0.5rem);
}

.LotsGrid {
  flex: 1;
  min-width: 0;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #e3dccb;
}

.LotsGrid__hint {
  font-size: 0.75rem;
  color: #527070;
  padding: 0.3rem 0.6rem;
  border-bottom: 1px solid #e3dccb;
  background-color: rgba(255, 255, 255, 0.4);
}

.LotsRow {
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid #e3dccb;
}
.LotsRow:last-child {
  border-bottom: none;
}
.LotsRow:nth-child(even) {
  background-color: rgba(0, 0, 0, 0.03);
}

.LotsRow__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

.LotsRow__species {
  font-size: 0.9rem;
  font-weight: 600;
}

.LotNewLink {
  font-size: 0.75rem;
  white-space: nowrap;
  flex-shrink: 0;
}

.LotsRow__lots {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.LotAccessionGroup {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.LotAccessionGroup--grouped {
  background-color: #ece5d3;
  border-radius: 5px;
  padding: 0.4rem;
  gap: 0.3rem;
}

.LotGroupHeader {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.2rem 0.5rem;
  border-radius: 3px;
  border-left-width: 3px;
  border-left-style: solid;
  background-color: var(--color-bg-light);
  font-size: 0.85rem;
}

.LotGroupHeader__label {
  font-size: 0.72rem;
  color: #527070;
  font-style: italic;
  margin-right: 0.25rem;
}

.LotGroupHeader__counts {
  display: flex;
  gap: 0.75rem;
}

.LotBox__footer {
  display: flex;
  align-items: center;
  margin-top: 0.3rem;
}

.LotBox__lastCounted {
  font-size: 0.75rem;
  color: #527070;
  margin-left: auto;
}

.LotBox__addCountToggle {
  margin-left: 0.5rem;
}

.LotImportedBadge {
  margin-left: 0.5rem;
  font-size: 0.72rem;
  color: #527070;
  font-style: italic;
}

.LotsRow__form {
  min-width: 0;
  width: 100%;
}

.LotBox {
  border-radius: 3px;
  padding: 0.3rem 0.5rem;
}

.LotBoxSummary {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.25rem;
}
@media (min-width: 520px) {
  .LotBoxSummary {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    min-height: 1.8em;
  }
}

.LotBoxRow {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.LotBoxRow--header {
  justify-content: space-between;
}

.LotBoxRow--counts {
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
}

.LotBoxDate {
  flex-shrink: 0;
  white-space: nowrap;
  font-size: 0.85rem;
}

.LotBoxHeaderMain {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 0;
}

.LotNoPriceFlag {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1;
  color: #fff;
  background-color: rgb(177, 75.5, 69.5);
  border-radius: 3px;
  text-decoration: none;
}
.LotNoPriceFlag:hover {
  background-color: rgb(147.7034482759, 63.0034482759, 57.9965517241);
}

.LotBoxCounts {
  white-space: nowrap;
  font-size: 0.85rem;
}
@media (min-width: 520px) {
  .LotBoxCounts {
    padding-left: 0.5rem;
    border-left: 1px dashed #e3dccb;
    min-width: 9rem;
  }
}

.LotCountLabel {
  color: #527070;
  margin-right: 0.15rem;
}

.LotCountBreakdown {
  font-size: 0.78rem;
  color: #527070;
}

.LotBoxActions {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: auto;
  flex-shrink: 0;
}

.LotBoxNotes {
  width: 100%;
  font-size: 0.8rem;
  color: #527070;
  font-style: italic;
  word-break: break-word;
  white-space: pre-wrap;
}

.LotEditToggle {
  font-size: 0.9rem;
  line-height: 1;
}

.LotDropdownToggle {
  font-size: 0.78rem;
  padding: 0.1rem 0.35rem;
  background: none;
  border: 1px solid #e3dccb;
  border-radius: 3px;
  cursor: pointer;
  color: #527070;
  line-height: 1.4;
  white-space: nowrap;
}
.LotDropdownToggle:hover {
  background-color: rgba(0, 0, 0, 0.05);
  color: #1f3d3d;
}

.LotFinalBadge {
  display: inline-flex;
  align-items: center;
  font-size: 0.72rem;
  font-weight: 600;
  color: rgb(9.2701030928, 46.9298969072, 46.9298969072);
  background-color: rgb(158.4346391753, 235.9253608247, 235.9253608247);
  border: 1px solid rgb(39.8432989691, 201.7067010309, 201.7067010309);
  border-radius: 3px;
  padding: 0.05rem 0.35rem;
  white-space: nowrap;
}

.LotUnmarkFinal {
  font-size: 0.72rem;
  padding: 0.05rem 0.3rem;
  background: none;
  border: 1px solid #e3dccb;
  border-radius: 3px;
  cursor: pointer;
  color: #527070;
  line-height: 1.4;
}
.LotUnmarkFinal:hover {
  background-color: rgb(240.3, 202.15, 195.85);
  border-color: rgb(177, 75.5, 69.5);
  color: #5d091f;
}

.LotFinalLabel {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.82rem;
  cursor: pointer;
  white-space: nowrap;
  color: #527070;
}

.LotFinalCheckbox {
  cursor: pointer;
}

.LotCountHistory {
  border-radius: 4px;
  border: 1px solid #e3dccb;
  overflow: hidden;
}

.LotCountHistoryRow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-end;
  gap: 0.3rem 0.75rem;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid #e3dccb;
  font-size: 0.9rem;
}
.LotCountHistoryRow:last-child {
  border-bottom: none;
}
.LotCountHistoryRow:nth-child(even) {
  background-color: rgba(0, 0, 0, 0.03);
}

.LotCountHistoryRow__meta {
  white-space: nowrap;
  color: #527070;
  font-size: 0.85rem;
  flex: 1;
}

.LotCountHistoryRow__counts {
  display: flex;
  justify-content: space-between;
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 7rem;
}

.LotCountHistoryRow__notes {
  flex-basis: 100%;
  font-size: 0.85rem;
}
.LotCountHistoryRow__notes p {
  margin: 0;
}

.LotCountHistoryRow__editForm {
  width: 100%;
  padding-top: 0.4rem;
}

.SaleItemRow.lot-count-final {
  background-color: rgb(186.024742268, 241.375257732, 241.375257732);
}

.LotFinalNote {
  display: block;
  font-size: 0.7rem;
  color: rgb(11.793814433, 59.706185567, 59.706185567);
}

.LotSalesNotes {
  display: block;
  font-size: 0.75rem;
  color: #1f3d3d;
  margin-top: 0.1rem;
}

.LotPrivateBadge {
  font-size: 0.78rem;
  font-style: italic;
}

.LotShowHeader {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}
.LotShowHeader h1 {
  margin-bottom: 0;
}

.LotShowHeader__meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
}

.LotEditLink {
  font-size: 0.85rem;
  white-space: nowrap;
}

.StockTypeNameInput, .StockTypeIntervalsInput {
  width: 12rem;
}

.StockTypeUnitLabelInput, .StockTypeUnitsPerLabelInput {
  width: 6rem;
}

.StockTypeSubmitButton {
  width: auto;
  padding-inline: 1rem;
}

/* Stacked label + input cells inside the inline stock type editor form. */
.InlineForm .StockTypeEditorField {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.InlineForm .StockTypeEditorField > label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  opacity: 0.7;
}
.InlineForm .StockTypeEditorField > textarea {
  width: 21rem;
}
.InlineForm .StockTypeEditorField > input[type=color] {
  height: 3rem;
}

/* Full-width separator that forces a flex line break and draws a subtle rule between field groups. */
.InlineForm .StockTypeEditorSeparator {
  flex-basis: 100%;
}

/* The "Lots bound by season" checkbox keeps its inline label styling. */
.InlineForm .StockTypeEditorField--checkbox {
  justify-content: flex-end;
}
.InlineForm .StockTypeEditorField--checkbox > label {
  flex-direction: row;
  align-items: center;
  gap: 0.25rem;
  font-size: inherit;
  font-weight: inherit;
  text-transform: none;
  letter-spacing: normal;
  opacity: 1;
}

.StockTypeList {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.25rem;
  list-style: none;
  border-radius: 0.5rem;
  background-color: #ece5d3;
  cursor: default;
}

/* Per-stock-type sizes, edited inline with the stock type they belong to. */
.InlineForm .StockTypeSizes {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.StockTypeSizes__label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  opacity: 0.7;
}

.StockTypeSizes__hint {
  margin: 0;
  max-width: 46rem;
  font-size: 0.8rem;
  color: #527070;
}

.StockTypeSizeRow {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid #e3dccb;
  border-radius: 0.35rem;
}
.StockTypeSizeRow--new {
  border-style: dashed;
}

.StockTypeSizeRow__field {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.StockTypeSizeRow__field input {
  width: 10rem;
}
.StockTypeSizeRow__field--narrow input {
  width: 4.5rem;
}

.StockTypeSizeRow__caption {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  opacity: 0.7;
}

.StockTypeSizeRow__toggle {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding-bottom: 0.3rem;
  font-size: 0.85rem;
  white-space: nowrap;
}
.StockTypeSizeRow__toggle--destroy {
  color: rgb(177, 75.5, 69.5);
}

.StockTypeSizeRow__locked {
  color: #527070;
  font-style: italic;
  cursor: help;
}

/* Phones: one field per line rather than a squeezed single row. */
@media (max-width: 600px) {
  .StockTypeSizeRow__field input {
    width: 100%;
  }
  .StockTypeSizeRow__field {
    flex: 1 1 100%;
  }
  .StockTypeSizeRow__field--narrow {
    flex: 0 0 6rem;
  }
  .StockTypeSizeRow__field--narrow input {
    width: 100%;
  }
}
/* Availability rules on the stock types page (docs/species_classification_architecture.md §9.1) */
.StockTypeAvailabilityGroup {
  padding-left: 0.75rem;
  margin-bottom: 1.25rem;
}
.StockTypeAvailabilityGroup__name {
  display: block;
  margin-bottom: 0.25rem;
  font-weight: 600;
}
.StockTypeAvailabilityGroup__add {
  margin-top: 0.25rem;
}
.StockTypeAvailabilityGroup__toggle {
  background: none;
  border: none;
  padding: 0.25rem 0;
  color: #0d6969;
  font-size: 0.9em;
  cursor: pointer;
}
.StockTypeAvailabilityGroup__toggle:hover {
  text-decoration: underline;
}
.VoggleChild.BoxContainer .StockTypeAvailabilityGroup__toggle {
  margin-top: 0.5rem;
}

.StockTypeAvailabilityList {
  list-style: none;
  padding: 0;
  margin: 0;
}
.StockTypeAvailabilityList__item {
  margin-bottom: 0.5rem;
  padding: 0.5rem 0.75rem;
}
.StockTypeAvailabilityList__frame {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}
.StockTypeAvailabilityList__text {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.35rem;
  align-items: baseline;
}
.StockTypeAvailabilityList__window {
  font-weight: 600;
  white-space: nowrap;
}
.StockTypeAvailabilityList__scope, .StockTypeAvailabilityList__label {
  color: #666;
  font-size: 0.9em;
}
.StockTypeAvailabilityList__actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  white-space: nowrap;
}
.StockTypeAvailabilityList__empty {
  padding: 0.25rem 0;
  font-size: 0.9em;
}

/* The inline add/edit form: one row on a desk, one column on a phone. */
.InlineForm.AvailabilityForm {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
.InlineForm.AvailabilityForm .AvailabilityForm__errors {
  flex-basis: 100%;
  margin: 0 0 0.25rem;
  padding-left: 1.25rem;
  color: #d56856;
  font-size: 0.9em;
}
.InlineForm.AvailabilityForm .AvailabilityForm__field {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
}
.InlineForm.AvailabilityForm .AvailabilityForm__label {
  color: #666;
  font-size: 0.85em;
  white-space: nowrap;
}
.InlineForm.AvailabilityForm .AvailabilityForm__label--to {
  margin-left: 0.25rem;
}
.InlineForm.AvailabilityForm .AvailabilityAppliesToInput {
  width: 220px;
}
.InlineForm.AvailabilityForm .AvailabilityForm__select {
  max-width: 220px;
}
.InlineForm.AvailabilityForm .AvailabilityMonthInput {
  width: 80px;
}
.InlineForm.AvailabilityForm .AvailabilityDayInput {
  width: 60px;
}
.InlineForm.AvailabilityForm .AvailabilityLabelInput {
  width: 160px;
}
.InlineForm.AvailabilityForm .DateRangeGroup {
  white-space: nowrap;
}
.InlineForm.AvailabilityForm .AvailabilityForm__actions {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

@media (max-width: 600px) {
  .InlineForm.AvailabilityForm {
    flex-direction: column;
    align-items: stretch;
  }
  .InlineForm.AvailabilityForm .AvailabilityForm__field {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.2rem;
  }
  .InlineForm.AvailabilityForm .DateRangeGroup {
    display: grid;
    grid-template-columns: auto 1fr 1fr;
    align-items: center;
    gap: 0.35rem;
    white-space: normal;
  }
  .InlineForm.AvailabilityForm .AvailabilityForm__label--to {
    margin-left: 0;
  }
  .InlineForm.AvailabilityForm .AvailabilityAppliesToInput,
  .InlineForm.AvailabilityForm .AvailabilityForm__select,
  .InlineForm.AvailabilityForm .AvailabilityMonthInput,
  .InlineForm.AvailabilityForm .AvailabilityDayInput,
  .InlineForm.AvailabilityForm .AvailabilityLabelInput {
    width: 100%;
    max-width: none;
  }
  .StockTypeAvailabilityList__frame {
    align-items: flex-start;
  }
  .StockTypeAvailabilityList__actions {
    visibility: visible;
    flex-shrink: 0;
  }
}
/* Base shell both lists can share. minmax(0, 1fr) rather than the default auto
   column: an auto column is sized by its max-content, so one long row would
   widen the whole list and spill it out of its container. */
.SalesList, .PullListsIndex {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.5rem;
}

/* Muted aside inside a list heading (e.g. how the list is sorted) */
.SalesListHint {
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  opacity: 0.65;
  white-space: nowrap;
}

/* The per-row skeleton that both lists can reuse */
.SalesRow, .PullListRow, .SalesMenuListItem {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

/* The row's lead: date, number and eye, and the note/email icons hold the
   first line together; the customer name follows them while it fits and
   otherwise starts the next line, where it has the row's whole width before
   it truncates. The header group dissolves into the lead (display: contents)
   so the name is a wrap point of its own rather than dragging the number
   down with it. */
.SaleLead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
}

.SaleLead > .SalesRowHeader, .SalesMenuListItem .SaleLead > .SalesMenuListItemHeader {
  display: contents;
}

.SaleLead > .SaleDate,
.SaleLead .SaleIdent,
.SaleLead .NoteIcon,
.SaleLead .EmailProblemIcon {
  flex: none;
}

.SaleLead .SaleUser {
  flex: 0 1 auto;
}

.SalesRowHeader, .SalesMenuListItem .SalesMenuListItemHeader {
  display: grid;
  grid-auto-flow: column;
  align-items: center;
  gap: 0.5rem;
}

.SaleNumber {
  font-weight: 700;
}

/* A sale number that opens the dock. It reads as part of the line until you
   approach it, then shows its edges — an affordance without a second accent
   color on a row already dense with badges, and without a glyph that every
   row would wear alike. The negative margin cancels the padding, so the chip
   costs no layout and the number stays on the row's text grid.

   Qualified with `a` so the hover rule ties `.SalesRow a:hover` on specificity
   and wins on source order: this chip is not underlined, it fills in. */
a.SaleNumberLink {
  display: inline-flex;
  align-items: baseline;
  padding: 0.1em 0.4em;
  margin: -0.1em -0.4em;
  border: 1px solid transparent;
  border-radius: 5px;
  color: inherit;
  text-decoration: none;
  transition: background-color 0.12s ease-in-out, border-color 0.12s ease-in-out;
}
a.SaleNumberLink:hover, a.SaleNumberLink:focus-visible {
  background: var(--color-bg-light);
  border-color: var(--color-border);
  text-decoration: none;
}

/* The eye beside the number that opens sales#show. Quiet until approached,
   like the number chip, so it does not compete with the row's badges. */
a.SalePageLink {
  display: inline-flex;
  align-items: center;
  color: inherit;
  opacity: 0.45;
  transition: opacity 0.12s ease-in-out;
}
a.SalePageLink:hover, a.SalePageLink:focus-visible {
  opacity: 1;
}

/* The row's lead — date, then number and eye — in slots of a fixed size on
   the index and the dashboard, so the names after them line up down the list.
   Tabular digits make every m/d/yy and YY-NNN the same width as its
   neighbours; min-width rather than width, so a longer one (a four-digit
   sequence) widens its own row instead of being clipped. */
.SalesRow--index .SaleDate,
.SalesRow--index .SaleIdent,
.SalesRow--dashboard .SaleIdent {
  font-variant-numeric: tabular-nums;
}

.SalesRow--index .SaleDate {
  min-width: 8ch;
}

.SaleIdent {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.SalesRow--index .SaleIdent,
.SalesRow--dashboard .SaleIdent {
  min-width: 9ch;
}

.SaleSummary {
  font-weight: 500;
}

.SaleDate {
  opacity: 0.75;
}

.SaleUser {
  font-size: 0.9rem;
  color: rgb(27.9, 54.9, 54.9);
}

.SaleStatus {
  font-size: 0.85rem;
  color: rgb(23.25, 45.75, 45.75);
}

/* The top line is two parts that never trade places: `.RowContent`, which wraps
   as freely as it needs to, and `.RowActions`, which does not. Splitting them is
   what keeps the comment button and the chevron in the row's top-right corner
   however many lines the content takes — as flat children of a wrapping flex row
   the pair dropped onto a line of its own the moment a total, a customer name or
   a badge grew.

   `align-items` stays at its `stretch` default so a one-line row still reads
   centered: the content group fills the row height (set by the taller action
   buttons) and centers its single line inside it. */
.RowMain, .PullListRow .RowMain {
  display: flex;
  gap: 0.5rem;
  width: 100%;
  min-width: 0;
}
.RowMain span, .PullListRow .RowMain span {
  white-space: nowrap;
}

.RowContent {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-width: 0;
}

/* Comments and the chevron (just comments on a menu row), pinned to the row's
   top-right corner — the one spot that does not move as a row's name, totals,
   status or badges change length, and the only one a reader can aim at without
   looking. */
.RowActions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex: 0 0 auto;
  margin-left: auto;
  align-self: flex-start;
}

/* Flex/grid children default to min-width:auto, which lets a long customer or
   company name push past the row and collide with its neighbors. Let them
   shrink, and truncate the name rather than overflow. */
.RowMain > *, .PullListRow .RowMain > *,
.RowContent > *,
.SaleLead > *,
.SalesRowHeader,
.SalesMenuListItem .SalesMenuListItemHeader,
.SalesRowHeader > *,
.SalesMenuListItem .SalesMenuListItemHeader > * {
  min-width: 0;
}

.SaleUser {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The chevron. `.RowActions` places it; this is only its surface.

   color: inherit is load-bearing: it resolves to $text-dark on the index variant
   and $text-light on the menu variant, so one chevron serves both. The hover
   fill is therefore derived from currentColor rather than being its own token —
   a 12% tint of the glyph color can never collide with the glyph itself, in
   either variant, however the variant colors move later. */
.RowExpand, .PullListRow .RowExpand {
  flex: 0 0 auto;
  border: 0;
  background: transparent;
  padding: 0.25rem;
  line-height: 0;
  cursor: pointer;
  color: inherit;
  border-radius: 999px;
  transition: transform 0.15s ease, background-color 0.15s ease;
}
.RowExpand:hover {
  background: color-mix(in srgb, currentColor 12%, transparent);
}

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

/* Narrow screens: let the header stack instead of squeezing everything onto one
   line, and allow the summary/status text to wrap. */
@media (max-width: 640px) {
  .SalesRow, .PullListRow, .SalesMenuListItem {
    position: relative;
    padding: 0.5rem 0.75rem;
  }
  /* The lead takes the whole first line, so the money summary always starts
     the second — a row with no customer otherwise pulls it up beside the
     number and leaves the status wrapping alone. */
  .SaleLead {
    flex: 1 1 100%;
  }
  /* The number/customer group keeps its single line and truncates the name (the
     expanded panel has the full contact details); the money summary and status
     wrap instead of running off the row. The nested spans need it too — the
     per-stock-type counts are their own spans and inherit .RowMain's nowrap. */
  .SaleSummary,
  .SaleSummary span,
  .SaleStatus,
  .SaleStatus span {
    white-space: normal;
  }
}
/* Details span full row width beneath. Single column: the items table needs the
   whole width, since line totals can run to hundreds of thousands of dollars. */
.SaleRowDetails, .PullListDetails {
  display: grid;
  gap: 0.5rem 1rem;
  width: 100%;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
  padding-top: 0.5rem;
}

.SaleRowDetails[hidden], [hidden].PullListDetails {
  display: none !important;
}

/* sales#show: the same panel, open on its own page. The row's divider has no
   header above it to divide from here. */
.SaleShow {
  border-top: 0;
  padding-top: 0;
}

.SaleShow__customer {
  font-weight: 400;
}

.SaleShow__summary {
  margin: 0.25rem 0 0.75rem;
}

/* The customer's card (users/_contact_card), under the dates. What the
   customer typed at order time sits in the .CustomerNotes box beneath it
   (sales/_customer_notes — the same partial, and the same box, as the sale
   form). */
.SaleRowCustomer {
  min-width: 0;
}

.SaleRowMeta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1.25rem;
  font-size: 0.85rem;
}

.SaleRowMetaItem {
  white-space: nowrap;
}

/* The sale's form and its documents, as quiet links beside the dates. */
.SaleRowLinks {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.75rem;
  white-space: normal;
}

.SaleRowLink {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  white-space: nowrap;
}

/* The steps a sale moves through (sales/_progress): a check for each one
   reached, with when and by whom beneath it; an empty ring for the rest. */
.SaleProgress {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
}

.SaleProgress__step {
  display: flex;
  align-items: flex-start;
  gap: 0.35rem;
}

.SaleProgress__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.05rem;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  opacity: 0.35;
}
.SaleProgress__mark svg {
  width: 0.8rem;
  height: 0.8rem;
}

.SaleProgress__step.is-done .SaleProgress__mark {
  background: #1c723b;
  border-color: #1c723b;
  color: #fff;
  opacity: 1;
}

.SaleProgress__step.is-cancelled .SaleProgress__mark {
  background: rgb(177, 75.5, 69.5);
  border-color: rgb(177, 75.5, 69.5);
  color: #fff;
  opacity: 1;
}

.SaleProgress__text {
  display: grid;
  line-height: 1.2;
}

.SaleProgress__label {
  font-weight: 600;
}

.SaleProgress__stamp {
  font-size: 0.78rem;
  opacity: 0.65;
  white-space: nowrap;
}

.SaleProgress__step.is-todo .SaleProgress__text {
  opacity: 0.5;
}

.SaleProgress__reason {
  font-size: 0.85rem;
}

.SaleRowMetaLabel {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
  margin-right: 0.15rem;
}

/* The sale's own notes, in full. The label wears the same tooltip as the
   form's field ("To customer" — where it goes; "Internal" — who sees it). */
.SaleRowNotes {
  display: grid;
  gap: 0.25rem;
  font-size: 0.85rem;
}

.SaleRowNote {
  overflow-wrap: anywhere;
}

.SaleRowNoteLabel {
  font-weight: 600;
  opacity: 0.7;
  margin-right: 0.25rem;
}
.SaleRowNoteLabel::after {
  content: ":";
}

/* Typed into a textarea, so the line breaks were meant. */
.SaleRowNoteText {
  white-space: pre-line;
}

/* The form's status-panel cluster (pull lists, pickups & deliveries,
   QuickBooks) inside the expanded row. `contents` rather than the form's flex
   column: the panels become items of the row's own grid and share its gap,
   and — since every wrapper inside is `contents` too — a row with nothing to
   report in any of the three costs no empty cell and no stray gap. Doubled
   up so it outranks the cluster's own `display: flex` (sale_dock.scss). */
.SaleStatusPanels.SaleRowPanels {
  display: contents;
}

/* Sale items */
.SaleItemsTable {
  margin-top: 0px;
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95em;
}

.SaleItemsTable th, .SaleItemsTable td {
  padding: 0.2rem 0.4rem;
}

.SaleItemsTable thead th {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
  opacity: 0.7;
}

.SaleItemsTable .num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Percentage widths under table-layout: fixed spill their contents into the next
   column — a six-figure line total or "0.25 qt" simply overflowed. The name
   column absorbs the slack instead and everything else sizes to its content
   (width: 1% is the shrink-to-fit idiom for an auto table). */
/* The item name is the only column allowed to wrap, so it gives up width first */
.SaleItemsTable .col-name {
  min-width: 6rem;
  overflow-wrap: anywhere;
}

.SaleItemAccession {
  display: block;
  font-size: 0.8em;
  opacity: 0.6;
  overflow-wrap: anywhere;
}

.SaleItemsTable .col-type {
  width: 1%;
  white-space: nowrap;
}

.SaleItemsTable .col-size {
  width: 1%;
  white-space: nowrap;
  opacity: 0.75;
}

.SaleItemsTable .col-qty {
  width: 1%;
}

.SaleItemsTable .col-unit {
  width: 1%;
}

.SaleItemsTable .col-total {
  width: 1%;
  font-weight: 600;
}

/* Spans the unit and total columns on an unpriced row */
.SaleItemsTable .col-no-pricing {
  width: 1%;
  white-space: nowrap;
}

.SaleItemsTable tfoot th,
.SaleItemsTable tfoot td {
  border-top: 1px solid rgba(0, 0, 0, 0.12);
  padding-top: 0.35rem;
}

.SaleItemsTable tfoot th {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
  opacity: 0.7;
}

/* The stock type's color (set inline as --st-row-tint), laid on as an image
   as the sale form's lines lay it on, so an unpriced row keeps its warning
   background under it. */
.SaleItemsTable tbody tr {
  background-image: linear-gradient(var(--st-row-tint, transparent), var(--st-row-tint, transparent));
}

/* Optional light row stripes, as a background-color so they sit under the
   tint rather than wiping it out. Unpriced rows sit this out: their warning
   background is the signal. */
.SaleItemsTable tbody tr:nth-child(odd):not(.needs-pricing) {
  background-color: rgba(0, 0, 0, 0.02);
}

/* Small screens: hide the header and give each item two lines — what identifies
   it (type, size, name, accession) above what it costs (qty, unit, total) */
@media (max-width: 640px) {
  .SaleItemsTable thead {
    display: none;
  }
  .SaleItemsTable, .SaleItemsTable tbody, .SaleItemsTable tr, .SaleItemsTable td {
    display: block;
  }
  .SaleItemsTable tr {
    padding: 0.35rem 0;
  }
  .SaleItemsTable tr + tr {
    border-top: 1px solid rgba(0, 0, 0, 0.06);
  }
  .SaleItemsTable td {
    width: auto;
    min-width: 0;
    padding: 0 0.4rem;
  }
  /* Line 1. Inline rather than block so the three cells share a line and wrap
     only when they have to; the accession gives up its own line here. */
  .SaleItemsTable .col-name {
    display: inline;
    font-weight: 600;
  }
  .SaleItemsTable .col-name .SaleItemAccession {
    display: inline;
  }
  .SaleItemsTable .col-type,
  .SaleItemsTable .col-size {
    display: inline;
  }
  /* A table row has nothing to wrap the two groups in, so the break between
     them is a preserved newline after the last cell of line 1 (which has to
     stay inline for the newline to break the row's line rather than its own).
     That last cell is the item name now that type and size lead the row. */
  .SaleItemsTable .col-name::after {
    content: "\a";
    white-space: pre;
  }
  /* Line 2 */
  .SaleItemsTable .col-qty,
  .SaleItemsTable .col-unit,
  .SaleItemsTable .col-total,
  .SaleItemsTable .col-no-pricing {
    display: inline-block;
    width: auto;
    margin-right: 0.5rem;
    text-align: left;
  }
  /* QTY/UNIT/TOTAL prefixes stood in for the hidden header, but they cost more
     width than the figures themselves and pushed the total onto a third line.
     The figures carry their own meaning as a receipt line instead:
     "4.00 qts @ $131.24  $524.96" (the quantity keeps its unit label, and the
     line total is the bold one). */
  .SaleItemsTable .col-unit::before {
    content: "@ ";
    opacity: 0.55;
  }
  /* The total keeps its own line, label and figure side by side. */
  .SaleItemsTable tfoot {
    display: block;
  }
  .SaleItemsTable tfoot tr {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
  }
  .SaleItemsTable tfoot th,
  .SaleItemsTable tfoot td {
    display: inline-block;
    width: auto;
    text-align: left;
  }
}
/* Right side: info at top, totals pinned bottom */
.RowDetailsSide {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

.RowDetailsTop {
  text-align: right;
}

/* Right-aligned contact info reads as a mistake once it is no longer a column */
@media (max-width: 720px) {
  .RowDetailsTop {
    text-align: left;
  }
}
.RowDetailsLeft {
  text-align: left;
  display: flex;
  flex-direction: column;
  /* Last-resort escape hatch: if even the wrapped name column cannot give up
     enough width, the table scrolls instead of pushing the page sideways. */
  overflow-x: auto;
}

/* ===== Variants ===== */
/* Right-side menu variant */
.SalesList--menu {
  background: rgba(10, 84, 84, 0.97);
  color: #ffffff;
}

.SalesList--menu .SalesRow, .SalesList--menu .PullListRow, .SalesList--menu .SalesMenuListItem {
  border-color: rgba(255, 255, 255, 0.1);
  color: #ffffff;
}

.SalesList--menu .SaleUser,
.SalesList--menu .SaleStatus {
  color: rgb(178.5, 178.5, 178.5);
}

/* The menu is a 20vw panel, so its rows wrap the way the 640px breakpoint
   makes every row wrap: the name, the money summary and the status break
   rather than run off the panel under `.RowMain`'s nowrap. The comment
   button still holds the top-right corner — `.RowActions` does that, not the
   wrapping. */
.SalesRow--menu .RowMain span {
  white-space: normal;
}

/* Index page variant (light/neutral) */
.SalesList--index, .PullListsIndex {
  color: #1f3d3d;
}

.SalesList--index .SalesRow, .PullListsIndex .SalesRow, .SalesList--index .PullListRow, .PullListsIndex .PullListRow, .SalesList--index .SalesMenuListItem, .PullListsIndex .SalesMenuListItem {
  border-color: rgba(0, 0, 0, 0.06);
  background-color: var(--color-bg-dark);
}

.SalesList--index .SaleUser, .PullListsIndex .SaleUser,
.SalesList--index .SaleStatus,
.PullListsIndex .SaleStatus {
  color: rgb(21.7, 42.7, 42.7);
}

/* ===== Compatibility layer (so you don't have to rename markup today) ===== */
/* A tiny component you can reuse anywhere */
.ChipGroup {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.5rem;
}

.Chip {
  --chip-border: rgba(0,0,0,.18);
  --chip-accent: #527070;
  --chip-active-bg: color-mix(in srgb, var(--chip-accent) 16%, transparent);
  --chip-focus: color-mix(in srgb, var(--chip-accent) 35%, transparent);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.7rem;
  border: 2px solid var(--chip-border);
  border-radius: 9999px;
  background: transparent;
  color: inherit;
  font-size: 0.9rem;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.Chip input[type=checkbox],
.Chip input[type=radio] {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: inherit;
  /* forms.scss now sizes every box at 1.1em; auto lets inset stretch this
     invisible one back across the whole chip so it stays the hit target. */
  width: auto;
  height: auto;
}
.Chip span {
  pointer-events: none;
}
.Chip.StockTypeChip {
  border-color: color-mix(in srgb, var(--stock-color) 35%, transparent);
  color: rgb(178.5, 178.5, 178.5);
}
.Chip.StockTypeChip:has(input:checked) {
  color: var(--color-text-light);
  border-color: var(--stock-color);
  background: color-mix(in srgb, var(--stock-color) 16%, transparent);
}
.Chip.StockTypeChip:not(:has(input:checked)) {
  opacity: 0.5;
  background: transparent;
}

.Chip:hover {
  border-color: rgba(0, 0, 0, 0.34);
}

.Chip:has(input:focus-visible) {
  box-shadow: 0 0 0 2px var(--chip-focus);
}

.Chip:has(input:checked) {
  border-color: var(--chip-accent);
  background: var(--chip-active-bg);
  color: #1f3d3d;
}

#SalesMenu,
#SaleDock {
  top: var(--app-header-height);
  height: calc(100vh - var(--app-header-height));
  position: fixed;
  right: 0;
}

#SalesMenu {
  z-index: var(--z-menu);
  width: var(--sales-menu-width);
  transform: translateX(100%);
  transition: transform var(--dock-transition-duration) var(--dock-transition-ease);
  will-change: transform;
  background-color: rgba(10, 84, 84, 0.97);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cg stroke='rgb(255,255,255)' stroke-opacity='0.045'%3E%3Cpath fill='none' stroke-width='1' d='M-1 1L1 -1M0 12L12 0M11 13L13 11'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 12px 12px;
  background-attachment: scroll;
  color: #ffffff;
  border-left: 1px solid rgba(255, 255, 255, 0.2);
  display: flex;
  flex-direction: column;
  overscroll-behavior: contain;
}
@media print {
  #SalesMenu {
    background-image: none;
  }
}
#SalesMenu ul {
  list-style: none;
  padding: 0;
}
#SalesMenu li {
  padding: 1rem;
}
#SalesMenu a {
  color: #ffffff;
}

html.sales-menu-open #SalesMenu {
  transform: translateX(0);
}

.SalesMenuHeader {
  padding: 0.5rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.NewSaleButton {
  background-color: #105151;
  color: #ffffff;
  border: 1px solid #105151;
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  font-weight: 700;
}
.NewSaleButton:hover {
  background-color: #166b6b;
}

.FiltersRow {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 0.5rem;
}

/* ensure controls fill their grid cell */
.FiltersRow input,
.FiltersRow select {
  width: 100%;
}

/* Use the Chip component here */
#SalesFilterForm .StockTypeFilters {
  margin-top: 0rem;
  padding: 0.25rem 0.25rem 0.5rem;
}

#SalesFilterForm .StockTypeFilters label.Checkbox {
  margin-top: 0rem;
}

/* turbo-frame is an inline element by default, so it needs to be told to behave as
   the flex child that owns the remaining column height. */
#SalesMenu turbo-frame#sales_menu_list {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.SalesMenuMeta {
  padding: 0.35rem 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: rgb(191.25, 191.25, 191.25);
}

.SalesMenuScroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

#SalesMenuList {
  padding: 0.5rem;
  /* The panel already paints the menu surface. The list used to paint its own
     translucent layer on top of it, which left a visible seam wherever a short list
     ended — the doubled background stopped and the page underneath started showing
     through the panel's single layer. */
  background: transparent;
}

/* Loading placeholder and "nothing matched" message */
.SalesMenuNotice {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem 0.5rem;
  text-align: center;
  color: #cccccc;
}

/* Legacy names kept; the visuals now come from shared .SalesRow* */
.SalesMenuListItem {
  color: #ffffff;
}

.SalesMenuListItem .SaleUser,
.SalesMenuListItem .SaleStatus {
  color: rgb(178.5, 178.5, 178.5);
}

/* The sale number's chip lifts off whatever surface it sits on. Out on the
   light canvas that is the cream wash `.SaleNumberLink` ships with; here the
   chrome is dark and the text is $text-light, so cream-on-white would swallow
   the number on hover. Same move .NewSaleButton makes above — go brighter than
   the surface rather than lighter than the page — in the translucent white
   this panel already borders itself with. */
#SalesMenu a.SaleNumberLink:hover, #SalesMenu a.SaleNumberLink:focus-visible {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.28);
}

.SalesStatsBar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1.2rem;
  padding: 0.45rem 0.75rem;
  margin-bottom: 0.5rem;
  background: #ece5d3;
  border-radius: 6px;
  font-size: 0.82rem;
  color: #527070;
}
.SalesStatsBar__group {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.SalesStatsBar__label {
  font-weight: 600;
  color: #1f3d3d;
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}
.SalesStatsBar__value {
  font-weight: 700;
  color: #105151;
  font-size: 0.92rem;
}
.SalesStatsBar__sub {
  color: #527070;
  font-size: 0.75rem;
}
.SalesStatsBar__states {
  gap: 0.25rem;
}
.SalesStatsBar__state {
  color: #1f3d3d;
  font-size: 0.8rem;
}
.SalesStatsBar__dot {
  color: #527070;
  font-size: 0.7rem;
  padding: 0 0.1rem;
}
.SalesStatsBar .StockTypeStats {
  display: inline-flex;
  align-items: center;
  gap: 0;
}
.SalesStatsBar .StockTypeStat {
  font-size: 0.82rem;
  font-weight: 600;
}

/* The filter row mixes a search box, a select, a date pair and a link — the
   shared .FiltersRow grid would stretch each to an equal cell, so flex sizes
   them to their content, and wraps on a phone. */
#SalesIndexFilters .FiltersRow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
#SalesIndexFilters .FiltersRow input, #SalesIndexFilters .FiltersRow select {
  width: auto;
}
#SalesIndexFilters .FiltersRow .OmniSearch {
  flex: 1 1 16rem;
  max-width: 22rem;
}

.SalesIndexFilters__dates {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}
.SalesIndexFilters__dates label {
  font-weight: 600;
}

.SalesIndexFilters__online {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
  cursor: pointer;
}

.SalesIndexFilters__clear {
  white-space: nowrap;
}

/* ===== Sale Dock (snaps to menu) ===== */
#SaleDock {
  z-index: var(--z-dock);
  width: var(--dock-width-closed);
  transform: translateX(100%);
  will-change: transform;
  transition: transform var(--dock-transition-duration) var(--dock-transition-ease), width var(--dock-transition-duration) var(--dock-transition-ease);
  background: #fff;
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  overscroll-behavior: contain;
}

#SaleDock.Open {
  transform: translateX(0);
}

html.sales-menu-open #SaleDock {
  width: var(--dock-width-open);
}

html.sales-menu-open #SaleDock.Open {
  transform: translateX(var(--dock-offset-when-menu-open));
}

/* ===== Header ===== */
#SaleDock .SaleDockHeader {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0.75rem;
  gap: 0.5rem;
  background: #fff;
  color: #1f3d3d;
  border-bottom: 1px solid #e3dccb;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02);
}

/* Header grouping */
#SaleDock .SaleDockHeader .Left,
#SaleDock .SaleDockHeader .Right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Prevent long titles from crowding right side */
#SaleDock .SaleDockHeader .Left {
  flex: 1;
  min-width: 0;
}

/* NEW: Wrapper for dynamic header content */
:is(#SaleDock, .SalePage) .SaleDockTitleWrapper {
  flex: 1;
  min-width: 0;
}

/* Legacy title (used as fallback) */
#SaleDock .SaleDockHeader .Title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* NEW: Rich header content */
:is(#SaleDock, .SalePage) .SaleDockHeaderContent {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

:is(#SaleDock, .SalePage) .SaleDockTitle {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

:is(#SaleDock, .SalePage) .SaleDockMeta {
  display: flex;
  flex-wrap: wrap;
  /* Tight row gap: on a narrow dock the items wrap onto their own lines, and a
     .75rem gap between them reads as a paragraph break at this font size. */
  gap: 0.15rem 0.75rem;
  font-size: 0.75rem;
  color: rgb(88.7086956522, 170.4913043478, 170.4913043478);
  line-height: 1.2;
}

:is(#SaleDock, .SalePage) .MetaItem {
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

/* Responsive: stack metadata on narrow docks */
@media (max-width: 400px) {
  :is(#SaleDock, .SalePage) .SaleDockMeta {
    flex-direction: column;
    gap: 0.25rem;
  }
}
/* ===== Full-page form (sales/_page) ===== */
/* sales#edit and #new — where a phone opens a sale, having no dock. It shares
   every form rule below through `:is(#SaleDock, .SalePage)`; what is here is
   only the frame the dock would otherwise give it. A dock's width is what the
   form is drawn for, so a wide screen gets a column, not a stretched form. */
.SalePage {
  max-width: 44rem;
  margin: 0 auto;
}

.SalePageHeader {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
}

.SalePageHeader__title {
  flex: 1;
  min-width: 0;
}

.SalePageHeader__title .SaleDockTitle {
  font-size: 1.25rem;
}

.SalePageHeader__new {
  margin: 0;
}

.SalePageHeader__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
}

/* Bottom of the window, not of a dock body — clear the home indicator. */
.SalePage .SaleFormFooter {
  padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
}

/* A phone is narrower than any dock: the four stamp buttons alone fill the
   row, so Update moves up beside the totals (stacked, quantities over money)
   and the status buttons get the whole second row. */
@media (max-width: 520px) {
  .SalePage .SaleFormFooter .SaleTotals {
    grid-column: 1;
    grid-row: 1;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
  }
  .SalePage .SaleFormFooter .SubmitRow {
    grid-column: 2;
    grid-row: 1;
  }
  .SalePage .SaleFormFooter .DockActions {
    grid-column: 1/-1;
    grid-row: 2;
  }
  /* iOS Safari zooms the page into any field under 16px the moment it is
     focused, and leaves it zoomed. */
  .SalePage :is(input:not([type=submit], [type=button], [type=checkbox], [type=radio]), select, textarea) {
    font-size: 16px;
  }
}
/* Header buttons */
#SaleDock .SaleDockHeader .CloseButton {
  line-height: 1;
  border: 0;
  cursor: pointer;
  font-size: 1rem;
  padding: 0.35rem 0.5rem;
  border-radius: 0.25rem;
}
#SaleDock .SaleDockHeader .CloseButton:hover {
  background: var(--color-accent);
}

/* The dock's Docs menu sits in the header's right-hand cluster; the menu
   itself is styled once, app-wide, in sales/_docs_menu. */
:is(#SaleDock, .SalePage) .DocsMenuWrap {
  display: inline-flex;
  align-items: center;
}

/* Status badge */
:is(#SaleDock, .SalePage) .StatusBadge {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  border: 1px solid rgb(209.95, 244.8, 115.6);
  background: rgb(220.55, 247.2, 148.4);
  color: #1f3d3d;
}
:is(#SaleDock, .SalePage) .StatusBadge.is-confirmed {
  border-color: rgb(77.738028169, 211.461971831, 125.9408450704);
  background: rgb(190.003943662, 239.036056338, 207.6783098592);
  color: #1f3d3d;
}
:is(#SaleDock, .SalePage) .StatusBadge.is-cancelled {
  border-color: rgb(184.4215517241, 81.3465517241, 75.2534482759);
  background: rgb(240.3, 202.15, 195.85);
  color: #5d091f;
}

/* ===== Body wrapper (wraps the turbo-frame) ===== */
#SaleDock .SaleDockBody {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: auto;
  padding: 0.75rem;
  background-color: #fffdf7;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cg fill='rgb(16,81,81)' fill-opacity='0.3'%3E%3Ccircle cx='6' cy='6' r='1'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 12px 12px;
  background-attachment: local;
  border-left: 1px solid #e3dccb;
}
@media print {
  #SaleDock .SaleDockBody {
    background-image: none;
  }
}

/* The frame and .SaleForm grow to at least the body's height, so a short
   sale's footer can sit on the dock's bottom edge (margin-top: auto on
   .SaleFormFooter below) instead of right under its last line. `0 auto`, never
   shrinking: a long sale still overflows and scrolls the body as before. The
   frame is an inline custom element until told otherwise. */
#SaleDock #sale_dock_frame {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

#SaleDock .SaleForm {
  flex: 1 0 auto;
}

/* ===== Form-in-dock ===== */
/* .SaleForm is the wrapper that holds the header fields, the status panels and
   the <form> itself (.SaleForm__form, which opens at the line items — see
   sales/_form). Both stack the same way so the seam between them is invisible.
   No bottom padding: the sticky footer is the last thing in .SaleForm and sits
   flush against the bottom of the dock. */
:is(#SaleDock, .SalePage) .SaleForm,
:is(#SaleDock, .SalePage) .SaleForm__form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

:is(#SaleDock, .SalePage) .SaleForm {
  font-size: 14px;
  line-height: 1.3;
  color: #1f3d3d;
  background: rgba(255, 255, 255, 0.85);
}

:is(#SaleDock, .SalePage) .SaleForm h3 {
  margin: 0.25rem 0;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgb(73.2543478261, 144.1456521739, 144.1456521739);
}

:is(#SaleDock, .SalePage) .FormGrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

@media (max-width: 520px) {
  :is(#SaleDock, .SalePage) .FormGrid {
    grid-template-columns: 1fr;
  }
}
/* Field styling */
:is(#SaleDock, .SalePage) .Field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

:is(#SaleDock, .SalePage) .Field > label {
  font-size: 12px;
  font-weight: 600;
  color: rgb(45.0847826087, 88.7152173913, 88.7152173913);
}

/* Inputs */
:is(#SaleDock, .SalePage) .Field input[type=text],
:is(#SaleDock, .SalePage) .Field input[type=number],
:is(#SaleDock, .SalePage) .Field input[type=date],
:is(#SaleDock, .SalePage) .Field select,
:is(#SaleDock, .SalePage) .Field textarea {
  border-radius: 8px;
}

:is(#SaleDock, .SalePage) select {
  min-height: 36px;
}

:is(#SaleDock, .SalePage) input[type=number] {
  text-align: right;
}

/* ===== Remote user search dropdown ===== */
:is(#SaleDock, .SalePage) .RemoteUserPicker {
  position: relative;
}

:is(#SaleDock, .SalePage) .RemoteUserPicker .DropdownResults {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: var(--z-header);
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  max-height: 240px;
  overflow: auto;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
}

:is(#SaleDock, .SalePage) .RemoteUserPicker .ResultItem {
  padding: 0.75rem 1rem;
  cursor: pointer;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  transition: background-color 0.15s ease;
}
:is(#SaleDock, .SalePage) .RemoteUserPicker .ResultItem:last-child {
  border-bottom: none;
}
:is(#SaleDock, .SalePage) .RemoteUserPicker .ResultItem:hover {
  background: #fffdf7;
}

/* NEW: Rich result item structure */
:is(#SaleDock, .SalePage) .RemoteUserPicker .ResultItem__primary {
  font-size: 0.95rem;
  line-height: 1.4;
  color: #1f3d3d;
  margin-bottom: 0.25rem;
}
:is(#SaleDock, .SalePage) .RemoteUserPicker .ResultItem__primary strong {
  font-weight: 600;
}

:is(#SaleDock, .SalePage) .RemoteUserPicker .ResultItem__secondary {
  font-size: 0.85rem;
  line-height: 1.3;
  color: rgb(88.7086956522, 170.4913043478, 170.4913043478);
}

/* ===== Sale Items list ===== */
:is(#SaleDock, .SalePage) .SaleItems {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Row layout. The row is a column of [summary head, fields]; the fields keep
   the flex-row layout they always had (docs/done/pull_lists_architecture.md §15.2). */
:is(#SaleDock, .SalePage) .SaleItemRow {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid transparent;
  border-image: repeating-linear-gradient(to right, var(--color-bg-dark) 0 20px, transparent 20px 40px) 100% 1;
}

:is(#SaleDock, .SalePage) .SaleItemRow__fields {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: flex-end;
  width: 100%;
}

/* No flex-grow: a growing field eats the slack the price cluster needs to reach
   the right edge, which left it floating in the middle of the row. The fields
   take the width they ask for, in order, and .PriceGroup's margin-left: auto
   collects everything that is left. */
:is(#SaleDock, .SalePage) .SaleItemRow__fields > .Field {
  flex: 0 1 auto;
  min-width: 4rem;
  max-width: 12rem;
}

/* Remove moved out of the head and into the panel, so it is only on screen for
   a line someone deliberately opened. It rides at the end of the field line,
   directly after the price cluster.

   Deliberately no `margin-left: auto` of its own: two auto margins on one flex
   line *split* the free space between them, which is what left the price
   cluster stranded in the middle of the row instead of against the right edge.
   .PriceGroup owns the auto margin now and this follows it. */
:is(#SaleDock, .SalePage) .SaleItemRow__fields > .col--actions {
  flex: 0 0 auto;
  align-self: center;
}

/* Remove is a trash can, not a ×: a little larger than the base 24px, and
   centred for real now that it holds an SVG rather than a glyph. */
:is(#SaleDock, .SalePage) .SaleItemRow__fields > .col--actions .IconButton {
  top: 0;
  width: 30px;
  height: 30px;
  align-items: center;
  padding-top: 0;
  font-size: 0.95rem;
}

/* Screen reader only labels */
.sr-only, :is(#SaleDock, .SalePage) .SaleItemRow .Field > label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  padding: 0;
}

/* Field-specific widths */
:is(#SaleDock, .SalePage) .SaleItemRow .SpeciesField {
  min-width: 8rem;
  max-width: 12rem;
}

:is(#SaleDock, .SalePage) .SaleItemRow .StockTypeField {
  max-width: 10rem;
}

:is(#SaleDock, .SalePage) .SaleItemRow .SizeField {
  max-width: 6rem;
}

/* Accession and lot: a link that becomes a select (see sale_item#openAccession
   and #openLot). Both states occupy the same slot in the field order, so
   revealing one does not reshuffle the row around it. */
:is(#SaleDock, .SalePage) .SaleItemRow .FieldPicker {
  flex: 0 1 auto;
  align-self: center;
  min-width: 0;
}

:is(#SaleDock, .SalePage) .SaleItemRow .FieldPicker .Field {
  margin: 0;
  max-width: 10rem;
}

.FieldRevealLink {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 0.8rem;
  color: var(--color-primary);
  text-decoration: underline;
  cursor: pointer;
  white-space: nowrap;
}

/* Price group */
:is(#SaleDock, .SalePage) .PriceGroup {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  align-items: baseline;
  margin-left: auto; /* right-align cluster */
}

:is(#SaleDock, .SalePage) .PriceGroup input {
  width: auto;
  max-width: none;
  text-align: right;
}

:is(#SaleDock, .SalePage) .QuantityField input {
  width: 11ch;
}

:is(#SaleDock, .SalePage) .UnitPriceField input {
  width: 10ch;
}

:is(#SaleDock, .SalePage) .TotalPriceField input {
  width: 10ch;
}

/* Availability chip */
:is(#SaleDock, .SalePage) .SaleItemRow .Availability {
  align-self: center;
}

:is(#SaleDock, .SalePage) .SaleItemRow .Availability small {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  font-size: 12px;
  border-radius: 999px;
  background: #c6e2ff;
  color: rgb(14.72, 74.52, 74.52);
  border: 1px solid rgb(143.64, 198.3431578947, 255);
}

/* Meta footer — spans full width, always below the field row */
:is(#SaleDock, .SalePage) .SaleItemRow .SaleItemMeta {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  font-size: 0.75rem;
}

/* Row buttons. .FieldRevealLink is deliberately a link, not a button-looking
   thing — it opens a field, it does not do anything. */
:is(#SaleDock, .SalePage) .SaleItemRow button[type=button]:not(.IconButton):not(.FieldRevealLink) {
  background-color: #fff;
  color: #1f3d3d;
  border: 1px solid #e3dccb;
  padding: 0.4rem 0.6rem;
  border-radius: var(--btn-radius);
  white-space: nowrap;
}
:is(#SaleDock, .SalePage) .SaleItemRow button[type=button]:not(.IconButton):not(.FieldRevealLink):hover {
  background-color: #fffdf7;
}

/* The stock type's color (set inline as --st-row-tint), laid on as an image
   rather than a background-color so a row that colors itself for its own state
   keeps both signals. Unscoped: the dock and the full-page sale form render the
   same row. */
.SaleItemRow {
  padding-inline: 0.4rem;
  border-radius: 6px;
  background-image: linear-gradient(var(--st-row-tint, transparent), var(--st-row-tint, transparent));
}

/* A new line has no summary head, so the box needs its own room above. */
.SaleItemRow.is-new {
  padding-block: 0.4rem;
}

/* Collapsed line summaries (§15.2) */
.SaleItemRow__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

.SaleItemRow__summary {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.2rem 0.3rem;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.SaleItemRow__summaryText {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  font-size: 0.9em;
}

/* The pull-floor signals take the whole second line of the summary.
   `min-width: 0` and the wrapping below are what keep them *inside* that line:
   a flex item defaults to min-width:auto, so a sale on three pull lists grew
   the line to its content and ran out past the dock's edge. */
.SaleItemRow__pullSummary {
  flex: 0 0 100%;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.5rem;
}

/* The span renders on every persisted line whether or not there is anything to
   say, because it is the target the pull side streams into (§15.4) and a target
   that only appeared once the line was already on a list could never catch the
   first commitment. Claiming the whole second line while empty is what has to
   be suppressed — `:empty` cannot do it, since ERB leaves whitespace inside. */
.SaleItemRow__pullSummary.is-empty {
  display: none;
}

.SaleItemRow__pull {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Quantity and money, right-aligned against the chevron. */
.SaleItemRow__amounts {
  flex: 0 0 auto;
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-size: 0.9em;
  white-space: nowrap;
}

.SaleItemRow__total,
.SaleItemRow__name {
  font-weight: 600;
}

.SaleItemRow__type,
.SaleItemRow__pull {
  opacity: 0.8;
  font-size: 0.9em;
}

/* Wraps rather than holding one line: the badge names a quantity and a unit,
   and in a dock narrow enough it would otherwise push itself out of the row. */
.OverCommittedBadge {
  cursor: help;
  min-width: 0;
  color: var(--color-warning);
  font-weight: 600;
}

.SaleItemRow__chevron svg {
  transition: transform 120ms ease;
}

.SaleItemRow:not(.is-collapsed) .SaleItemRow__chevron svg {
  transform: rotate(180deg);
}

/* ===== Price lock =====
   Unscoped, like .SaleItemRow itself: the dock and the full-page sale form
   render the same row. The padlock sits at the end of the money cluster, where
   the thing it holds still ends. */
.PriceLockField {
  display: flex;
  align-items: center;
  margin: 0;
}

/* Doubled up on purpose: .IconButton is defined in application.scss, which the
   cascade reaches after this file, so a single class here would lose to it. */
.IconButton.PriceLockButton {
  top: 0;
  font-size: 0.85rem;
  opacity: 0.55;
}

.IconButton.PriceLockButton:hover,
.IconButton.PriceLockButton[aria-pressed=true] {
  opacity: 1;
}

/* A locked price field is readonly, not disabled (see price_lock_controller),
   and used to be grayed out from here because nothing else in the app styled an
   uneditable field. forms.scss now gives every disabled and readonly field the
   same look, and price_lock_controller sets .readOnly alongside .is-locked on
   the same line — so this block only said the baseline again, in slightly
   different numbers. Left as a pointer: if a locked field ever needs to differ
   from a disabled one, it goes here.

   The focus ring moved with it: this block killed it outright, the baseline
   instead swaps the live teal for a faint one, so tabbing into a locked price to
   copy it still shows you where you are. */
.PriceLockNote {
  color: #527070;
  white-space: nowrap;
}

/* Destroy state */
.SaleItemRow.marked-for-destroy {
  opacity: 0.55;
  filter: grayscale(0.2);
  pointer-events: none;
}

.SaleItemRow.marked-for-destroy .IconButton {
  pointer-events: auto;
}

/* Add line button */
:is(#SaleDock, .SalePage) button[data-action*="sale-form#addItem"] {
  background-color: #fff;
  color: #1f3d3d;
  border: 1px solid #e3dccb;
  align-self: start;
  padding: 0.5rem 0.75rem;
  border-radius: var(--btn-radius);
  border-style: dashed;
}
:is(#SaleDock, .SalePage) button[data-action*="sale-form#addItem"]:hover {
  background-color: #fffdf7;
}

/* ===== Errors ===== */
:is(#SaleDock, .SalePage) .field_with_errors input,
:is(#SaleDock, .SalePage) .field_with_errors select,
:is(#SaleDock, .SalePage) .field_with_errors textarea {
  border-color: rgb(177, 75.5, 69.5);
  box-shadow: 0 0 0 3px rgba(177, 75.5, 69.5, 0.15);
}

:is(#SaleDock, .SalePage) .ErrorMessage {
  margin-top: 0.25rem;
  font-size: 12px;
  color: rgb(177, 75.5, 69.5);
}

/* ===== Sticky footer: totals, status buttons, save ===== */
/* Pinned to the bottom of whatever scrolls the form — the dock body, or the
   window on the full-page form. Two rows: the running totals, then the status
   buttons on the left and Create/Update on the right. Solid, because content
   scrolls under it. The negative side margins bleed it out over the dock
   body's padding so it reads as the dock's edge rather than a box inside it. */
.SaleFormFooter {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.4rem 0.75rem;
  align-items: center;
  padding: 0.5rem 0.75rem;
  background: #fff;
  border-top: 1px solid #e3dccb;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.06);
}

/* The sticky rectangle is the dock body's content box, inside its padding, so
   the footer is pushed that far below zero to sit on the body's true edge. */
#SaleDock .SaleFormFooter {
  bottom: -0.75rem;
  margin: auto -0.75rem -0.75rem;
}

/* Row one, full width: quantities on the left, money on the right — under the
   price column it sums. */
.SaleTotals {
  grid-column: 1/-1;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  min-width: 0;
}

.SaleTotals__qty {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  flex-wrap: wrap;
  min-width: 0;
}

.SaleTotals__amount {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The per-stock-type quantity badges, same shape as the ones on the sales index
   and the pull list rows (sale_form_controller#recalc builds them). */
.SaleTotals .StockTypeStats {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0;
}

.SaleTotals .StockTypeStat {
  font-size: 0.9em;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.SaleTotals .Separator {
  opacity: 0.5;
}

/* Row two. */
.SaleFormFooter .DockActions {
  grid-column: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  min-width: 0;
}

.SaleFormFooter .SubmitRow {
  grid-column: 2;
}

/* Both still used by other forms (users, species, the pull-list pages). */
.SubmitRow {
  display: flex;
  justify-content: flex-end;
}

.Actions {
  display: grid;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.DockActions .RowBelow {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.DockActions .InlineButtonForm {
  display: inline-flex;
  margin: 0;
}

/* ===== Status panels: pull lists, pickups & deliveries, QuickBooks ===== */
/* One cluster between the header and the lines, tighter than the form's own
   rhythm so the three read as a group (the panels carry no margins of their
   own — qbo.scss). Each panel arrives inside a wrapper that is only a stream
   target: `contents`, so an empty one (no lists yet, nothing sent) costs no
   gap. The expanded sales row draws the same cluster (.SaleRowPanels). */
.SaleStatusPanels {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  /* The summary carries a bottom margin for standing alone; in the cluster
     the gap does that job. */
}
.SaleStatusPanels > .SaleStatusPanels__target {
  display: contents;
}
.SaleStatusPanels .SalePullLists {
  margin-bottom: 0;
}

/* ===== Sale notes (dock form) ===== */
/* Under the customer's notes: a <details> whose summary is a one-line preview
   of each note (or "add notes"), and whose body is the two editors. The
   summary swaps its wording with the open state so the preview and the
   textarea holding the same text are never both on screen. */
.SaleNotes {
  font-size: 12px;
  line-height: 1.5;
  /* Closed: the previews stack in the first column, one line each, with the
     link at the end of the first line. Open: just a heading and the link. */
}
.SaleNotes > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.5rem;
  min-width: 0;
}
.SaleNotes > summary::-webkit-details-marker {
  display: none;
}
.SaleNotes__closed, .SaleNotes__open {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 0.5rem;
  align-items: baseline;
  min-width: 0;
  flex: 1 1 auto;
}
.SaleNotes[open] > summary .SaleNotes__closed {
  display: none;
}
.SaleNotes:not([open]) > summary .SaleNotes__open {
  display: none;
}
.SaleNotes__open {
  font-weight: 600;
}
.SaleNotes__preview {
  grid-column: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: #1f3d3d;
}
.SaleNotes__link {
  grid-column: 2;
  grid-row: 1;
  /* "add notes" with no preview beside it sits where the text would. */
}
.SaleNotes__link:only-child {
  grid-column: 1;
  justify-self: start;
}
.SaleNotes__label {
  font-weight: 600;
  margin-right: 0.3rem;
}
.SaleNotes__link {
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--color-primary);
  text-decoration: underline;
  white-space: nowrap;
}
.SaleNotes__fields {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.4rem;
}

/* ===== Customer info icon (dock header) ===== */
.CustomerInfoIcon {
  cursor: default;
  font-size: 0.9em;
  opacity: 0.75;
}
.CustomerInfoIcon:hover {
  opacity: 1;
}

/* ===== Customer notes (dock form and the expanded sales row) ===== */
.CustomerNotes {
  font-size: 12px;
  color: #1f3d3d;
  background: rgb(248.64, 253.56, 235.32);
  border-left: 3px solid rgb(209.5, 236.1, 124.6);
  padding: 0.4rem 0.6rem;
  border-radius: 0 6px 6px 0;
  line-height: 1.5;
}
.CustomerNotes__provenance {
  font-size: 11px;
  color: #527070;
  margin-bottom: 0.25rem;
}
.CustomerNotes__label {
  font-weight: 600;
  margin-right: 0.3rem;
}
.CustomerNotes__overflow {
  display: inline;
}
.CustomerNotes__overflow summary {
  display: inline;
  cursor: pointer;
  color: #105151;
  list-style: none;
}
.CustomerNotes__overflow summary::-webkit-details-marker {
  display: none;
}

/* ===== Suggested user banner ===== */
.Button--link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  color: #105151;
  cursor: pointer;
  text-decoration: underline;
  font-size: inherit;
  line-height: inherit;
}
.Button--link:hover {
  color: rgb(13.6, 68.85, 68.85);
  text-decoration: none;
  background-color: unset;
}

.SuggestedUser {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.75rem;
  padding: 0.6rem 0.75rem;
  background: rgb(243.34, 252.36, 218.92);
  border: 1px solid rgb(213.25, 232.65, 141.4);
  border-radius: 8px;
  font-size: 13px;
  margin-bottom: 0.5rem;
}
.SuggestedUser form {
  display: contents;
}
.SuggestedUser__prompt {
  flex: 1 1 auto;
  min-width: 0;
}
.SuggestedUser__details {
  width: 100%;
}
.SuggestedUser__details summary {
  cursor: pointer;
  color: #527070;
  font-size: 12px;
  user-select: none;
}
.SuggestedUser__details[open] summary {
  margin-bottom: 0.4rem;
}
.SuggestedUser__dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.6rem;
  font-size: 12px;
  margin: 0 0 0.4rem;
}
.SuggestedUser__dl dt {
  font-weight: 600;
  color: #527070;
}
.SuggestedUser__dl dd {
  margin: 0;
}

/* ===== Customer field (sales/_customer_field) =====
   The customer's business card, or the picker behind "Change customer". The
   card is taller than the needed-on box beside it, so the row lines up at the
   top rather than along the inputs' bottoms. */
:is(#SaleDock, .SalePage) .SaleForm__customerRow {
  align-items: flex-start;
}

:is(#SaleDock, .SalePage) .CustomerField .ContactCard {
  max-width: none;
}
:is(#SaleDock, .SalePage) .CustomerField [hidden] {
  display: none !important;
}

:is(#SaleDock, .SalePage) .CustomerField__change {
  margin-top: 0.35rem;
  font-size: 0.85rem;
}

:is(#SaleDock, .SalePage) .CustomerField__actions {
  display: flex;
  gap: 1rem;
  margin-top: 0.35rem;
  font-size: 0.85rem;
}

/* The short users form: a bordered box under the search, so it reads as the
   picker's own rather than as more of the sale. */
:is(#SaleDock, .SalePage) .CustomerField__new {
  margin-top: 0.5rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  background: var(--color-bg-light);
}
:is(#SaleDock, .SalePage) .CustomerField__new fieldset {
  margin: 0;
}
:is(#SaleDock, .SalePage) .CustomerField__new .SubmitRow {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Needed on with the sale's notes under it, beside the customer's card. The
   column is narrow, so a note's preview wraps to a few lines rather than
   ellipsing after a couple of words. */
:is(#SaleDock, .SalePage) .SaleForm__customerRow > .CustomerField {
  flex: 1.5 1 18rem;
}

:is(#SaleDock, .SalePage) .SaleForm__headerSide {
  flex: 1 1 13rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-width: 0;
}
:is(#SaleDock, .SalePage) .SaleForm__headerSide .WantedOnField {
  flex: none;
}
:is(#SaleDock, .SalePage) .SaleForm__headerSide .SaleNotes__preview {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

/* ===== Docs menu (sales/_documents_menu) =====
   One control, two homes: the sale dock's header and a pull list's header. The
   button is deliberately quiet at rest — an outline pill, not a filled one — so
   it reads as a door rather than as the page's primary action, which on both
   screens belongs to something else (Pull All, the sale form). */
.DocsMenu {
  position: relative;
  display: inline-flex;
}

/* The quiet outline pill. Shared, because anything that merely *opens* the
   documents page has to look unlike the filled buttons that commit something —
   the QuickBooks panel's invoice step sat in a row with "Send estimate" and
   "Record deposit" wearing their exact styling, and read as a third button that
   sends. */
.DocsLink, .DocsMenu__button {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid #e3dccb;
  border-radius: 999px;
  background: #fff;
  color: #1f3d3d;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.DocsLink:hover, .DocsMenu__button:hover, .DocsLink:focus-visible, .DocsMenu__button:focus-visible, [aria-expanded=true].DocsLink, [aria-expanded=true].DocsMenu__button {
  border-color: var(--color-accent);
  background: #faf7ee;
  text-decoration: none;
}

/* A single destination rather than a menu — same door, same look. */
.DocsLink .DocsLink__glyph {
  font-size: 0.95rem;
  line-height: 1;
}

.DocsMenu__icon {
  font-size: 0.95rem;
  line-height: 1;
}

/* Points down closed, up open — the one moving part, so the button says whether
   the menu is showing without anyone having to look for it. */
.DocsMenu__caret {
  font-size: 0.7rem;
  opacity: 0.6;
  transition: transform 0.15s ease;
}
.DocsMenu__button[aria-expanded=true] .DocsMenu__caret {
  transform: rotate(180deg);
}

.DocsMenu__list {
  position: absolute;
  top: calc(100% + 0.25rem);
  right: 0;
  z-index: 30;
  min-width: 11rem;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  /* `hidden` has to beat the flex/block display above it. */
}
.DocsMenu__list[hidden] {
  display: none;
}

/* A row is a link where it navigates (the dock, a pull list) and a button where
   it switches the layout in place (the print page). Same row either way. */
.DocsMenu__item {
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.55rem;
  border-radius: 6px;
  color: #1f3d3d;
  font-size: 0.85rem;
  text-decoration: none;
  white-space: nowrap;
}
.DocsMenu__item:hover, .DocsMenu__item:focus-visible {
  background: #faf7ee;
  text-decoration: none;
}

/* A fixed column for the glyph, so the labels line up whether the row's mark is
   an emoji or the drawn QB disc. */
.DocsMenu__itemGlyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.3em;
  font-size: 0.95rem;
  line-height: 1;
}

.DocsMenu__itemLabel {
  font-weight: 500;
}

/* Narrow screens: the label goes and the caret keeps the button readable as a
   menu rather than a lone icon. */
@media (max-width: 480px) {
  .DocsMenu__label {
    display: none;
  }
}
.needs-pricing {
  background-color: rgb(248.64, 240.96, 224.88);
}
.needs-pricing:hover {
  background-color: rgb(243.34, 229.26, 199.78);
}

.price-warning {
  color: rgb(141.9883495146, 97.0019417476, 2.8116504854);
  font-weight: bold;
  font-style: italic;
}

.price-warning-badge {
  display: inline-block;
  background-color: rgb(151.5, 103.5, 3);
  color: #ffffff;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.85em;
  margin-left: 8px;
  font-weight: bold;
}

.price-missing {
  border: 2px solid #ca8a04 !important;
  background-color: rgb(248.64, 240.96, 224.88) !important;
}

.Button--warning {
  background-color: #ca8a04 !important;
  border-color: #ca8a04 !important;
}
.Button--warning:hover {
  background-color: rgb(171.9941747573, 117.5009708738, 3.4058252427) !important;
  border-color: rgb(171.9941747573, 117.5009708738, 3.4058252427) !important;
}

.UnpublishedPriceNotice {
  flex-basis: 100%;
  margin-top: 0.25rem;
  font-size: 0.7rem;
  font-style: italic;
  color: rgb(111.9825242718, 76.5029126214, 2.2174757282);
}
.UnpublishedPriceNotice[hidden] {
  display: none;
}

.received {
  background-color: var(--color-bg-dark);
  color: var(--color-text-faint);
}

/* Pull-list propagation confirmation panel (docs/done/pull_lists_architecture.md §5) */
.PropagationConfirm:not(:empty) {
  margin: 0 0 0.75rem;
  padding: 0.75rem 1rem;
  border-left: 4px solid var(--color-warning);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.03);
}

.PropagationConfirm-title {
  margin: 0 0 0.5rem;
  font-size: 1rem;
}

.PropagationConfirm-list {
  margin: 0 0 0.75rem;
  padding-left: 1.1rem;
}

.PropagationConfirm-warning {
  font-weight: 600;
}

.PropagationConfirm-option {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

.PropagationConfirm-actions {
  display: flex;
  gap: 0.5rem;
}

/* The sale form's pull-list summary (docs/done/pull_lists_architecture.md §15.1). */
.SalePullLists {
  margin: 0 0 0.75rem;
  padding: 0.4rem 0.6rem;
  border-left: 3px solid var(--color-accent, currentColor);
  font-size: 0.9em;
}

.SalePullLists__heading {
  margin: 0 0 0.25rem;
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.SalePullLists__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.15rem 0;
}

.SalePullLists__row.is-cancelled {
  opacity: 0.6;
}

/* The same amber edge a pull list row wears on the index (pull_lists.scss),
   at summary size: the sale form must not read as though the floor is finished
   while the list still has something to resolve. */
.SalePullLists__row.is-incomplete {
  box-shadow: inset 3px 0 0 var(--color-warning-light);
  padding-left: 0.4rem;
}

.SalePullLists__link {
  font-weight: 600;
  white-space: nowrap;
}

.SalePullLists__cancelled summary {
  cursor: pointer;
  font-size: 0.85em;
}

.PricingTable {
  width: auto;
  border-collapse: collapse;
  font-size: 1rem;
  table-layout: auto;
  margin: 1rem 0;
}

.PricingTable th {
  text-align: center;
}

.PricingTable td {
  text-align: right;
}

.PricingTable th,
.PricingTable td {
  width: 6rem;
  border: 1px solid #e3dccb;
  padding: 0.25rem 0.4rem;
}

.PricingTable.TableWithSuffixCells th,
.PricingTable.TableWithSuffixCells td {
  width: 8rem;
}

.PricingTable td.PricingSpeciesCell,
.PricingTable th.PricingSpeciesCell {
  width: auto;
  text-align: left;
  white-space: nowrap;
  padding-right: 0.5rem;
}

.PricingInput {
  width: 100%;
  max-width: 6rem;
  font-size: 1rem;
  padding: 0.1rem 0.2rem;
  text-align: right;
  box-sizing: border-box;
}

.PricingTable.TableWithSuffixCells .PricingInput {
  max-width: 8rem;
}

.PricingTable tr:nth-child(even) {
  background-color: rgba(0, 0, 0, 0.03);
}

.PricingRowSpecies {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 0;
}

.PriceNoLotFlag {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1;
  color: #fff;
  background-color: rgb(151.5, 103.5, 3);
  border-radius: 3px;
  text-decoration: none;
}
.PriceNoLotFlag:hover {
  background-color: rgb(111.4922330097, 76.167961165, 2.2077669903);
}

.HiddenPriceCell {
  background-color: rgba(202, 138, 4, 0.15);
}

.PricingRowHidden {
  display: inline-flex;
  align-items: center;
  margin-left: 0.25rem;
  color: #527070;
  vertical-align: middle;
}

.HiddenPriceRow .PricingRowSpecies {
  opacity: 0.6;
}

.PricingTable th.PricingVisibilityHeader,
.PricingTable td.PricingVisibilityCell {
  width: 1%;
  text-align: center;
  white-space: nowrap;
  padding: 0.25rem 0.35rem;
}

.PricingTable th.PricingVisibilityHeader {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.PricingVisibilityCell form {
  margin: 0;
  line-height: 0;
}

.PricingVisibilityToggle {
  cursor: pointer;
  margin: 0;
  vertical-align: middle;
}

.PricingTableScroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

@media (max-width: 767px) {
  .PricingTable {
    font-size: 0.9rem;
  }
  .PricingTable th:not(.PricingSpeciesCell):not(.PricingVisibilityHeader),
  .PricingTable td:not(.PricingSpeciesCell):not(.PricingVisibilityCell) {
    width: auto;
    min-width: 4.5rem;
    padding: 0.25rem 0.3rem;
  }
  .PricingTable.TableWithSuffixCells th:not(.PricingSpeciesCell):not(.PricingVisibilityHeader),
  .PricingTable.TableWithSuffixCells td:not(.PricingSpeciesCell):not(.PricingVisibilityCell) {
    min-width: 8rem;
  }
  .PricingTable th.PricingSpeciesCell,
  .PricingTable td.PricingSpeciesCell {
    min-width: 7rem;
    max-width: 10rem;
    white-space: normal;
  }
  .PricingRowSpecies {
    flex-wrap: wrap;
    gap: 0.15rem 0.3rem;
  }
  .PricingInput,
  .PricingTable.TableWithSuffixCells .PricingInput {
    max-width: none;
  }
  .PricingTable .PricingInput {
    padding: 0.15rem 0.3rem;
  }
  .PricingTable th.PricingVisibilityHeader,
  .PricingTable td.PricingVisibilityCell {
    min-width: 0;
    padding: 0.25rem 0.25rem;
  }
}
.PublishAllButton {
  background-color: #1c723b;
  color: #ffffff;
  border: none;
  border-radius: 3px;
  padding: 0.2rem 0.6rem;
  cursor: pointer;
}
.PublishAllButton:hover {
  background-color: rgb(21.9661971831, 89.4338028169, 46.285915493);
}

.UnpublishAllButton {
  background-color: transparent;
  color: #527070;
  border: 1px solid #e3dccb;
  border-radius: 3px;
  padding: 0.2rem 0.6rem;
  cursor: pointer;
}
.UnpublishAllButton:hover {
  background-color: rgba(0, 0, 0, 0.04);
}

.PricingSizeTabs {
  display: flex;
  gap: 0.25rem;
  margin: 0.5rem 0 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.PricingSizeTab {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid #e3dccb;
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  background-color: rgba(0, 0, 0, 0.04);
  color: #527070;
  text-decoration: none;
  white-space: nowrap;
}
.PricingSizeTab:hover {
  background-color: rgba(0, 0, 0, 0.08);
}
.PricingSizeTab.is-current {
  background-color: transparent;
  color: inherit;
  font-weight: 600;
  box-shadow: inset 0 -2px 0 0 #1c723b;
}

.PricingSizeTab__hidden {
  font-size: 0.65rem;
  font-style: italic;
  color: #527070;
}

.ImportForm {
  max-width: 520px;
  margin: 1rem 0 2rem;
}

.ImportFormRow {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.ImportFormLabel {
  width: 140px;
  flex-shrink: 0;
  font-weight: bold;
  font-size: 0.9rem;
}

.ImportFormRadioLabel {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.9rem;
}

.ImportFormHint {
  font-size: 0.8rem;
  color: #527070;
}

.ImportFormAmountInput {
  width: 6rem;
  font-size: 1rem;
  padding: 0.1rem 0.3rem;
}

.ImportPreviewAdjustmentLabel {
  font-size: 0.8rem;
  font-weight: normal;
  color: #527070;
}

.BulkSaveActions {
  display: flex;
  gap: 0.75rem;
  margin: 1rem 0 2rem;
}

/* ---------- Wrapper ---------- */
#SalePrint {
  margin-left: auto; /* centered by default */
  margin-right: auto;
  color: var(--color-text-dark, #111);
  background: var(--color-bg, #fff);
}

@media print {
  html, body.PrintPage {
    background: #fff !important;
  }
  .Surface, .Page {
    background: #fff !important;
  }
}
@media screen {
  #SalePrint {
    max-width: 8.5in;
    margin-inline: auto;
    padding: 0 0.5in; /* visual gutter on screen */
  }
}
/* Hide setup controls on print */
@media print {
  @page {
    size: Letter portrait;
    margin: 0.5in;
  }
  .no-print {
    display: none !important;
  }
  #SalePrint {
    max-width: none;
    padding: 0;
  }
}
.PrintLayoutControls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  /* Dead on the invoice layout — you print that from QuickBooks. Greyed and
     unclickable rather than gone, so the button does not move about as the
     layout changes (sale_print_controller#applyLayoutVisibility). */
}
.PrintLayoutControls .PrintLink, .PrintLayoutControls .CreatePullListLink {
  padding: 0.35rem 0.65rem;
  margin-left: 0; /* the gap above spaces them now */
}
.PrintLayoutControls .PrintLink.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: auto; /* keep the title readable on hover */
}

/* ---------- Header (3-column grid) ---------- */
.PrintHeader {
  display: grid;
  grid-template-columns: 1fr 1.5fr 1fr; /* Logo : Account : Customer */
  gap: 0.75rem 1rem;
  align-items: start;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--color-border, #ddd);
  background: var(--color-bg, transparent);
}

.PrintHeader .Col {
  min-width: 0;
}
.PrintHeader .Col.CustomerCol {
  text-align: right;
}

@media print {
  .PrintHeader {
    max-height: 2.75in;
    overflow: hidden;
  }
}
/* ---------- Logo ---------- */
.LogoImg {
  display: block;
  max-width: 100%;
  height: auto;
  max-height: 1.75in;
  object-fit: contain;
}

/* ---------- Account block ---------- */
.AccountName {
  margin: 0 0 0.25rem 0;
  font-size: 1.1rem;
  color: var(--color-text-dark, #111);
}

.AccountContact {
  font-size: 0.95rem;
  line-height: 1.25rem;
  color: var(--color-text-dark, #111);
}

.AccountContact br {
  line-height: 1.25rem;
}

/* ---------- Customer block ---------- */
.LayoutTitle {
  margin: 0 0 0.25rem 0;
  font-size: 1.1rem;
  color: var(--color-primary);
}

.SaleMeta {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: end;
}
.SaleMeta .MetaCol {
  flex-grow: 1;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.SaleMeta .Label {
  font-weight: 600;
  line-height: 1.2;
  background: var(--color-bg-dark);
}
.SaleMeta .Value {
  font-size: 0.95rem;
}

.CustomerName {
  margin: 0 0 0.25rem 0;
  font-size: 1.1rem;
  color: var(--color-text-dark, #111);
}

.CustomerContact {
  font-size: 0.95rem;
  line-height: 1.25rem;
}

/* ---------- Table ---------- */
.SaleItems {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.5rem;
  page-break-inside: auto;
  font-size: 0.95rem;
  background: var(--color-bg, #fff);
  color: var(--color-text-dark, #111);
}

.SaleItems th,
.SaleItems td {
  border: 1px solid var(--color-border, #ccc);
  padding: 0.35rem 0.4rem;
  vertical-align: top;
}

.SaleItems thead th {
  background: var(--color-bg-dark);
  color: var(--color-text-dark, #111);
  white-space: nowrap; /* "Unit Price $" must not strand its "$" */
}

.IncludeCol {
  width: 1.25rem;
  text-align: center;
}

/* Figures read down a column, so they hold to one line: the quantity beside its
   unit, and the prices at their natural width. */
.SaleItems .QtyCol,
.SaleItems .amount-only {
  white-space: nowrap;
}

.SaleItems .QtyCol input[type=number] {
  width: 10ch;
  text-align: right;
}

/* ---------- Totals & disclaimer ---------- */
#receiptExtras {
  margin-top: 0.75rem;
  font-size: 1rem;
  color: var(--color-text-dark, #111);
}

#receiptExtras .Disclaimer {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  opacity: 0.9;
}

/* ---------- Invoice footer ---------- */
/* The invoice screen's stack (#invoiceExtras): figures on the right like the
   receipt's, then the controls for the push. The global form baseline fights
   that — `label` is block and `select` is 100% wide — so "Deposit to apply"
   and "For" each sat orphaned on a line above a full-width control. Each row
   is a right-justified flex line instead: label and control together,
   wrapping only when the page is too narrow to hold them. */
#invoiceExtras {
  margin-top: 0.75rem;
  font-size: 1rem;
  color: var(--color-text-dark, #111);
  /* The notes (dating, no estimate) and the email box hold to a short
     right-hand column rather than a sentence stretched across the page with
     one word left over. */
  /* The no-email warning takes a line of its own under the box. */
}
#invoiceExtras > p {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0.25rem 0.4rem;
}
#invoiceExtras select {
  width: auto;
  max-width: 100%;
  margin-top: 0;
}
#invoiceExtras > p.hint,
#invoiceExtras > .QboEmailCustomer__row {
  max-width: 30rem;
  margin-left: auto;
}
#invoiceExtras .QboEmailCustomer__why {
  flex-basis: 100%;
}

/* The invoice's own notes (#invoiceExtras > .InvoiceNotes): closed to a link
   on the right with the figures, and opening into two left-aligned editors in
   the same short column the hints and the email box hold to. Nothing here is
   saved on the sale — see sales/print for why. */
.InvoiceNotes {
  max-width: 30rem;
  margin: 0.35rem 0 0 auto;
  text-align: left;
  /* The summary swaps its wording with the open state, like the dock's
     .SaleNotes — "+ add notes" is a lie once the editors are on screen. */
}
.InvoiceNotes > summary {
  cursor: pointer;
  list-style: none;
  text-align: right;
}
.InvoiceNotes > summary::-webkit-details-marker {
  display: none;
}
.InvoiceNotes[open] > summary .InvoiceNotes__closed {
  display: none;
}
.InvoiceNotes:not([open]) > summary .InvoiceNotes__open {
  display: none;
}
.InvoiceNotes__link {
  font-size: 0.85rem;
  color: var(--color-primary);
  text-decoration: underline;
  white-space: nowrap;
}
.InvoiceNotes__fields {
  display: grid;
  gap: 0.4rem;
  margin-top: 0.3rem;
}
.InvoiceNotes__field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
}
.InvoiceNotes__field textarea {
  width: 100%;
  font-size: 0.9rem;
}
.InvoiceNotes__fields > p.hint {
  font-size: 0.8rem;
  margin: 0;
}

/* ---------- Pack-only ---------- */
.pack-only.Hidden {
  display: none;
}

/* ---------- Print niceties ---------- */
@media print {
  input[type=checkbox] {
    appearance: none;
    width: 0;
    height: 0;
    border: 0;
    margin: 0;
    padding: 0;
  }
  .SaleItems thead {
    display: table-header-group;
  }
  .SaleItems tr {
    page-break-inside: avoid;
  }
  .SaleItems th, .SaleItems td {
    padding: 0.25rem 0.3rem;
  }
}
.SignatureContainer {
  line-height: 4rem;
  font-size: 1.5rem;
}

/* ---------- Sale Notes ---------- */
.SaleReceiptThankYouMessage {
  font-weight: bold;
}

/* ---------- Context stamp ---------- */
/* Which record the documents below are being cut from. Screen-only scaffolding
   — it tells the person building the document what they are looking at, and a
   pull-list page whose lines are a subset of the sale says so here rather than
   leaving the reader to compare quantities. */
.PrintContext {
  display: flex;
  align-items: baseline;
  gap: 0.4rem 1rem;
  margin-bottom: 0.75rem;
  padding: 0.5rem 0.75rem;
  border-left: 3px solid var(--color-accent, #2ca01c);
  border-radius: 0 4px 4px 0;
  background: var(--color-surface-panel, #f6f4ee);
}

/* The description, wrapping on its own so it never pushes the badge beside it
   down a line. */
.PrintContext__main {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  flex: 1 1 auto;
  min-width: 0;
}

.PrintContext__label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.65;
}

.PrintContext__subject {
  font-weight: 700;
  font-size: 1rem;
}

.PrintContext__note {
  font-size: 0.8rem;
  opacity: 0.7;
}

/* The sale named as a dock-launch link (sales/print: the subject itself, or
   "of Sale N" beside a pull list's). Underlined so it reads as the way back
   when the badge says the dock has moved on. */
.PrintContext__sale {
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
}
.PrintContext__sale:hover {
  text-decoration-color: currentColor;
}

/* The right-hand column: the dock badge over the freshness line. Keeps its
   natural width — it is the short side, so the description is what wraps —
   and wraps itself only once it would take more than its share. Pushed to the
   far right so the eye finds both answers in one place. */
.PrintContext__status {
  margin-left: auto;
  flex: 0 0 auto;
  max-width: 60%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.15rem;
  text-align: right;
  font-size: 0.8rem;
}

/* Synced with dock / NOT synced with dock / Dock closed — filled by
   sale_print_controller#syncDockStatus, which also hides it on a page with no
   dock beside it. */
.PrintContext__dock {
  font-weight: 600;
  /* An inline dot rather than a flex item: keeps the badge's baseline on its
     text, so it lines up with the label's first line however either side wraps. */
}
.PrintContext__dock::before {
  content: "";
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  margin-right: 0.35em;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 0.05em;
}
.PrintContext__dock[data-state=synced] {
  color: var(--color-success, #2ca01c);
}
.PrintContext__dock[data-state=unsynced] {
  color: var(--color-danger, #c62828);
}
.PrintContext__dock[data-state=closed] {
  color: var(--color-text-faint, #888);
  font-weight: 400;
}
.PrintContext__dock[data-state=closed]::before {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px currentColor;
}

/* "As of 2:14 PM" while the sale is as this page shows it; "Sale changed since
   2:14 PM · Refresh" once sale_print_controller#checkFreshness learns
   otherwise. Quiet until then — the time is a footnote, the change is not. */
.PrintContext__fresh {
  color: var(--color-text-faint, #888);
}
.PrintContext__fresh[data-state=stale] {
  color: var(--color-warning-deep, #9a6700);
  font-weight: 600;
}

.PrintContext__refresh {
  margin-left: 0.4em;
  padding: 0.05em 0.5em;
  border: 1px solid currentColor;
  border-radius: 999px;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.PrintContext__refresh:hover {
  background: color-mix(in srgb, currentColor 12%, transparent);
  text-decoration: none;
}

/* ---------- Phones ---------- */
/* The print page is reachable from the phone's sale form, so on a narrow
   screen it stops pretending to be a sheet of Letter paper: no inch gutters,
   the letterhead stacked, and each line a small card instead of a six-column
   table. Screen only — what comes out of the printer is the layout above. */
@media screen and (max-width: 767px) {
  #SalePrint {
    padding: 0;
  }
  /* The bare "Open" page has no #main-content margin around it. */
  body.PrintPage #SalePrint {
    padding: 1rem;
  }
  /* The description over the two status answers, rather than squeezed beside them. */
  .PrintContext {
    flex-direction: column;
    align-items: stretch;
    gap: 0.35rem;
  }
  .PrintContext__status {
    margin-left: 0;
    max-width: none;
    align-items: flex-start;
    text-align: left;
  }
  .PrintLayoutControls {
    justify-content: flex-start;
  }
  /* The docs menu drops its label on a narrow screen (_docs_menu.scss), but
     here it is the page's main control — which document is this — so it keeps it. */
  .PrintLayoutControls .DocsMenu__label {
    display: inline;
  }
  /* Letterhead: the nursery (logo beside its name and contact), then the
     customer and the sale's date and number beneath, all reading left. */
  .PrintHeader {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "logo     account" "customer customer";
    gap: 0.75rem;
  }
  .PrintHeader .LogoCol {
    grid-area: logo;
  }
  .PrintHeader .AccountCol {
    grid-area: account;
  }
  .PrintHeader .Col.CustomerCol {
    grid-area: customer;
    text-align: left;
    padding-top: 0.75rem;
    border-top: 1px solid var(--color-border, #ddd);
  }
  .LogoImg {
    max-width: 5rem;
    max-height: 5rem;
  }
  .SaleMeta {
    justify-content: flex-start;
    gap: 1.5rem;
    margin-bottom: 0.5rem;
  }
  .SaleMeta .MetaCol {
    flex-grow: 0;
  }
  .SaleMeta .Label {
    background: none;
    font-size: 0.8rem;
    opacity: 0.7;
  }
  .AccountContact,
  .CustomerContact {
    overflow-wrap: anywhere;
  }
  /* Lines as cards: the checkbox down the left, the plant and its category,
     then quantity, unit price and line total along the bottom. The cells stay
     cells — sale_print_controller reads them by row — and grid items are
     blockified, so `.Hidden` on a price cell still hides it. */
  .SaleItems {
    display: block;
    border: 0;
    background: none;
  }
  .SaleItems thead {
    display: none;
  }
  .SaleItems tbody {
    display: grid;
    gap: 0.5rem;
  }
  .SaleItems tr:not(.Hidden) {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "inc desc desc  desc" "inc cat  cat   cat" "inc qty  unit  total";
    column-gap: 0.6rem;
    row-gap: 0.15rem;
    padding: 0.6rem 0.75rem;
    background: var(--color-bg, #fff);
    border: 1px solid var(--color-border, #ccc);
    border-radius: 8px;
  }
  .SaleItems th, .SaleItems td {
    border: 0;
    padding: 0;
  }
  .SaleItems td.IncludeCol {
    grid-area: inc;
    width: auto;
    padding-top: 0.15rem;
  }
  .SaleItems td.DescCol {
    grid-area: desc;
    font-weight: 600;
  }
  .SaleItems td.CategoryCol {
    grid-area: cat;
    font-size: 0.85rem;
    opacity: 0.75;
  }
  .SaleItems td.QtyCol {
    grid-area: qty;
    align-self: center;
    margin-top: 0.35rem;
  }
  .SaleItems td.UnitPriceCol,
  .SaleItems td.LineTotalCol {
    align-self: center;
    margin-top: 0.35rem;
  }
  .SaleItems td.UnitPriceCol {
    grid-area: unit;
    opacity: 0.75;
  }
  .SaleItems td.UnitPriceCol:not(.is-unpriced)::before {
    content: "@ $";
  }
  .SaleItems td.LineTotalCol {
    grid-area: total;
    font-weight: 700;
  }
  .SaleItems td.LineTotalCol:not(.is-unpriced)::before {
    content: "$";
  }
  .SaleItems .QtyCol input[type=number] {
    width: 7ch;
  }
  #receiptQtyTotal,
  #receiptExtras,
  #invoiceExtras {
    margin-top: 0.75rem;
  }
  #invoiceExtras > p {
    justify-content: flex-start;
  }
  #invoiceExtras > p.hint,
  #invoiceExtras > .QboEmailCustomer__row,
  .InvoiceNotes {
    max-width: none;
    margin-left: 0;
  }
  .InvoiceNotes > summary {
    text-align: left;
  }
  .SignatureContainer {
    line-height: 3rem;
    font-size: 1.15rem;
  }
}
.PullListsIndex {
  /* The filter bar ended flush against the first row, so the search box read as
     part of the list rather than as the control above it. */
  margin-top: 1.25rem;
}

/* The shared .FiltersRow is a `repeat(auto-fit, minmax(8rem, 1fr))` grid built
   for the sales menu's stack of equal-width selects. This row holds two things
   of different natures — a search box and a button — and the grid both stretched
   the button across its cell and pushed it a whole column away from the box it
   belongs beside. Flex sizes each to its content instead. */
#PullListsIndexFilters .FiltersRow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.PullListsIndex__create {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* The sale picker behind Create Pull List — a short form, not a page of data. */
.PullListSelectSale {
  max-width: 44rem;
}
.PullListSelectSale .Field {
  margin-bottom: 1rem;
}
.PullListSelectSale .SaleChoiceSelect {
  width: 100%;
}
.PullListSelectSale .Actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.PullListDetails {
  /* One column, customer card above the items, as the sales row does it: the
     items get the row's whole width, however narrow the dock leaves it. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem 1rem;
}

/* Pull List variants */
.PullListsList--print {
  background: transparent;
}

/* Pull list specific elements */
.WantedAt {
  font-weight: 500;
  color: rgb(26.35, 51.85, 51.85);
}

/* ── The show page ────────────────────────────────────────────────────────────

   The header's buttons are `button_to` forms, which are block elements: dropped
   into a bare container they stack into a column, which is what this page did
   before. `.PageHeaderActions` (already flex) plus `margin: 0` on the forms puts
   them back on one line, here and in every action cluster below. */
.PullListShow__header {
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}
.PullListShow__header h1 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.PullListShow__header .PageHeaderActions {
  margin-left: auto;
}

.PageHeaderActions form,
.ItemActions form,
.NeedsAttention form,
.PullListItems__header form {
  margin: 0;
}

.PullListShow {
  background: var(--color-bg-light);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-bottom: 1.25rem;
}

/* Label over value, wrapping into as many columns as fit — the old
   <p><strong>Sale:</strong> …</p> stack burned a full line on each fact. */
.PullListShow__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  margin: 0;
}

.PullListShow__metaItem {
  min-width: 0;
}
.PullListShow__metaItem dt {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
  margin-bottom: 0.1rem;
}
.PullListShow__metaItem dd {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
}

.PullListShow__notes {
  overflow-wrap: anywhere;
  margin-top: 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--color-border);
}
.PullListShow__notes p {
  margin: 0 0 0.25rem;
}

/* The same note at the head of an expanded row, above the customer card. */
.PullListRowNotes {
  min-width: 0;
  padding: 0.4rem 0.6rem;
  border-left: 3px solid var(--color-border);
  overflow-wrap: anywhere;
}
.PullListRowNotes p {
  margin: 0 0 0.25rem;
}
.PullListRowNotes p:last-child {
  margin-bottom: 0;
}

.PullListShow__notesHeading {
  margin: 0 0 0.2rem;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.7;
}

/* Collapsed to its "Add note" toggle until someone means to write — the note is
   read far more often than it is edited. Same treatment as the item editor it
   replaces. */
.PullListNotesEditor summary {
  cursor: pointer;
  font-size: 0.85em;
}
.PullListNotesEditor .FormControl {
  margin: 0.3rem 0;
}

.PullListShow .CancelledBanner,
.PullListShow .SaleUpdatedBanner {
  padding: 0.35rem 0.5rem;
  margin: -0.25rem 0 0.6rem;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.035);
}

/* ── Items on the show page ───────────────────────────────────────────────── */
.PullListItems__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.PullListItems__header h2 {
  margin: 0;
}
.PullListItems__header .Button {
  margin-left: auto;
}

.PullListItems__count {
  font-size: 0.8rem;
  font-weight: 600;
  vertical-align: middle;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  background: var(--color-bg-dark);
  color: var(--color-text-dark);
}

/* The show page's card list, and — since an expanded index row draws the same
   cards — the row's too. */
.PullListItems__list,
.PullListItemsList {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
  /* The cards answer to the list's width, not the viewport's: beside an open
     dock a wide screen leaves them phone-narrow (the 640px rule below never
     fires), and the nowrap action cluster then squeezed the item's name. */
  container-type: inline-size;
}

@container (max-width: 30rem) {
  .PullListItemRow .ItemActions {
    margin-left: 0;
    width: 100%;
  }
}
.PullListItems__empty {
  opacity: 0.7;
}

/* One line and its own history. The resolved rows above the live one belong to
   it, so the group closes the list's gap between them — near-touching reads as
   "this happened to that row", a half-rem apart reads as two rows. */
.PullListItemGroup {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

/* Each item is a card: the identity line and its buttons share one row, and
   everything conditional (flag, adjustment, note, provenance) stacks beneath at
   full width instead of being squeezed alongside. */
.PullListItemRow {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background-color: #fff;
  /* The stock type's color (set inline as --st-row-tint), laid on as an image
     rather than a background-color so a row that colors itself for its own
     state — pulled, below — keeps both signals. */
  background-image: linear-gradient(var(--st-row-tint, transparent), var(--st-row-tint, transparent));
}

/* background-color, not the shorthand: the shorthand would blank the tint. */
.PullListItemRow.is-pulled {
  background-color: rgb(237.2738028169, 250.6461971831, 242.094084507);
}

.PullListItemRow .ItemMain {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.75rem;
}

.PullListItemRow .ItemInfo {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.5rem;
  min-width: 0;
}
.PullListItemRow .ItemInfo .ItemName {
  font-weight: 600;
}
.PullListItemRow .ItemInfo .Accession,
.PullListItemRow .ItemInfo .StockType,
.PullListItemRow .ItemInfo .Size {
  font-size: 0.85em;
  opacity: 0.7;
}

/* Open rows carry it in the action cluster; a cancelled row's tombstone still
   carries it inside .ItemInfo, so the rule sits at row level. */
.PullListItemRow .Quantity {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.PullListItemRow .ItemActions {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.35rem 0.6rem;
  margin-left: auto;
}

/* The row's edit chevron. Deliberately not `.RowExpand`: that class pins itself
   to the top-right corner of its row below 640px, which is where the pull
   list's own chevron goes — an item's belongs in the flow of its action
   cluster, on every width. */
.ItemExpand {
  flex: 0 0 auto;
  border: 0;
  background: transparent;
  padding: 0.25rem;
  line-height: 0;
  cursor: pointer;
  color: inherit;
  border-radius: 999px;
  transition: transform 0.15s ease, background-color 0.15s ease;
}
.ItemExpand:hover {
  background: color-mix(in srgb, currentColor 12%, transparent);
}
.ItemExpand.is-open {
  transform: rotate(180deg);
}

/* The in-row editor (§15.2's collapse, applied to an item). Hidden until the
   chevron opens it — `[hidden]` alone loses to the `display: flex` here, and
   expand_row_controller sets `style.display` for the same reason. */
.PullListItemRow .ItemEditor {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--color-border);
}
.PullListItemRow .ItemEditor[hidden] {
  display: none;
}

/* The way back off a full-page item form. */
.BackLink {
  display: inline-block;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

/* The full-page variant (new / edit). Left to itself the fields run the whole
   width of the content column, which reads as a wall of controls for what is
   really one decision — so it is capped, and the line and its quantity share a
   row wherever there is room for them. */
.PullListItemForm:not(.PullListItemForm--inline) {
  max-width: 44rem;
  /* A quantity is a short number; a full-width box for it only invites doubt. */
}
.PullListItemForm:not(.PullListItemForm--inline) .Field {
  margin-bottom: 0.75rem;
}
.PullListItemForm:not(.PullListItemForm--inline) .FormControl {
  width: 100%;
}
.PullListItemForm:not(.PullListItemForm--inline) .FormRow--line {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.75rem;
  align-items: flex-start;
}
.PullListItemForm:not(.PullListItemForm--inline) .Field--line {
  flex: 1 1 22rem;
  min-width: 14rem;
}
.PullListItemForm:not(.PullListItemForm--inline) .Field--quantity {
  flex: 0 0 9rem;
}
.PullListItemForm:not(.PullListItemForm--inline) .Field--quantity .FormControl {
  text-align: right;
}

.PullListItemForm--inline {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
  margin: 0;
  /* Quantity is a number and a short one; the note wants whatever is left.
     The note is first in the DOM order that reads best in a form, but the
     quantity belongs on the right — under the number the row displays in its
     own right-hand cluster, so opening a row to change it does not make the
     figure jump across the card. `order` moves it without moving the tab
     order's sense of "what, then how many". */
  /* Right-aligned for the same reason the full-page variant does it: a quantity
     is read against the ones above and below it. */
  /* The global .Actions is a grid, which stacks these two into a column. */
}
.PullListItemForm--inline .Field {
  margin: 0;
}
.PullListItemForm--inline .Field label {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
}
.PullListItemForm--inline .Field--quantity,
.PullListItemForm--inline .Field:has(input[type=number]) {
  order: 2;
  flex: 0 0 8rem;
  margin-left: auto;
}
.PullListItemForm--inline .Field--notes,
.PullListItemForm--inline .Field:has(textarea) {
  order: 1;
  flex: 1 1 14rem;
  min-width: 10rem;
}
.PullListItemForm--inline .Actions {
  order: 3;
}
.PullListItemForm--inline .ErrorMessages {
  order: 0;
}
.PullListItemForm--inline .Field--quantity .FormControl {
  text-align: right;
}
.PullListItemForm--inline textarea.FormControl {
  min-height: 2.2rem;
}
.PullListItemForm--inline .Actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0;
}
.PullListItemForm--inline .ErrorMessages {
  flex: 1 0 100%;
}

/* Cancel sits at the end of the editor line, aligned with the buttons beside it
   rather than with the inputs' baseline. */
.ItemEditorActions {
  display: flex;
  align-items: center;
  margin-left: auto;
  /* .IconButton nudges itself up 5px for the contexts it was born in; on this
     line it just floats above its neighbors. */
}
.ItemEditorActions form {
  margin: 0;
}
.ItemEditorActions .IconButton {
  top: 0;
}

/* "Added 8/13 · Updated 8/14 by BK" — quiet by design; it only has to be there
   when someone goes looking for whether a row is new. */
.ItemProvenance {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: rgb(73.2543478261, 144.1456521739, 144.1456521739);
}
.ItemProvenance .Separator {
  opacity: 0.5;
}
.ItemProvenance .Stamp {
  cursor: help;
  white-space: nowrap;
}

.PullListShow__metaItem .Stamp {
  cursor: help;
}

/* One wrapping line for everything under the identity line. A card with nothing
   to say costs a single line of collapsed summaries; the blocks that need the
   width take it back with a 100% basis. */
.ItemFooter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.9rem;
}
.ItemFooter > .NeedsAttention,
.ItemFooter > .ItemAdjustment--pending {
  flex: 1 0 100%;
}

.ItemFooter .ItemNotes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  min-width: 0;
}

/* A written note is a block of prose and wants the card's width, not whatever
   is left beside the provenance chip. Collapsed to just its "Add note" toggle
   it stays inline — which is the whole point of the footer row. */
.ItemFooter .ItemNotes:has(.ItemNotesBody) {
  flex: 1 0 100%;
}

.ItemNotesBody {
  overflow-wrap: anywhere;
  flex: 1 0 100%;
  font-size: 0.9em;
  padding: 0.1rem 0.5rem;
  border-left: 3px solid var(--color-border);
}
.ItemNotesBody p {
  margin: 0;
}

/* An open editor or request form needs the full width; collapsed, it is just
   its summary and sits inline with its neighbors. */
.ItemFooter details[open] {
  flex: 1 0 100%;
}

.ItemNotesEditor summary,
.ItemAdjustment--request summary {
  color: rgb(66.2119565217, 130.2880434783, 130.2880434783);
}

/* ── The list form (new / edit) ───────────────────────────────────────────────

   Two shapes on one page, because §14.9 splits the items in two: an unpulled
   row is a line of fields, a pulled one is the show page's own card carrying
   its adjustment control. */
.PullListForm {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.PullListForm .Field {
  margin: 0;
}

/* Sale and Wanted side by side, wrapping when there is no room for both. */
.PullListForm__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.75rem 1.5rem;
}

/* The sale is a fact, not a picker — it needs a label that looks like the real
   ones beside it without being one. */
.FieldLabel {
  display: block;
  font-weight: bold;
}

.FieldStatic {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0.25rem 0 0;
  /* Line up with the inputs beside it, which carry a border and .5rem of pad. */
  padding: 0.5rem 0;
}

.FieldStatic__aside {
  font-size: 0.9em;
  opacity: 0.7;
}

.PullListForm__itemsHeading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
}
.PullListForm__itemsHeading .Button {
  margin-left: auto;
}

.PullListItemFieldsList {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* One item, one line. The identity takes the slack; the inputs keep the widths
   they actually need, and the whole thing wraps rather than stacking. */
.PullListItemFields {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.75rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background-color: #fff;
  /* The stock type's color, the same wash the show page's rows wear. */
  background-image: linear-gradient(var(--st-row-tint, transparent), var(--st-row-tint, transparent));
}
.PullListItemFields label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
}

.PullListItemFields__identity {
  flex: 1 1 18rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.5rem;
  min-width: 0;
}
.PullListItemFields__identity .ItemName {
  font-weight: 600;
}
.PullListItemFields__identity .StockType,
.PullListItemFields__identity .Size,
.PullListItemFields__identity .Accession {
  font-size: 0.85em;
  opacity: 0.7;
}

/* forms.scss gives every text input `width: 100%`, which is why this one used
   to run the width of the page. A quantity is four characters wide.

   The basis is fixed rather than shrink-to-fit so the column lands in the same
   place on every row: a unit label that happens to be "feet" instead of "qts"
   would otherwise walk the quantity and the note across the list. */
.PullListItemFields__quantity {
  flex: 0 0 9rem;
}
.PullListItemFields__quantity .QuantityField {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
}
.PullListItemFields__quantity input[type=number] {
  width: 5.5rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.PullListItemFields__quantity .QuantityField__unit {
  font-size: 0.85em;
  opacity: 0.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.PullListItemFields__notes {
  flex: 1 1 12rem;
  min-width: 8rem;
}

.PullListItemFields__actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  margin-left: auto;
}

/* The global .Actions is a one-column grid: it stacked these two full width and
   butted them against each other. */
.PullListForm__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

.PullListForm__pulled {
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}

.PullListForm__pulledHint {
  margin: -0.25rem 0 0.6rem;
  font-size: 0.85rem;
  opacity: 0.75;
}

/* Tombstones, below the working set. A quiet container so the section reads as
   a section rather than as a loose table on the page background. Superseded
   rows have no section of their own any more — each one sits against the row
   that replaced it. */
.CancelledItems {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  background: var(--color-bg-light);
}

@media (max-width: 640px) {
  .PullListShow__header .PageHeaderActions {
    margin-left: 0;
    width: 100%;
  }
  .PullListItemRow .ItemActions {
    margin-left: 0;
    width: 100%;
  }
}
.PulledStatus {
  color: var(--color-success);
  font-size: 0.9em;
}

.NotPulledStatus {
  color: var(--color-warning);
  font-size: 0.9em;
}

.UnpullButton {
  background-color: var(--color-warning);
  opacity: 0.8;
}

.UnpullButton:hover {
  background-color: var(--color-warning);
  opacity: 1;
}

/* Cancellation tombstones and the needs-attention flag (§2, §4). */
.PullListRow.is-cancelled {
  opacity: 0.6;
  /* The dock glyph is a control, not a fact about the list — striking it
     through would only make it hard to read. The row's opacity is enough. */
}
.PullListRow.is-cancelled .WantedAt,
.PullListRow.is-cancelled .Status,
.PullListRow.is-cancelled .PullListNumber {
  text-decoration: line-through;
}

.PullListNumber {
  font-weight: 700;
  /* The number is the row's link to its own page. It inherits the row's color
     rather than the link blue — a row already dense with badges does not need
     a second accent — and announces itself on hover instead. */
}
.PullListNumber a {
  color: inherit;
  text-decoration: none;
}
.PullListNumber a:hover, .PullListNumber a:focus-visible {
  text-decoration: underline;
}

/* A row's door into the dock (`pull_list_sale_dock_button`): the glyph alone,
   sized like the row's other icon badges. It only renders for someone who has
   a dock, so there is no hidden twin to swap in here. */
.SaleDockButton {
  line-height: 1;
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.12s ease-in-out, transform 0.12s ease-in-out;
}
.SaleDockButton:hover, .SaleDockButton:focus-visible {
  opacity: 1;
  transform: scale(1.12);
  text-decoration: none;
}

/* ── "Not finished" as one look, everywhere ───────────────────────────────────

   A list with anything left to resolve — rows still to pull, a raised flag, an
   adjustment waiting on a person (PullList#incomplete?) — wears the same amber
   edge on the index, on the dashboard, inside an expanded sale row and on its
   own page. The finished ones settle back a little, so a full page of rows
   sorts itself into "still mine" and "done" at a glance rather than on a read
   of each status word.

   Ordered before `.needs-attention` deliberately: the two share specificity, and
   a flagged row should keep the heavier bar. */
.PullListRow.is-incomplete {
  box-shadow: inset 3px 0 0 var(--color-warning-light);
}

/* Not faded to tombstone levels (`.is-cancelled` is 0.6) — a finished list is
   still a record someone reads, it just stops competing for attention. */
.PullListRow.is-complete {
  opacity: 0.88;
}

.PullListRow.needs-attention {
  box-shadow: inset 3px 0 0 var(--color-warning);
}

/* The status chip itself (`pull_list_status_badge`): glyph plus word, in the
   color its state earns. Amber for every shape of unfinished, quiet green for
   done, struck-through faint for a tombstone. */
.PullListStatus {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  padding: 0.1rem 0.45rem;
  border: 1px solid transparent;
  border-radius: 9999px;
  font-size: 0.85em;
  line-height: 1.35;
  white-space: nowrap;
}

.PullListStatus__glyph {
  font-size: 0.95em;
}

/* In a page header the chip inherits the <h1>'s scale, which turns a status
   word into a second headline beside the list number. */
.PullListShow__header h1 .PullListStatus {
  font-size: 1rem;
  font-weight: 600;
}

.PullListStatus.is-incomplete {
  color: var(--color-warning-deep);
  background: color-mix(in srgb, var(--color-warning) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-warning) 45%, transparent);
  font-weight: 600;
}

/* The one that used to read "✅ Pulled" while a person was still owed an
   answer — it gets the loudest of the three. */
.PullListStatus.PullListStatus--attention {
  background: color-mix(in srgb, var(--color-warning) 22%, transparent);
  border-color: var(--color-warning);
}

.PullListStatus--pulled {
  color: var(--color-success);
  border-color: color-mix(in srgb, var(--color-success) 35%, transparent);
}

.PullListStatus--cancelled {
  color: var(--color-text-faint);
}

/* The glyph on its own, where a sale line or the sale form's summary has no
   room for the word. It carries the word in its tooltip; what it carries here
   is weight — the finished ones step back so an amber one stands out. */
.StatusIcon {
  cursor: help;
}

.StatusIcon--pulled,
.StatusIcon--cancelled {
  opacity: 0.65;
}

/* "2/3 items". The color comes from PullList#incomplete?, not from the tally:
   a 3/3 list holding a pending adjustment is amber, because the thing left to
   do is not something the tally can count. */
.PullListProgress {
  font-size: 0.9em;
  font-weight: 600;
  white-space: nowrap;
}

.ProgressPending,
.ProgressPartial {
  color: var(--color-warning-deep);
}

.ProgressComplete {
  color: var(--color-success);
}

.ProgressCancelled {
  color: var(--color-text-faint);
}

/* The show page's card takes the same edge as its row, and says in words what
   is left — the page where someone decides a list is done is the page that can
   afford a sentence. */
.PullListShow.is-incomplete {
  border-left: 3px solid var(--color-warning);
}

.IncompleteBanner {
  padding: 0.3rem 0.5rem;
  margin-bottom: 0.5rem;
  border-left: 3px solid var(--color-warning);
  background: color-mix(in srgb, var(--color-warning) 10%, transparent);
  color: var(--color-warning-deep);
  font-size: 0.9em;
}

.NeedsAttentionBadge {
  cursor: help;
}

.NeedsAttention {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;
  border-left: 3px solid var(--color-warning);
  font-size: 0.9em;
}

.NeedsAttentionReason {
  color: rgb(27.9, 54.9, 54.9);
}

.SaleUpdatedBanner,
.CancelledBanner {
  padding: 0.25rem 0.5rem;
  font-size: 0.85em;
}

.SaleUpdatedBanner {
  color: var(--color-warning);
}

.CancelledBanner {
  color: rgb(66.2119565217, 130.2880434783, 130.2880434783);
}

.CancelledItems {
  margin-top: 0.75rem;
  opacity: 0.65;
}

.CancelledItemsHeading {
  margin: 0 0 0.25rem;
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.CancelledReason,
.CancelledMeta {
  font-size: 0.85em;
  color: rgb(59.1695652174, 116.4304347826, 116.4304347826);
}

.PullListItemRow.is-cancelled {
  opacity: 0.65;
}

.PullListItemRow.needs-attention {
  box-shadow: inset 3px 0 0 var(--color-warning);
}

.ItemNotesEditor summary {
  cursor: pointer;
  font-size: 0.85em;
}

/* Supersession and adjustments (§14). Superseded rows are history — faded, and
   never struck through: struck means cancelled, and these were real work. */
.SupersededMeta,
.AdjustmentMeta,
.AdjustmentReason {
  font-size: 0.85em;
  color: rgb(59.1695652174, 116.4304347826, 116.4304347826);
}

.PullListItemRow.is-superseded {
  opacity: 0.6;
}

/* Why the pile changed, under the line it changed on. */
.SupersededReason {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem;
  font-size: 0.85em;
  color: rgb(59.1695652174, 116.4304347826, 116.4304347826);
}

.SupersededReason__label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.7;
}

.AdjustmentBadge {
  font-weight: 600;
  white-space: nowrap;
}

.PendingAdjustmentBadge {
  cursor: help;
  white-space: nowrap;
}

.ItemAdjustment {
  padding: 0.25rem 0.5rem;
  font-size: 0.9em;
}

.ItemAdjustment--pending {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  border-left: 3px solid var(--color-warning);
}

.ItemAdjustment--request summary {
  cursor: pointer;
  font-size: 0.85em;
}

/* Opened, the request is a short line of fields, not a page-wide stack — a
   signed quantity and a one-line reason. Without this, forms.scss's
   `input { width: 100% }` ran both of them the width of the card. */
.ItemAdjustment--request form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.4rem 0.75rem;
  margin-top: 0.35rem;
  /* The warning is prose and wants the width; the button follows on its own
     line rather than being wedged against the reason field. */
}
.ItemAdjustment--request form .Field {
  margin: 0;
}
.ItemAdjustment--request form label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
}
.ItemAdjustment--request form .Field:has(input[type=number]) {
  flex: 0 0 9rem;
}
.ItemAdjustment--request form .Field:has(input[type=text]) {
  flex: 1 1 14rem;
  min-width: 10rem;
}
.ItemAdjustment--request form input[type=number] {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.ItemAdjustment--request form .RestockHint {
  flex: 1 0 100%;
  margin: 0;
}
.ItemAdjustment--request form input[type=submit] {
  flex: 0 0 auto;
}

.RestockWarning,
.RestockHint {
  color: var(--color-warning);
  font-size: 0.85em;
}

.AdjustmentActions {
  display: flex;
  gap: 0.25rem;
}

/* The print page's refused-create block (pull_lists/_create_errors). Inherits
   .ErrorSummary's colors; all it adds is the room the print controls above it
   don't leave, and a dismiss in the corner — this one stays until it is read,
   so it needs a way out that isn't a page reload. */
.PullListCreateErrors {
  position: relative;
  margin: 0 0 1rem;
  padding-right: 2rem;
}
.PullListCreateErrors ul {
  margin: 0;
}
.PullListCreateErrors:focus-visible {
  outline: 2px solid rgb(177, 75.5, 69.5);
  outline-offset: 2px;
}

.PullListCreateErrors__dismiss {
  position: absolute;
  top: 0.25rem;
  right: 0.4rem;
  background: none;
  border: 0;
  padding: 0 0.25rem;
  font-size: 1.1rem;
  line-height: 1;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
}
.PullListCreateErrors__dismiss:hover {
  opacity: 1;
}

/* QuickBooks integration surfaces (docs/qbo_booking_architecture.md):
   the settings panel, the sale form's QuickBooks block and fulfillments
   block, and the QuickBooks Sync screen. */
.QboPanel {
  /* Full width so the Status cell has room to push its buttons to the right. */
  /* The Status cell: pill at the left, Reconnect/Disconnect at the right —
     the state and the actions on it, in one line. Wraps under the pill where
     the panel is too narrow for both. */
}
.QboPanel .QboPanel-status {
  width: 100%;
}
.QboPanel .QboPanel-status th {
  font-weight: 600;
}
.QboPanel .QboPanel-statusRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
}
.QboPanel .QboPanel-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* Connection state, on the account/site status line and the settings page.
   The same pill as the sale dock's StatusBadge: connected wears the confirmed
   green tint, not connected the cancelled red tint with the maroon ink. Needs
   reconnecting is the one state asking someone to act, so it alone is filled
   solid — $danger under white, the pairing colors.scss clears for AA. */
.QboStatus {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  border: 1px solid transparent;
}
.QboStatus.QboStatus--on {
  border-color: rgb(77.738028169, 211.461971831, 125.9408450704);
  background: rgb(190.003943662, 239.036056338, 207.6783098592);
  color: #1f3d3d;
}
.QboStatus.QboStatus--off {
  border-color: rgb(184.4215517241, 81.3465517241, 75.2534482759);
  background: rgb(240.3, 202.15, 195.85);
  color: #5d091f;
}
.QboStatus.QboStatus--reauth {
  border-color: rgb(177, 75.5, 69.5);
  background: rgb(177, 75.5, 69.5);
  color: #ffffff;
}

/* The automation toggles on the settings page. The box and its sentence are
   separate flex items so a label that wraps keeps its second line under the
   text, not centred beneath the box; the sentences are plain weight because
   they are choices, not field titles. Neither the spacing nor the weight can
   sit on the label itself: .Field label { margin: 0; font-weight: 600 } is
   (0,1,1) and outranks the toggle class — so the margin goes on the .Field and
   the weight on the sentence's own span. That rule's display: block would
   undo the flex too, so the toggle is reached through its .Field (0,2,0). */
.QboSettings > .Field {
  margin: 0.45rem 0;
}

.Field > .QboSettings__toggle {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  cursor: pointer;
}
.Field > .QboSettings__toggle > span {
  font-weight: normal;
}
.Field > .QboSettings__toggle input[type=checkbox] {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  margin: 0.2rem 0 0;
}

/* "Invoice and estimate lines" sits beside its select rather than over it: a
   short label and a one-line choice read as one row, like the toggles above
   it. The .Field column turns into a row (the parent selector is what beats
   customer_orders' .Field, which loads later at the same specificity), the
   select gives up the global width:100% for its content width, and the pair
   wraps onto two lines where it cannot fit. */
.QboSettings > .QboSettings__inline {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  /* A prefix is a few characters; a full-width box would read as a sentence. */
}
.QboSettings > .QboSettings__inline > label {
  flex: 0 0 auto;
}
.QboSettings > .QboSettings__inline > select {
  flex: 0 1 auto;
  width: auto;
  max-width: 100%;
  margin-top: 0;
}
.QboSettings > .QboSettings__inline > .QboSettings__prefix {
  flex: 0 0 auto;
  width: 8rem;
  margin-top: 0;
}

/* The numbering section is its own .QboSettings so its fields keep the
   direct-child rules above. A field switched off by doc_numbering_controller
   must actually go: .Field's display:flex outranks the browser's own
   [hidden] rule. */
.QboSettings__numbering {
  margin-top: 1.25rem;
}
.QboSettings__numbering [hidden] {
  display: none;
}

/* Automation: the same summary-then-"change" shape as the numbering below. */
.QboSettings__automation [hidden] {
  display: none;
}

.QboSettings__automationFields {
  margin-top: 0.5rem;
}

/* One line per toggle, what it has the app do or not do; the off ones recede. */
.QboAutomationSummary ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.QboAutomationSummary li {
  display: flex;
  gap: 0.5rem;
  margin: 0.15rem 0;
}
.QboAutomationSummary li.is-off {
  opacity: 0.65;
}
.QboAutomationSummary p {
  margin: 0.4rem 0 0;
}

.QboAutomationSummary__mark {
  flex: 0 0 1rem;
  text-align: center;
}

/* The section title with its Change button on the same line. */
.QboSettings__heading {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 0 0 0.25rem;
  /* The toggle carries both labels; its aria-expanded picks one. */
}
.QboSettings__heading h3 {
  margin: 0;
}
.QboSettings__heading [aria-expanded=true] .QboSettings__whenClosed,
.QboSettings__heading [aria-expanded=false] .QboSettings__whenOpen {
  display: none;
}

.QboSettings__numberingFields {
  margin-top: 0.75rem;
}

/* Items and income accounts: the same summary-then-"change" shape. */
.QboSettings__items {
  margin-top: 1.25rem;
}
.QboSettings__items [hidden] {
  display: none;
}

.QboSettings__itemFields {
  margin-top: 0.75rem;
}

/* What each sale line posts to, one line per mapped row. */
.QboItemSummary ul {
  margin: 0;
  padding-left: 1.25rem;
}

/* What the numbering settings produce, worked through for one sale. */
.QboDocNumberPreview {
  margin: 0;
}
.QboDocNumberPreview p {
  margin: 0;
}
.QboDocNumberPreview ul {
  margin: 0.25rem 0 0;
  padding-left: 1.25rem;
}
.QboDocNumberPreview code {
  white-space: nowrap;
}

.QboMappings {
  border-collapse: collapse;
  /* A row still pointing at an item QuickBooks has deactivated or dropped. The
     warning above the picker says which item and what happened; this only has
     to make the row findable in a long table. */
  /* A cell's controls — picker(s), the ×/→ glyphs, the override's ✕ — read as
     one line that wraps where it must. The forms are display:contents so
     their fields join that line directly rather than each form being a row. */
  /* Pickers take their content width, not the global width:100% — with that
     every select claims a whole line of the flex row and stretches across it
     (the same fix as .QboSettings__inline above). The item picker is capped
     because QuickBooks item names run long. */
  /* .IconButton was tuned for a × at body size: it nudges itself up 5px and
     top-aligns the glyph with a 2px padding fudge. Here it holds a ✕ inside
     .9em type, so centre it for real and undo both fudges. */
}
.QboMappings th, .QboMappings td {
  padding: 0.25rem 0.4rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
}
.QboMappings .QboMappings__row.is-unmapped td:first-child {
  font-weight: 600;
}
.QboMappings .QboMappings__row.is-unusable td:first-child {
  font-weight: 600;
}
.QboMappings .QboMappings__unusable {
  margin: 0 0 0.3rem;
  font-size: 0.95em;
}
.QboMappings .QboMappings__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}
.QboMappings form {
  display: contents;
}
.QboMappings select {
  flex: 0 1 auto;
  width: auto;
  max-width: 100%;
  margin-top: 0;
}
.QboMappings .QboMappings__item {
  max-width: min(22rem, 100%);
}
.QboMappings .IconButton {
  top: 0;
  align-items: center;
  padding-top: 0;
  font-size: 1rem;
}

/* The sale form's QuickBooks block and fulfillments block sit with the
   pull-list summary in .SaleStatusPanels and read like it: an accent rule,
   small type. No margins of their own — the cluster's gap spaces them. */
.SaleQbo,
.SaleFulfillments {
  margin: 0;
  padding: 0.25rem 0.6rem;
  border-left: 3px solid var(--color-accent, currentColor);
  font-size: 0.9em;
}

.SaleQbo__heading,
.SaleFulfillments__heading {
  cursor: pointer;
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}

/* The ? at the heading's right: the door to the guide (qbo/help). Plain
   weight and case — it is a link, not part of the heading's label. */
.SaleQbo__help {
  float: right;
  width: 1.3em;
  height: 1.3em;
  border: 1px solid currentColor;
  border-radius: 50%;
  text-align: center;
  line-height: 1.2em;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  text-decoration: none;
  opacity: 0.6;
}
.SaleQbo__help:hover, .SaleQbo__help:focus-visible {
  opacity: 1;
  text-decoration: none;
}

/* A status word that explains itself on hover: the dotted rule is the
   convention for "there is a title here". */
.SaleQbo__status {
  text-decoration: underline dotted;
  text-underline-offset: 0.15em;
  cursor: help;
}

.SaleQbo__badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0 0.4rem;
  border-radius: 999px;
  font-size: 0.85em;
  text-transform: none;
  letter-spacing: 0;
  background: var(--color-bg-light);
}
.SaleQbo__badge.is-failed {
  background: var(--color-warning-light);
}
.SaleQbo__badge.is-ok {
  opacity: 0.7;
}

/* The documents table stacks when its block is narrow (a phone's sales row,
   or the dock beside an open menu): the query is on the block, not the
   viewport, because the same table lives in both. */
.SaleQbo {
  container-type: inline-size;
}

.SaleQbo__documents {
  width: 100%;
  border-collapse: collapse;
  margin: 0.4rem 0;
  /* Refresh and Void as icon buttons side by side, never wrapped onto two
     lines. The same .IconButton correction as .QboMappings above — no upward
     nudge, centred — since the content is an SVG box, not a glyph. */
}
.SaleQbo__documents th, .SaleQbo__documents td {
  padding: 0.2rem 0.35rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}
.SaleQbo__documents th {
  text-align: left;
  font-weight: 600;
  font-size: 0.9em;
}
.SaleQbo__documents tr.is-voided td {
  opacity: 0.55;
  text-decoration: line-through;
}
.SaleQbo__documents tr.is-drifted td {
  box-shadow: inset 3px 0 0 var(--color-warning-light);
}
.SaleQbo__documents .SaleQbo__actions {
  white-space: nowrap;
}
.SaleQbo__documents .SaleQbo__actions form {
  display: inline;
}
.SaleQbo__documents .SaleQbo__actions form + form {
  margin-left: 0.25rem;
}
.SaleQbo__documents .SaleQbo__actions .IconButton {
  top: 0;
  align-items: center;
  padding-top: 0;
}
.SaleQbo__documents .SaleQbo__actions .QboIcon {
  display: block;
  width: 14px;
  height: 14px;
}

.SaleQbo__operations {
  list-style: none;
  margin: 0.4rem 0;
  padding: 0;
}
.SaleQbo__operations li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  padding: 0.2rem 0;
}
.SaleQbo__operations li.is-failed {
  box-shadow: inset 3px 0 0 var(--color-warning);
  padding-left: 0.4rem;
}
.SaleQbo__operations .SaleQbo__opLabel {
  font-weight: 600;
}
.SaleQbo__operations .SaleQbo__opStatus {
  opacity: 0.7;
}
.SaleQbo__operations .SaleQbo__opError {
  flex: 0 0 100%;
  color: var(--color-warning);
  font-size: 0.9em;
}
.SaleQbo__operations form {
  display: inline;
}

/* The three pushes, one row each — Estimate, Deposit, Invoice — in the order
   they happen: the button in a column of its own so the three line up, what
   it does beside it, and a rule between rows so each reads as its own act.
   The hint wraps under the button where the block is narrow. */
.SaleQbo__pushes {
  margin-top: 0.6rem;
  border-top: 1px solid var(--color-border);
}

.SaleQbo__step {
  padding: 0.45rem 0;
}
.SaleQbo__step + .SaleQbo__step {
  border-top: 1px dashed var(--color-border);
}

.SaleQbo__step:not(details),
.SaleQbo__stepSummary {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.75rem;
  align-items: center;
}

/* Wide enough for the usual three; "Create another deposit invoice…" is
   longer and pushes its own hint over rather than spilling into it. */
.SaleQbo__stepAction {
  flex: 0 0 auto;
  min-width: 11rem;
}
.SaleQbo__stepAction form {
  display: inline;
}

.SaleQbo__stepHint {
  flex: 1 1 14rem;
  min-width: 0;
  margin: 0;
}

/* The deposit row is a <details>: its summary is the row (button and hint),
   and the form folds out under both. The summary's own marker goes — the
   button's trailing ellipsis already says there is more to fill in. */
.SaleQbo__stepSummary {
  cursor: pointer;
  list-style: none;
}
.SaleQbo__stepSummary::-webkit-details-marker {
  display: none;
}

.SaleQbo__disclosureBody {
  margin-top: 0.45rem;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  background: var(--color-bg-light);
}
.SaleQbo__disclosureBody > .hint {
  margin: 0 0 0.4rem;
}

.SaleQbo__inlineForm {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}

.SaleQbo__inlineForm .Button--link {
  font-size: inherit;
}

/* The "email it" box on the deposit invoice form and beside Invoice via QuickBooks
   (qbo/_email_customer_checkbox). On the deposit form it takes a line of its
   own under the amount; on the invoice screen it sits in the footer's flow. */
.QboEmailCustomer {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  font-size: 0.9em;
  cursor: pointer;
}
.QboEmailCustomer input {
  margin: 0;
  cursor: pointer;
}
.QboEmailCustomer.is-disabled {
  opacity: 0.6;
}

/* The deposit form stacks the suggestion, then the box, then its warning,
   each on a line of its own under the amount. */
.SaleQbo__inlineForm .SaleQbo__suggestion,
.SaleQbo__inlineForm .QboEmailCustomer,
.SaleQbo__inlineForm .QboEmailCustomer__why {
  flex-basis: 100%;
}

.QboEmailCustomer__why {
  display: block;
  font-size: 0.85em;
  margin-top: 0.15rem;
}

.QboEmailCustomer__row {
  margin: 0.35rem 0;
}

/* Narrow: the header goes and each document becomes a two-line entry — its
   label on the first, then number, money, status and sync age wrapping under
   it, each prefixed by the column it came from (data-label). */
@container (max-width: 560px) {
  .SaleQbo__documents {
    /* The drift rule moves from every cell to the entry. */
    /* Buttons on a line of their own, under the figures. */
  }
  .SaleQbo__documents thead {
    display: none;
  }
  .SaleQbo__documents, .SaleQbo__documents tbody, .SaleQbo__documents tr {
    display: block;
  }
  .SaleQbo__documents tr {
    padding: 0.3rem 0;
    border-bottom: 1px solid var(--color-border);
  }
  .SaleQbo__documents tr:last-child {
    border-bottom: 0;
  }
  .SaleQbo__documents tr.is-drifted {
    box-shadow: inset 3px 0 0 var(--color-warning-light);
    padding-left: 0.4rem;
  }
  .SaleQbo__documents td {
    display: inline-block;
    padding: 0 0.6rem 0 0;
    border: 0;
    box-shadow: none;
    text-align: left;
    white-space: nowrap;
  }
  .SaleQbo__documents td.SaleQbo__doc {
    display: block;
    font-weight: 600;
    white-space: normal;
  }
  .SaleQbo__documents td[data-label]::before {
    content: attr(data-label) " ";
    opacity: 0.6;
  }
  .SaleQbo__documents td.SaleQbo__actions {
    display: block;
    padding-top: 0.2rem;
  }
}
.SaleFulfillments__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  padding: 0.15rem 0;
}
.SaleFulfillments__row.is-cancelled {
  opacity: 0.6;
  text-decoration: line-through;
}

.SaleFulfillments__label {
  font-weight: 600;
}

.SaleFulfillments__label a,
.SaleFulfillments__lists a {
  color: inherit;
}

.SaleFulfillments__stamp {
  font-size: 0.85em;
  color: var(--color-text-faint, currentColor);
  opacity: 0.8;
}

/* A cancelled row's mark, in the check-off circle's footprint so the
   column keeps its left edge. */
.SaleFulfillments__cancelMark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  cursor: help;
}

/* A row's ✏️ sits at the end of the line while shut; open, its actions span
   takes the row's width so the choices fold out under the whole row rather
   than squeezed beside the label. The summary keeps .ButtonIcon's flex box —
   this selector would otherwise outrank it. */
.SaleFulfillments__change {
  display: inline;
}
.SaleFulfillments__change > summary {
  list-style: none;
  display: inline-flex;
}
.SaleFulfillments__change > summary::-webkit-details-marker {
  display: none;
}

.SaleFulfillments__actions:has(> .SaleFulfillments__change[open]) {
  display: block;
  flex-basis: 100%;
}

.SaleFulfillments__cancelled {
  margin-top: 0.25rem;
}
.SaleFulfillments__cancelled > summary {
  cursor: pointer;
}

/* The add buttons and each choice inside Change…: as the QBO panel's steps,
   the button in a column of its own, what it does beside it, wrapping under
   where the block is narrow. An open slot picker takes the line and its hint
   goes — the picker says the rest. */
.SaleFulfillments__add {
  margin-top: 0.5rem;
  padding-top: 0.25rem;
  border-top: 1px solid var(--color-border);
}

.SaleFulfillments__step {
  padding: 0.3rem 0;
}
.SaleFulfillments__step + .SaleFulfillments__step {
  border-top: 1px dashed var(--color-border);
}
.SaleFulfillments__step .BookingStaffPicker[open] + .SaleFulfillments__stepHint {
  display: none;
}

.SaleFulfillments__step:not(details),
.SaleFulfillments__stepSummary {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.75rem;
  align-items: center;
}
.SaleFulfillments__step:not(details) > .Button, .SaleFulfillments__step:not(details) > .BookingStaffPicker:not([open]),
.SaleFulfillments__stepSummary > .Button,
.SaleFulfillments__stepSummary > .BookingStaffPicker:not([open]) {
  flex: 0 0 auto;
  min-width: 9rem;
}
.SaleFulfillments__step:not(details) > .BookingStaffPicker[open],
.SaleFulfillments__stepSummary > .BookingStaffPicker[open] {
  flex-basis: 100%;
}

.SaleFulfillments__stepSummary {
  cursor: pointer;
  list-style: none;
}
.SaleFulfillments__stepSummary::-webkit-details-marker {
  display: none;
}

.SaleFulfillments__stepHint {
  flex: 1 1 14rem;
  min-width: 0;
  margin: 0;
}

.SaleFulfillments__disclosureBody {
  margin-top: 0.4rem;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  background: var(--color-bg-light);
}

.SaleFulfillments__change > .SaleFulfillments__disclosureBody {
  white-space: normal;
}

.SaleFulfillments__form {
  margin: 0;
}

.SaleFulfillments__listsForm {
  margin-top: 0.35rem;
}

.SaleFulfillments__notesForm {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  margin-top: 0.35rem;
}
.SaleFulfillments__notesForm textarea {
  width: 100%;
}

.SaleFulfillments__lists-picker {
  margin: 0.25rem 0;
}
.SaleFulfillments__lists-picker label {
  margin-right: 0.5rem;
}

/* Per-line badges on the sale form (§5). */
.SaleItemRow__invoiced {
  opacity: 0.8;
}

.OverInvoicedBadge {
  color: var(--color-warning);
  font-weight: 600;
}

/* The QuickBooks Sync screen. Each table has one column of prose (the error,
   the reason, the company name) and a handful of short facts around it. The
   facts never wrap — a sale number split at its hyphen or "5 minutes / ago"
   on two lines reads as two values — and the prose column takes whatever
   width is left (`width: 100%` in an auto table is "everything the others
   don't need"). Each table sits in a `.table-responsive` box, so on a narrow
   screen it scrolls sideways rather than crushing its columns. */
.QboSync__connections,
.QboSync__operations,
.QboSync__drift {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.25rem;
  /* Sale numbers and try counts: fixed-width values centred under a header
     that is wider than they are. */
  /* A drift row following its refresh (qbo/sync/_drift_row): busy while the
     operation runs, then green or the failure's warning bar. */
}
.QboSync__connections th, .QboSync__connections td,
.QboSync__operations th,
.QboSync__operations td,
.QboSync__drift th,
.QboSync__drift td {
  padding: 0.3rem 0.4rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
  text-align: left;
  white-space: nowrap;
}
.QboSync__connections tr.is-failed td:first-child,
.QboSync__operations tr.is-failed td:first-child,
.QboSync__drift tr.is-failed td:first-child {
  box-shadow: inset 3px 0 0 var(--color-warning);
}
.QboSync__connections form,
.QboSync__operations form,
.QboSync__drift form {
  display: inline;
}
.QboSync__connections .QboSync__num,
.QboSync__operations .QboSync__num,
.QboSync__drift .QboSync__num {
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.QboSync__connections .QboSync__fill,
.QboSync__operations .QboSync__fill,
.QboSync__drift .QboSync__fill {
  width: 100%;
  min-width: 14rem;
  white-space: normal;
}
.QboSync__connections .QboSync__error,
.QboSync__operations .QboSync__error,
.QboSync__drift .QboSync__error {
  font-size: 0.9em;
  color: var(--color-warning);
}
.QboSync__connections .QboSync__ok,
.QboSync__operations .QboSync__ok,
.QboSync__drift .QboSync__ok {
  color: var(--color-success);
  font-weight: 600;
}
.QboSync__connections .QboSync__actions form + form,
.QboSync__operations .QboSync__actions form + form,
.QboSync__drift .QboSync__actions form + form {
  margin-left: 0.35rem;
}
.QboSync__connections tr.is-refreshing td,
.QboSync__operations tr.is-refreshing td,
.QboSync__drift tr.is-refreshing td {
  opacity: 0.75;
}
.QboSync__connections tr.is-refreshed td:first-child,
.QboSync__operations tr.is-refreshed td:first-child,
.QboSync__drift tr.is-refreshed td:first-child {
  box-shadow: inset 3px 0 0 var(--color-success);
}

.QboSync__spinner {
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  margin-right: 0.4em;
  vertical-align: -0.1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: QboSync-spin 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .QboSync__spinner {
    animation: none;
  }
}

@keyframes QboSync-spin {
  to {
    transform: rotate(360deg);
  }
}
/* The staff guide (qbo/help). Reading width, a table of contents in one
   line, and tables whose prose column takes the room. */
.QboHelp {
  max-width: 52rem;
}
.QboHelp h2 {
  margin-top: 1.75rem;
}
.QboHelp .QboHelp__toc {
  margin: 0 0 1rem;
  line-height: 1.8;
}
.QboHelp .QboHelp__table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.5rem 0 1rem;
}
.QboHelp .QboHelp__table th, .QboHelp .QboHelp__table td {
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
  text-align: left;
}
.QboHelp .QboHelp__table th {
  font-weight: 600;
}
.QboHelp .QboHelp__table td:first-child {
  white-space: nowrap;
}
.QboHelp .QboHelp__statuses td:nth-child(2) {
  white-space: nowrap;
  opacity: 0.7;
}
.QboHelp .QboHelp__steps li,
.QboHelp ul li {
  margin: 0.35rem 0;
}
.QboHelp .QboHelp__buttons dt {
  margin-top: 0.75rem;
  font-weight: 600;
}
.QboHelp .QboHelp__buttons dd {
  margin: 0.15rem 0 0 1rem;
}

/* Pickup / delivery booking (docs/qbo_booking_architecture.md §11): the
   customer's picker on the confirmation page, the staff picker on the sale
   page, the staff week grid, and resource administration. */
/* ---- Slot picker (customer and staff) ---------------------------------- */
.BookingPicker {
  margin: 1.5rem auto;
  padding: 1.25rem;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  background: #fffdf7;
  text-align: left;
}

.BookingPicker__title {
  font-size: 1.1rem;
  margin-bottom: 0.25rem;
  color: #1f3d3d;
}

.BookingPicker__lead {
  color: #527070;
  margin: 0 0 0.75rem;
  font-size: 0.95rem;
}

.BookingPicker__kinds {
  border: 0;
  padding: 0;
  margin: 0 0 0.75rem;
  display: flex;
  gap: 1rem;
}

.BookingPicker__kind {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
}

/* The date strip scrolls sideways on narrow screens rather than wrapping
   into a wall of chips. */
.BookingPicker__dates {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  padding: 0.25rem 0 0.5rem;
  scrollbar-width: thin;
}

.BookingPicker__date {
  flex: 0 0 auto;
  padding: 0.35rem 0.7rem;
  border: 1px solid #e3dccb;
  border-radius: 999px;
  background: #fff;
  color: #1f3d3d;
  font-size: 0.9rem;
  cursor: pointer;
  white-space: nowrap;
}
.BookingPicker__date:hover {
  border-color: #105151;
}
.BookingPicker__date.is-selected {
  background: #105151;
  border-color: #105151;
  color: #fff;
}

.BookingPicker__slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: 0.4rem;
  margin: 0.25rem 0 0.75rem;
}

.BookingPicker__slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.45rem 0.5rem;
  border: 1px solid #e3dccb;
  border-radius: 6px;
  background: #fff;
  color: #1f3d3d;
  cursor: pointer;
  line-height: 1.25;
}
.BookingPicker__slot:hover {
  border-color: #105151;
}
.BookingPicker__slot.is-selected {
  background: #105151;
  border-color: #105151;
  color: #fff;
}

/* Staff, all resources: a name, then that resource's own grid. */
.BookingPicker__slots.is-grouped {
  display: block;
}

.BookingPicker__groupName {
  margin: 0.5rem 0 0.25rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: #1f3d3d;
}
.BookingPicker__groupName:first-child {
  margin-top: 0;
}

.BookingPicker__groupSlots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
  gap: 0.4rem;
}

.BookingPicker__slotTime {
  font-weight: 600;
}

.BookingPicker__slotResource {
  font-size: 0.75rem;
  opacity: 0.8;
}

.BookingPicker__status {
  color: #527070;
  font-size: 0.9rem;
  margin: 0 0 0.75rem;
  min-height: 1.2em;
}

.BookingPicker__submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.BookingPicker__notes {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0.35rem 0;
}
.BookingPicker__notes textarea {
  width: 100%;
}

.BookingBooked {
  margin: 1.5rem auto;
  padding: 1rem 1.25rem;
  border-left: 4px solid #1c723b;
  background: #fffdf7;
  text-align: left;
}

.BookingBooked__slot {
  font-size: 1.05rem;
  margin: 0 0 0.25rem;
}

.BookingBooked__hint {
  color: #527070;
  font-size: 0.9rem;
  margin: 0;
}

/* ---- Shared bits ------------------------------------------------------- */
.BookingHint {
  display: block;
  color: #527070;
  font-size: 0.9em;
}

.BookingNowrap {
  white-space: nowrap;
}

/* ---- Resource administration ------------------------------------------- */
.BookableResources__scroll {
  overflow-x: auto;
}

.BookableResources td {
  vertical-align: top;
}
.BookableResources tr.is-inactive td {
  opacity: 0.6;
}

.BookableResources__center {
  text-align: center;
  width: 1%;
}

.BookableResources__check {
  color: #1c723b;
  font-weight: 700;
  font-size: 1.1em;
}

/* Day on the left, each window on its own line to its right. */
.BookingWeeklyHours {
  display: grid;
  grid-template-columns: max-content max-content;
  gap: 0.3rem 1rem;
  margin: 0;
  font-size: 0.9em;
}
.BookingWeeklyHours dt {
  font-weight: 600;
}
.BookingWeeklyHours dd {
  margin: 0;
  white-space: nowrap;
}
.BookingWeeklyHours dd span {
  display: block;
}

/* One tbody per weekday: the day cell spans its windows, so a day with two
   windows reads as one row with a remove button per window. */
.BookableResourceHours__table {
  margin-top: 0.5rem;
}
.BookableResourceHours__table th, .BookableResourceHours__table td {
  border: 0;
  padding: 0.35rem 0.5rem;
}
.BookableResourceHours__table th {
  width: 1%;
  padding-right: 2rem;
  background: none;
  color: inherit;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: top;
}
.BookableResourceHours__table .BookableResourceHours__range {
  white-space: nowrap;
}
.BookableResourceHours__table tbody {
  border-top: 1px solid #e3dccb;
}
.BookableResourceHours__table tbody:last-child {
  border-bottom: 1px solid #e3dccb;
}
.BookableResourceHours__table tbody tr:first-child td, .BookableResourceHours__table tbody tr:first-child th {
  padding-top: 0.6rem;
}
.BookableResourceHours__table tbody tr:last-child td, .BookableResourceHours__table tbody tr:last-child th {
  padding-bottom: 0.6rem;
}

.BookableResourceHours__add {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin-top: 0.75rem;
}
.BookableResourceHours__add label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
}

.BookableResourceHours__errors {
  flex-basis: 100%;
  margin: 0;
}

/* ---- Staff picker on the sale page ------------------------------------- */
.BookingStaffPicker {
  display: inline-block;
  vertical-align: middle;
  /* the open picker takes the row; neighbours drop below */
}
.BookingStaffPicker > summary {
  list-style: none;
  display: inline-block;
}
.BookingStaffPicker > summary::-webkit-details-marker {
  display: none;
}
.BookingStaffPicker[open] {
  display: block;
}

/* Staff only: ‹ month › on the left, the resource select on the right,
   wrapping onto two lines where the dock is narrow. */
.BookingPicker__toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-bottom: 0.35rem;
}

.BookingPicker__monthNav {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.BookingPicker__navButton {
  width: 2rem;
  height: 2rem;
  border: 1px solid #e3dccb;
  border-radius: 999px;
  background: #fff;
  color: #1f3d3d;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.BookingPicker__navButton:hover:not(:disabled) {
  border-color: #105151;
}
.BookingPicker__navButton:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.BookingPicker__month {
  min-width: 10rem;
}

.BookingPicker__resource {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.BookingPicker__resource[hidden] {
  display: none;
}

.BookingPicker--staff {
  margin: 0.5rem 0;
  padding: 0.75rem;
  font-size: 0.9em;
  max-width: 40rem;
}

.SaleFulfillments__booking {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.05rem 0.5rem;
  border-radius: 999px;
  background: var(--color-accent-light);
  color: var(--color-text-dark);
  font-size: 0.9em;
}

.SaleFulfillments__bookingResource {
  opacity: 0.75;
}

.SaleFulfillments__actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}

/* ---- Week grid --------------------------------------------------------- */
.BookingWeek__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 0.5rem;
}

.BookingWeek__range {
  margin-left: auto;
  font-weight: 600;
}

.BookingWeek__scroll {
  overflow-x: auto;
}

.BookingWeek__grid {
  min-width: 56rem;
  table-layout: fixed; /* equal day columns whatever a cell holds */
}
.BookingWeek__grid th, .BookingWeek__grid td {
  vertical-align: top;
  overflow-wrap: anywhere;
}
.BookingWeek__grid .BookingWeek__resource {
  width: 11rem;
  white-space: nowrap;
}
.BookingWeek__grid .BookingWeek__day {
  text-align: center;
}
.BookingWeek__grid .BookingWeek__date {
  font-weight: 400;
  font-size: 0.85em;
}
.BookingWeek__grid .BookingWeek__kind th {
  background: #ece5d3;
  color: #1f3d3d;
  text-transform: uppercase;
  font-size: 0.8em;
  letter-spacing: 0.04em;
}
.BookingWeek__grid tr.is-inactive th, .BookingWeek__grid tr.is-inactive td {
  opacity: 0.6;
}
.BookingWeek__grid .is-today {
  background: #fffdf7;
}
.BookingWeek__grid .BookingWeek__cell.is-closed {
  background: repeating-linear-gradient(-45deg, transparent 0 6px, rgba(0, 0, 0, 0.04) 6px 12px);
}

.BookingWeek__booking {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  padding: 0.15rem 0;
  font-size: 0.9em;
}
.BookingWeek__booking + .BookingWeek__booking {
  border-top: 1px dotted #e3dccb;
}

.BookingWeek__time {
  font-weight: 600;
}

.BookingWeek__customer {
  color: #527070;
}

.BookingWeek__closed {
  color: #527070;
  font-size: 0.8em;
}

.BookingWeek__toggle {
  display: inline-flex;
  gap: 0.25rem;
  margin-left: 0.5rem;
}

/* ---- Month grid -------------------------------------------------------- */
.BookingMonth__grid {
  width: 100%;
  min-width: 56rem;
  table-layout: fixed; /* seven equal days whatever a cell holds */
}
.BookingMonth__grid th, .BookingMonth__grid td {
  vertical-align: top;
  overflow-wrap: anywhere;
}
.BookingMonth__grid .BookingMonth__weekday {
  text-align: center;
}
.BookingMonth__grid .BookingMonth__cell {
  height: 6.5rem;
}
.BookingMonth__grid .BookingMonth__cell.is-outside {
  opacity: 0.5;
}
.BookingMonth__grid .is-today {
  background: #fffdf7;
}

.BookingMonth__date {
  display: block;
  font-weight: 600;
  text-align: right;
  font-size: 0.85em;
}

.BookingMonth__resource {
  color: #527070;
  font-size: 0.85em;
}

.BookingWeek__jump {
  display: inline-flex;
  gap: 0.35rem;
  align-items: center;
  margin: 0 0 0 0.5rem;
}
.BookingWeek__jump select, .BookingWeek__jump input {
  width: auto;
  margin: 0;
}

/* The staff calendar (CalendarController): events in their type's colour
   beside the site's pickups and deliveries. The month grid borrows the
   schedule's .BookingMonth__grid; these are the calendar's own pieces. */
.Calendar__header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1rem;
}
.Calendar__header h1 {
  margin-bottom: 0.25rem;
}

.Calendar__actions {
  display: inline-flex;
  gap: 0.35rem;
}

.Calendar__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 1rem;
  border: 0;
  padding: 0;
  margin: 0.25rem 0 0.75rem;
}
.Calendar__filters legend {
  float: left;
  margin-right: 0.5rem;
}

.Calendar__filter {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  cursor: pointer;
}
.Calendar__filter input {
  margin: 0;
}
.Calendar__filter input:checked {
  background-color: var(--event-color, #105151);
  border-color: var(--event-color, #105151);
}

.Calendar__swatch {
  display: inline-block;
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 3px;
  background: var(--event-color);
  vertical-align: middle;
}

.Calendar__retired {
  display: inline;
}

/* A day is washed in proportion to how much goes out on it. */
.Calendar__cell {
  height: 7.5rem;
  background-image: linear-gradient(rgba(211, 84, 0, calc(var(--day-load, 0) * 0.18)), rgba(211, 84, 0, calc(var(--day-load, 0) * 0.18)));
}

.Calendar__cellHead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.Calendar__cellHead .BookingMonth__date {
  margin-left: auto;
}

.Calendar__add {
  text-decoration: none;
  font-weight: 600;
  padding: 0 0.3rem;
  border-radius: 4px;
  color: #527070;
}
.Calendar__add:hover, .Calendar__add:focus-visible {
  background: #fffdf7;
  color: inherit;
}

.Calendar__month .Calendar__add {
  opacity: 0;
}

.Calendar__month td:hover .Calendar__add,
.Calendar__month .Calendar__add:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  .Calendar__month .Calendar__add {
    opacity: 1;
  }
}
.Calendar__daySummary {
  font-size: 0.8em;
  margin: 0.2rem 0 0.1rem;
  padding-top: 0.15rem;
  border-top: 1px dotted #e3dccb;
}

.CalendarItem {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem;
  font-size: 0.85em;
  padding: 0.1rem 0.3rem;
  margin: 0.1rem 0;
  border-radius: 4px;
}
.CalendarItem[hidden] {
  display: none;
}

.CalendarItem__link {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  color: inherit;
  text-decoration: none;
  min-width: 0;
}

a.CalendarItem__link:hover .CalendarItem__title {
  text-decoration: underline;
}

.CalendarItem__time {
  font-weight: 600;
  white-space: nowrap;
}

.CalendarItem__span {
  opacity: 0.8;
  font-size: 0.9em;
}

.CalendarItem__stats {
  font-size: 0.9em;
}

.CalendarItem--event {
  background: color-mix(in srgb, var(--event-color) 16%, transparent);
  border-left: 3px solid var(--event-color);
}
.CalendarItem--event.is-continued {
  border-left-style: dashed;
}

.CalendarItem--fulfillment {
  border-left: 3px solid #e3dccb;
}
.CalendarItem--fulfillment.is-fulfilled {
  opacity: 0.6;
}

.Calendar__list {
  max-width: 48rem;
}

.Calendar__listDay {
  padding: 0.5rem 0;
  border-bottom: 1px solid #e3dccb;
}
.Calendar__listDay[hidden] {
  display: none;
}
.Calendar__listDay.is-today .Calendar__listDate {
  color: #1f3d3d;
}
.Calendar__listDay .CalendarItem {
  font-size: 0.95em;
  padding: 0.25rem 0.4rem;
}

.Calendar__listDate {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 1rem;
  margin: 0 0 0.25rem;
}
.Calendar__listDate .Calendar__add {
  margin-left: auto;
}

.Calendar__todayTag {
  display: inline;
}

/* The week: a row per layer, the day columns shared. */
.Calendar__week {
  width: 100%;
  /* Lanes of one type read as one row: only its first lane draws a top rule. */
}
.Calendar__week .BookingWeek__resource {
  width: 9rem;
  white-space: normal;
  text-align: left;
}
.Calendar__week .Calendar__weekCell {
  background-image: linear-gradient(rgba(211, 84, 0, calc(var(--day-load, 0) * 0.18)), rgba(211, 84, 0, calc(var(--day-load, 0) * 0.18)));
  padding: 0.2rem 0.3rem;
}
.Calendar__week .Calendar__weekCell.is-today, .Calendar__week .Calendar__weekDay.is-today {
  background-color: #fffdf7;
}
.Calendar__week .Calendar__weekBar {
  padding: 0.1rem 0.2rem;
}
.Calendar__week .Calendar__weekBar .CalendarItem {
  margin: 0;
}
.Calendar__week .Calendar__weekRow--events:not(.is-lane-first) td {
  border-top: 0;
}
.Calendar__week .Calendar__weekRow--fulfillment td {
  height: 4rem;
}
.Calendar__week .Calendar__typeHead {
  border-left: 3px solid var(--event-color);
}

.Calendar__weekDay {
  position: relative;
  background-image: linear-gradient(rgba(211, 84, 0, calc(var(--day-load, 0) * 0.18)), rgba(211, 84, 0, calc(var(--day-load, 0) * 0.18)));
}
.Calendar__weekDay .Calendar__add {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
}

@media (max-width: 600px) {
  .Calendar__week .BookingWeek__resource {
    width: 6rem;
  }
}
.Calendar__weekOut {
  display: block;
  font-size: 0.8em;
  font-weight: 600;
}

/* Tasks List */
.TasksList {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.TaskRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  transition: all 0.2s;
}

.TaskCompleteAction {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.15rem;
}
.TaskCompleteAction form {
  display: flex;
}

.TaskAssigneeDropdown {
  position: relative;
}
.TaskAssigneeDropdown > summary {
  list-style: none;
  cursor: pointer;
  font-size: 0.85rem;
  color: #527070;
  line-height: 1;
  padding: 4px 5px;
  border-radius: 3px;
  user-select: none;
  display: block;
  text-align: center;
  transform: scaleX(1.5);
}
.TaskAssigneeDropdown > summary::-webkit-details-marker {
  display: none;
}
.TaskAssigneeDropdown > summary:hover {
  color: #1f3d3d;
  background: #faf7ee;
}

.TaskAssigneeList {
  position: absolute;
  left: 0;
  top: calc(100% + 0.25rem);
  z-index: 100;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  padding: 0.5rem;
  min-width: 220px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.TaskRow:hover {
  border-color: #105151;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.TaskRow.completed,
.TaskRow.cancelled {
  opacity: 0.6;
  background: #fffdf7;
}

.TaskRow.overdue,
.TaskRow.priority-urgent {
  border-left: 4px solid #d56856;
}

.TaskRow.priority-high {
  border-left: 4px solid #ca8a04;
}

.TaskRow.priority-backburner {
  opacity: 0.7;
}

.TaskRowMain {
  flex: 1;
  min-width: 0;
}

.TaskRowHeader {
  display: flex;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
  flex-wrap: wrap;
}

.TaskTitleLine {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  flex: 1 1 auto;
  min-width: 0;
}

.TaskTitle {
  font-size: 1.1rem;
  font-weight: 600;
  color: #1f3d3d;
  text-decoration: none;
  min-width: 0;
  overflow-wrap: anywhere;
}

.TaskTitle:hover {
  color: #105151;
}

.TaskBadges {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.TaskRowDetails {
  display: flex;
  gap: 1rem;
  font-size: 0.9rem;
  color: #527070;
  flex-wrap: wrap;
  overflow-wrap: anywhere;
}

.TaskRowBody {
  font-size: 0.9rem;
  color: #527070;
  overflow-wrap: anywhere;
}

.TaskRowActions {
  display: flex;
  gap: 0.5rem;
  margin-left: 1rem;
  align-items: center;
}
.TaskRowActions > form {
  display: flex;
  align-items: center;
}

/* Assignee completion dropdown in TaskRowActions */
.AssigneeCompletionDropdown {
  position: relative;
}
.AssigneeCompletionDropdown > summary {
  list-style: none;
  cursor: pointer;
}
.AssigneeCompletionDropdown > summary::-webkit-details-marker {
  display: none;
}

.AssigneeCompletionList {
  position: absolute;
  top: calc(100% + 0.25rem);
  right: 0;
  z-index: 100;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  padding: 0.5rem;
  min-width: 220px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.AssigneeCompletionItem {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  white-space: nowrap;
}
.AssigneeCompletionItem form {
  display: flex;
  align-items: center;
}

/* Assignee completions section on show page */
.AssigneeCompletions {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.AssigneeCompletionRow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid #e3dccb;
}
.AssigneeCompletionRow:last-child {
  border-bottom: none;
}
.AssigneeCompletionRow form {
  display: flex;
  align-items: center;
}

.AssigneeCompletionStatus {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
}

/* Task Show Page */
.TaskShow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 2rem;
  margin-top: 1rem;
}

.TaskShowMain {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.TaskShowSidebar {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.TaskShowSection {
  background: #fff;
  padding: 1.5rem;
  border-radius: 4px;
  border: 1px solid #e3dccb;
}

.TaskShowSection h2 {
  margin-top: 0;
  margin-bottom: 1rem;
  font-size: 1.25rem;
}

.TaskShowSection h3 {
  margin-top: 0;
  margin-bottom: 1rem;
  font-size: 1.1rem;
}

.TaskDetails {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.TaskDetailRow {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.TaskDetailRow strong {
  min-width: 120px;
}

.TaskBody {
  overflow-wrap: anywhere;
  line-height: 1.6;
}
.TaskBody p {
  margin-bottom: 0.75rem;
}
.TaskBody p:last-child {
  margin-bottom: 0;
}
.TaskBody ul, .TaskBody ol {
  margin: 0.5rem 0 0.75rem 1.5rem;
}
.TaskBody ul li, .TaskBody ol li {
  margin-bottom: 0.25rem;
}
.TaskBody hr {
  border: none;
  border-top: 2px solid #e3dccb;
  margin: 1rem 0;
}
.TaskBody a {
  color: #105151;
  text-decoration: underline;
}
.TaskBody strong {
  font-weight: 700;
}
.TaskBody em {
  font-style: italic;
}
.TaskBody del {
  text-decoration: line-through;
  color: #527070;
}
.TaskBody code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.875em;
  background: var(--color-bg);
  border: 1px solid #e3dccb;
  border-radius: 3px;
  padding: 0.1em 0.35em;
}
.TaskBody pre {
  background: var(--color-bg);
  border: 1px solid #e3dccb;
  border-radius: 4px;
  padding: 0.75rem 1rem;
  overflow-x: auto;
  margin: 0.75rem 0;
}
.TaskBody pre code {
  background: none;
  border: none;
  padding: 0;
  font-size: 0.875rem;
}
.TaskBody table {
  border-collapse: collapse;
  width: 100%;
  margin: 0.75rem 0;
  font-size: 0.9rem;
}
.TaskBody table th, .TaskBody table td {
  border: 1px solid #e3dccb;
  padding: 0.4rem 0.75rem;
  text-align: left;
}
.TaskBody table th {
  background: var(--color-bg);
  font-weight: 600;
}
.TaskBody table tr:nth-child(even) td {
  background: #fffdf7;
}

.TaskActions {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Badges */
.Badge {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  border-radius: 3px;
  white-space: nowrap;
}

.BadgeFeature {
  background: rgb(248.64, 240.96, 224.88);
  color: rgb(141.9883495146, 97.0019417476, 2.8116504854);
}

.BadgePriority {
  background: rgb(231.1, 237.6, 237.6);
  color: #105151;
}

.BadgePriority.priority-urgent {
  background: rgb(240.3, 202.15, 195.85);
  color: #5d091f;
}

.BadgePriority.priority-high {
  background: rgb(248.64, 240.96, 224.88);
  color: rgb(141.9883495146, 97.0019417476, 2.8116504854);
}

.BadgePriority.priority-backburner {
  background: #ece5d3;
  color: #527070;
}

.BadgeCompleted {
  background: rgb(227.76, 238.08, 231.48);
  color: #1c723b;
}

.BadgePending {
  background: rgb(220.55, 247.2, 148.4);
  color: #1f3d3d;
}

/* A task the schedule made, not a person. Links to the generator behind it. */
.BadgeGenerated {
  background: #ece5d3;
  color: #527070;
  text-decoration: none;
}
.BadgeGenerated:hover {
  color: #105151;
}

.BadgeOverdue {
  background: rgb(240.3, 202.15, 195.85);
  color: #5d091f;
}

.BadgeWarning {
  background: rgb(248.64, 240.96, 224.88);
  color: rgb(141.9883495146, 97.0019417476, 2.8116504854);
}

/* Vote Widget */
.TaskVoteWidget {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
}

.VoteDisplay {
  text-align: center;
}

.VoteCount {
  font-size: 2rem;
  font-weight: bold;
  color: #105151;
}

.VoteLabel {
  font-size: 0.9rem;
  color: #527070;
}

.VoteControls {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
}

.VoteButton {
  padding: 0.5rem 1rem;
  border: 1px solid #e3dccb;
  background: #fff;
  color: #527070;
  cursor: pointer;
  border-radius: 4px;
  font-weight: 600;
  transition: all 0.2s;
}

.VoteButtonUp:hover {
  background: rgb(227.76, 238.08, 231.48);
  border-color: #1c723b;
  color: #1c723b;
}

.VoteButtonDown:hover {
  background: rgb(240.3, 202.15, 195.85);
  border-color: #d56856;
  color: #5d091f;
}

.YourVote, .OtherVotes {
  font-size: 0.9rem;
  color: #527070;
  text-align: center;
}

/* Task Status Alerts */
.TaskStatus {
  margin-bottom: 1rem;
}

.Alert {
  padding: 1rem;
  border-radius: 4px;
  border-left: 4px solid;
}

.AlertSuccess {
  background: rgb(227.76, 238.08, 231.48);
  border-color: #1c723b;
  color: #1c723b;
}

.AlertDanger {
  background: rgb(240.3, 202.15, 195.85);
  border-color: #d56856;
  color: #5d091f;
}

.AlertWarning {
  background: rgb(248.64, 240.96, 224.88);
  border-color: #ca8a04;
  color: rgb(141.9883495146, 97.0019417476, 2.8116504854);
}

.AlertInfo {
  background: rgb(231.1, 237.6, 237.6);
  border-color: #105151;
  color: #105151;
}

/* Form Checkbox Groups */
.FormCheckboxGroup {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.5rem;
  padding: 0.5rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  max-height: 300px;
  overflow-y: auto;
}

.FormCheckboxItem {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem;
}

.FormCheckboxItem:hover {
  background: #faf7ee;
}

.FormCheckboxLabel {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
}

/* Responsive */
@media (max-width: 768px) {
  .TaskShow {
    grid-template-columns: minmax(0, 1fr);
  }
  .TaskRow {
    flex-wrap: wrap;
    align-items: flex-start;
  }
  .TaskRowActions {
    flex-basis: 100%;
    margin-left: 0;
    margin-top: 0.5rem;
  }
}
/* Task Mini Rows (home page "My Tasks" boxes)

   The row's own line is `.RowMain` (sales/_lists.shared.scss), the same
   content-plus-pinned-actions split the dashboard's sale and pull list rows use,
   with the details panel below it — so this is only the card around them. */
.TaskMiniRow {
  padding: 0.75rem;
  margin-bottom: 0.5rem;
  border-left: 3px solid transparent;
  background: #fff;
  border-radius: 4px;
  transition: all 0.2s;
}

.TaskMiniRow:last-child {
  margin-bottom: 0;
}

.TaskMiniRow:hover {
  background: #fffdf7;
}

.TaskMiniRow.overdue {
  border-left-color: #d56856;
  background: rgb(240.3, 202.15, 195.85);
}

.TaskMiniRow.priority-urgent {
  border-left-color: #d56856;
}

.TaskMiniRow.priority-high {
  border-left-color: #ca8a04;
}

.TaskMiniTitle {
  /* Takes the slack, so the badges sit against the actions cluster rather than
     drifting with the title's length. */
  flex: 1 1 auto;
  font-weight: 500;
  color: #1f3d3d;
  text-decoration: none;
  overflow-wrap: anywhere;
}

.TaskMiniTitle:hover {
  color: #105151;
}

.TaskMiniBadges {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.TaskMiniAssignees,
.TaskMiniDue {
  font-size: 0.85rem;
  color: #527070;
}

.TaskMiniDue.overdue {
  color: rgb(177, 75.5, 69.5);
  font-weight: 600;
}

/* What the row hides until the chevron is used: the task's body and its meta
   line, the same block the full row on /tasks shows outright. */
.TaskMiniDetails {
  display: grid;
  gap: 0.35rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
  /* `display: grid` beats the `hidden` attribute on its own. */
}
.TaskMiniDetails[hidden] {
  display: none !important;
}

/* Cancelled and completed rows stay readable but stop competing with the work
   that is still open — the same dimming the full row uses. */
.TaskMiniRow.completed,
.TaskMiniRow.cancelled {
  opacity: 0.6;
}

.FulfillmentsIndex__earlier {
  margin: 0.75rem 0 0;
  padding: 0.4rem 0.75rem;
  border-left: 4px solid #d56856;
  background: rgb(240.3, 202.15, 195.85);
  color: #5d091f;
  font-size: 0.9rem;
}

.FulfillmentRow {
  padding: 0.75rem 1rem;
}

.FulfillmentRow__line {
  align-items: center;
  flex-wrap: wrap;
}

.FulfillmentRow__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  flex: 1 1 16rem;
  min-width: 0;
  color: #1f3d3d;
  text-decoration: none;
}
.FulfillmentRow__summary:hover {
  color: #105151;
}

.FulfillmentRow__when {
  font-weight: 600;
  white-space: nowrap;
}

.FulfillmentRow__kind {
  font-size: 0.85rem;
  opacity: 0.75;
}

.FulfillmentRow__customer {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.FulfillmentRow__sale {
  font-size: 0.85rem;
  opacity: 0.75;
}

.FulfillmentRow__badges {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}

.FulfillmentRow__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin: 0.35rem 0 0 calc(24px + 0.75rem);
  font-size: 0.9rem;
}

.FulfillmentShow__header h1 {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.FulfillmentShow {
  background: var(--color-bg-light);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-bottom: 1.25rem;
}
.FulfillmentShow.is-overdue {
  border-left: 4px solid #d56856;
}

.FulfillmentShow__done {
  padding: 0.35rem 0.5rem;
  margin: -0.25rem 0 0.6rem;
  background: rgb(227.76, 238.08, 231.48);
  border-radius: 4px;
  font-size: 0.9rem;
}

.FulfillmentShow__columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem 2rem;
  margin-top: 1rem;
}

.FulfillmentShow__panel {
  min-width: 0;
}
.FulfillmentShow__panel h2 {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
  margin: 0 0 0.35rem;
}

.FulfillmentShow__contact {
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.FulfillmentShow__typed {
  margin-top: 0.6rem;
}

.FulfillmentShow__subhead {
  font-size: 0.8rem;
  font-weight: 600;
  margin: 0.75rem 0 0.25rem;
}

.FulfillmentShow__notes {
  white-space: normal;
  overflow-wrap: anywhere;
}
.FulfillmentShow__notes p {
  margin: 0 0 0.4rem;
}

.FulfillmentShow__items h2 {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.FulfillmentShow__table {
  width: 100%;
}
.FulfillmentShow__table tbody tr {
  background-image: linear-gradient(var(--st-row-tint, transparent), var(--st-row-tint, transparent));
}

.FulfillmentShow__header .CompleteToggleBtn {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  min-height: 0;
  padding: 0;
  margin: 0;
  font-size: 0.8rem;
}

.CommentsButtonWrap {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
}

.btn-comments {
  border: 1px solid #105151;
  border-radius: var(--btn-radius);
  background: #105151;
  color: #ffffff;
  cursor: pointer;
  padding: 0;
}
.btn-comments:hover {
  background: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}

.CommentsGlyph {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.CommentsGlyph > .Icon {
  stroke-width: 1.5;
  width: 1.75em;
  height: 1.75em;
}

.CommentCount {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 0.5em;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.CommentCount--wide {
  font-size: 0.4em;
  letter-spacing: -0.04em;
}

.CommentsDialog {
  border-radius: 8px;
  width: min(720px, 92vw);
  margin: 8vh auto;
}
.CommentsDialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}

.CommentsDialog turbo-frame {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.CommentsDialog turbo-frame > turbo-frame {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.CommentsDialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid #e3dccb;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  transition: box-shadow 0.2s;
}
[data-scroll-cues-more-above] > .CommentsDialog-header {
  box-shadow: 0 6px 10px -6px rgba(0, 0, 0, 0.28);
}
.CommentsDialog-header h2 {
  margin: 0;
  font-size: 1.1rem;
  color: #1f3d3d;
}

.CommentsDialog-title {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1 1 auto;
}

.CommentsDialog-subject {
  font-size: 0.8rem;
  color: #527070;
  overflow-wrap: anywhere;
}

.CommentsDialog-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: #527070;
  padding: 0 0.4rem 0.25rem;
  flex: 0 0 auto;
  align-self: flex-start;
}
.CommentsDialog-close:hover {
  color: #1f3d3d;
}

.CommentsList {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.CommentsList::before, .CommentsList::after {
  content: "";
  flex: 0 0 auto;
  align-self: center;
  width: min(200px, 60%);
  aspect-ratio: 10/1;
  background-color: #105151;
  opacity: 0.55;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 20'%3E%3Cdefs%3E%3ClinearGradient id='g'%3E%3Cstop offset='0' stop-opacity='0'/%3E%3Cstop offset='.4'/%3E%3Cstop offset='.6'/%3E%3Cstop offset='1' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M4 10C40 10 66 4 88 8C94 9 96 14 100 14C104 14 106 9 112 8C134 4 160 10 196 10' fill='none' stroke='url(%23g)' stroke-width='1.5' stroke-linecap='round'/%3E%3Cpath d='M100 2.5l2.5 3-2.5 3-2.5-3z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 20'%3E%3Cdefs%3E%3ClinearGradient id='g'%3E%3Cstop offset='0' stop-opacity='0'/%3E%3Cstop offset='.4'/%3E%3Cstop offset='.6'/%3E%3Cstop offset='1' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M4 10C40 10 66 4 88 8C94 9 96 14 100 14C104 14 106 9 112 8C134 4 160 10 196 10' fill='none' stroke='url(%23g)' stroke-width='1.5' stroke-linecap='round'/%3E%3Cpath d='M100 2.5l2.5 3-2.5 3-2.5-3z'/%3E%3C/svg%3E") center/contain no-repeat;
}
.CommentsList::after {
  transform: scaleY(-1);
}

.CommentsEmpty {
  color: #527070;
  font-size: 0.9rem;
  text-align: center;
  padding: 2rem 0;
}

.CommentsLoading {
  color: #527070;
  font-size: 0.9rem;
  padding: 1.5rem 1.25rem;
}

.Comment {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  background-color: #faf7ee;
  border: 1px solid #e3dccb;
  padding: 0.5rem;
}

.Comment-meta {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.Comment-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
}

.Comment-avatarImg {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.Comment-avatarInitials {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #105151;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1;
}

.Comment-meta-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex: 1;
}

.Comment-actions {
  display: flex;
  align-items: center;
  gap: 0.1rem;
  margin-left: auto;
  opacity: 0;
  transition: opacity 0.15s;
}
.Comment:hover .Comment-actions {
  opacity: 1;
}

.Comment-action {
  background: none;
  border: none;
  padding: 0.1rem 0.25rem;
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  border-radius: 4px;
  text-decoration: none;
}
.Comment-action:hover {
  background: #ece5d3;
}

.Comment-author {
  font-weight: 600;
  color: #105151;
}

.Comment-meta-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.Comment-time {
  color: #527070;
}

.CommentBadge {
  font-size: 0.6rem;
  font-weight: 700;
  padding: 0.1rem 0.35rem;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.CommentBadge--new {
  background: #105151;
  color: #fff;
}
.CommentBadge--updated {
  background: #e5c786;
  color: #1f3d3d;
}

@keyframes comment-badge-fade {
  0%, 50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
.Comment-body {
  overflow-wrap: anywhere;
  font-size: 0.9rem;
  line-height: 1.5;
}
.Comment-body p, .Comment-body ul, .Comment-body ol, .Comment-body blockquote, .Comment-body pre {
  margin: 0.3rem 0;
}
.Comment-body p:first-child, .Comment-body ul:first-child, .Comment-body ol:first-child, .Comment-body blockquote:first-child, .Comment-body pre:first-child {
  margin-top: 0;
}
.Comment-body p:last-child, .Comment-body ul:last-child, .Comment-body ol:last-child, .Comment-body blockquote:last-child, .Comment-body pre:last-child {
  margin-bottom: 0;
}
.Comment-body ul, .Comment-body ol {
  padding-left: 1.4rem;
}
.Comment-body hr {
  margin: 0.4rem 0;
  border: none;
  border-top: 1px solid #e3dccb;
}

.Comment--editing {
  padding: 0.5rem;
}
.Comment--editing .CommentForm-body {
  width: 100%;
}

.CommentEditActions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  justify-content: flex-end;
  margin-top: 0.25rem;
}

.CommentEditCancel {
  font-size: 0.85rem;
  color: #527070;
  text-decoration: none;
}
.CommentEditCancel:hover {
  color: #1f3d3d;
}

.CommentForm {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid #e3dccb;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  transition: box-shadow 0.2s;
}
[data-scroll-cues-more-below] .CommentForm {
  box-shadow: 0 -8px 12px -6px rgba(0, 0, 0, 0.28);
}

.CommentsMore {
  position: absolute;
  bottom: calc(100% + 0.6rem);
  left: 50%;
  transform: translate(-50%, 0.25rem);
  padding: 0.2rem 0.7rem;
  border: none;
  border-radius: 999px;
  background: #105151;
  color: #fff;
  font-size: 0.75rem;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, transform 0.2s, visibility 0s 0.2s;
}
.CommentsMore:hover {
  background: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}
[data-scroll-cues-more-below] .CommentsMore {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity 0.2s, transform 0.2s, visibility 0s;
}

.CommentForm-body {
  width: 100%;
  resize: vertical;
  padding: 0.5rem 0.75rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  font-family: inherit;
  font-size: 0.9rem;
  line-height: 1.5;
}
.CommentForm-body:focus {
  outline: none;
  border-color: #105151;
  box-shadow: 0 0 0 3px rgba(16, 81, 81, 0.15);
}
.CommentForm-body.is-invalid {
  border-color: rgb(177, 75.5, 69.5);
}

.CommentForm-error {
  font-size: 0.8rem;
  color: rgb(177, 75.5, 69.5);
}

.CommentForm-footer {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
}

.CommentForm-formatting {
  font-size: 0.8rem;
  color: #527070;
}
.CommentForm-formatting summary {
  cursor: pointer;
  user-select: none;
  color: #527070;
}
.CommentForm-formatting summary:hover {
  color: #1f3d3d;
}

.CommentForm-formattingList {
  margin: 0.4rem 0 0 0;
  padding-left: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.CommentForm-formattingList code {
  font-size: 0.8em;
  background: #ece5d3;
  border-radius: 3px;
  padding: 0.05em 0.3em;
}

.CommentForm-notified {
  flex-shrink: 0;
  text-align: right;
}
.CommentForm-notified summary {
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}
.CommentForm-notified summary:hover {
  color: #1f3d3d;
}

.CommentForm-notifiedList {
  margin: 0.4rem 0 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.CommentForm-submit {
  align-self: flex-end;
  padding: 0.4rem 1rem;
  background: #105151;
  color: #fff;
  border: none;
  border-radius: 4px;
  font-size: 0.875rem;
  cursor: pointer;
}
.CommentForm-submit:hover {
  background: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}

#NotificationDock {
  container-type: inline-size;
  position: fixed;
  top: var(--app-header-height);
  left: 0;
  height: calc(100vh - var(--app-header-height));
  width: var(--notif-dock-width);
  transform: translateX(-100%);
  will-change: transform;
  transition: transform var(--dock-transition-duration) var(--dock-transition-ease), width var(--dock-transition-duration) var(--dock-transition-ease);
  z-index: var(--z-dock);
  background: #fff;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  overscroll-behavior: contain;
}

#NotificationDock.Open {
  transform: translateX(0);
  box-shadow: 2px 0 12px rgba(0, 0, 0, 0.15);
}

.NotifDockHeader {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0.75rem;
  gap: 0.5rem;
  background: #fff;
  border-bottom: 1px solid #e3dccb;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02);
  flex-shrink: 0;
}

.NotifDockHeader-left,
.NotifDockHeader-right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.NotifDockTitle {
  font-weight: 600;
  font-size: 0.95rem;
}

@container (max-width: 280px) {
  .NotifDockTitle {
    display: none;
  }
}
.NotifDockHeader .CloseButton {
  line-height: 1;
  border: 0;
  cursor: pointer;
  font-size: 1rem;
  padding: 0.35rem 0.5rem;
  border-radius: 0.25rem;
}
.NotifDockHeader .CloseButton:hover {
  background: var(--color-accent);
}

.NotifRefreshBtn {
  font-size: 1rem;
  color: #527070;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  border-radius: 0.25rem;
  line-height: 1;
}
.NotifRefreshBtn:hover {
  color: #1f3d3d;
  background: #ece5d3;
}

.NotifMarkAllBtn {
  font-size: 0.75rem;
  color: #527070;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  border-radius: 0.25rem;
  white-space: nowrap;
}
.NotifMarkAllBtn:hover {
  color: #1f3d3d;
  background: #ece5d3;
}

.NotifDockBody {
  flex: 1;
  overflow-y: auto;
  background-color: #fffdf7;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15.59' height='27' viewBox='0 0 15.59 27'%3E%3Cg stroke='rgb(16,81,81)' stroke-opacity='0.08'%3E%3Cpath fill='none' stroke-width='1' d='M7.795 0L15.59 4.5V13.5L7.795 18L0 13.5V4.5ZM7.795 18V27'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 15.59px 27px;
  background-attachment: local;
  border-left: 1px solid #e3dccb;
}
@media print {
  .NotifDockBody {
    background-image: none;
  }
}

#dock_notification_list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.5rem;
}
#dock_notification_list .NotifGroup {
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid #e3dccb;
  border-left-width: 3px;
  border-radius: 0.375rem;
}
#dock_notification_list .NotifGroup:not(.Unread) {
  border-left-color: #e3dccb;
}
#dock_notification_list .NotifGroup.Unread {
  background: rgba(238.27, 242.82, 242.82, 0.7);
}

.NotifEmpty {
  padding: 2rem 1rem;
  text-align: center;
  color: #527070;
  font-size: 0.9rem;
}

.NotifDockFooter {
  flex-shrink: 0;
  border-top: 1px solid #e3dccb;
  background: #fff;
  text-align: center;
  padding: 0.55rem 1rem;
}

.NotifDockFooter-link {
  font-size: 0.8rem;
  color: #527070;
  text-decoration: none;
}
.NotifDockFooter-link:hover {
  color: #1f3d3d;
  text-decoration: underline;
}

.NotifGroup {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid #e3dccb;
  background: #fff;
  border-left: 3px solid transparent;
  transition: background 0.1s;
}
.NotifGroup.Unread {
  background: rgb(238.27, 242.82, 242.82);
  border-left-color: #105151;
  cursor: pointer;
}

.NotifGroup-header {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
}

.NotifGroup-icon {
  font-size: 1rem;
  flex-shrink: 0;
  margin-top: 0.1rem;
}

.NotifGroup-subject {
  flex: 1;
  min-width: 0;
}

.NotifGroup-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: #1f3d3d;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.NotifGroup-title a {
  color: inherit;
  text-decoration: none;
}
.NotifGroup-title a:hover {
  text-decoration: underline;
}

.NotifGroup-event {
  font-size: 0.75rem;
  color: #527070;
  margin-top: 0.1rem;
}

.NotifGroup-actors {
  font-size: 0.8rem;
  color: #1f3d3d;
  margin-bottom: 0.25rem;
}

.NotifGroup-comments {
  margin: 0.4rem 0 0.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.NotifGroup-comment {
  overflow-wrap: anywhere;
  font-size: 0.8rem;
  color: #1f3d3d;
  line-height: 1.4;
  padding: 0.2rem 0.4rem;
  border-left: 2px solid #e3dccb;
  border-radius: 0 2px 2px 0;
}
.NotifGroup-comment ol, .NotifGroup-comment ul {
  margin: 0.25rem 0 0.25rem 1.25rem;
  padding: 0;
}
.NotifGroup-comment p {
  margin: 0;
}
.NotifGroup-comment p + p {
  margin-top: 0.25rem;
}

.NotifGroup-comment--read {
  color: #527070;
  border-left-color: transparent;
}

.NotifGroup-comment--context {
  color: #527070;
  border-left-color: transparent;
  transition: color 0.15s;
}
.NotifGroup-comment--context:hover {
  color: #1f3d3d;
}

.NotifGroup-comment-author {
  font-weight: 600;
  margin-right: 0.2rem;
}

.NotifGroup-time {
  font-size: 0.75rem;
  color: #527070;
}

.NotifGroup-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.4rem;
}

.NotifMarkUnreadBtn {
  font-size: 0.75rem;
  color: #527070;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.2rem 0;
  text-decoration: underline;
}
.NotifMarkUnreadBtn:hover {
  color: #1f3d3d;
}

.NotifMarkForm {
  display: inline;
}

.NotifSnoozeIcon {
  display: none;
  position: absolute;
  bottom: 4px;
  right: 0;
  line-height: 1;
  pointer-events: none;
}

html.notif-heartbeat-snoozed .NotifSnoozeIcon {
  display: block;
}

@keyframes notif-badge-pulse {
  0% {
    transform: scale(1);
  }
  40% {
    transform: scale(1.45);
  }
  70% {
    transform: scale(0.9);
  }
  100% {
    transform: scale(1);
  }
}
#NotificationToggle {
  position: relative;
  background: none;
  border: none;
  font-size: 1.2rem;
  cursor: pointer;
  padding: 0.25rem 0.4rem;
  border-radius: 0.375rem;
  color: #ffffff;
  display: flex;
  align-items: center;
  line-height: 1;
}
#NotificationToggle:hover {
  background: rgba(255, 255, 255, 0.08);
}

.NotifBadge.Pulse {
  animation: notif-badge-pulse 0.4s ease-out;
}

.NotifBadge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25em;
  padding: 0 0.3em;
  height: 1.25em;
  background: rgb(177, 75.5, 69.5);
  color: #fff;
  font-size: 0.85rem;
  border-radius: 999px;
  line-height: 1;
  margin-left: -0.2rem;
  margin-top: -0.6rem;
}
.NotifBadge.Hidden {
  display: none;
}

.NotifPage .PageHeaderActions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.NotifPage .PageHeaderActions form {
  display: contents;
}

.NotifPage {
  margin: 0 auto;
}
.NotifPage h1 {
  margin-bottom: 1rem;
}

@media (max-width: 767px) {
  #NotificationDock {
    display: none !important;
  }
  .NotifPage .PageHeader {
    flex-direction: column;
    align-items: flex-start;
    gap: 0rem;
    margin-bottom: 0.5rem;
  }
  .NotifPage .PageHeader h1 {
    margin-bottom: 0;
  }
  .NotifPage .PageHeaderActions .Button,
  .NotifPage .PageHeaderActions .Button--secondary {
    padding: 0.35rem 0.65rem;
    font-size: 0.82rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  #NotificationDock {
    transition: none !important;
  }
}
/* Customer email settings (/site/emails) and the sent-mail log (/emails). */
/* ===== Settings list ===== */
.EmailTemplates {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.EmailTemplates__row {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: 6px;
}
.EmailTemplates__row.is-off {
  border-left-color: var(--color-border);
}
.EmailTemplates__row.is-off .EmailTemplates__main {
  opacity: 0.6;
}
@media (max-width: 600px) {
  .EmailTemplates__row {
    flex-direction: column;
  }
}

.EmailTemplates__name {
  margin: 0 0 0.25rem;
  font-size: 1.05rem;
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
}

.EmailTemplates__trigger,
.EmailTemplates__subject,
.EmailTemplates__count {
  margin: 0.15rem 0;
  font-size: 0.9em;
}

.EmailTemplates__subject {
  overflow-wrap: anywhere;
}

.EmailTemplates__count,
.EmailTemplates__subject {
  color: var(--color-text-faint);
}

.EmailTemplates__actions {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
  align-items: center;
}
.EmailTemplates__actions form {
  margin: 0;
}

/* ===== Edit form ===== */
.EmailTemplateForm textarea {
  width: 100%;
  font-family: inherit;
}

.EmailTemplateForm__tokens {
  margin-top: 0.5rem;
  font-size: 0.9em;
}
.EmailTemplateForm__tokens dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
  margin: 0.5rem 0 0;
}
.EmailTemplateForm__tokens dd {
  margin: 0;
}

.EmailTemplateForm__actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.EmailTemplates__previewHeading {
  margin-top: 2rem;
}

/* ===== Preview / message as sent ===== */
.EmailPreview__headers {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 1rem;
  margin: 0.5rem 0 1rem;
  font-size: 0.9em;
}
.EmailPreview__headers dt {
  color: var(--color-text-faint);
}
.EmailPreview__headers dd {
  margin: 0;
  overflow-wrap: anywhere;
}

/* The email is its own light document, whatever the app's theme. */
.EmailPreview__frame {
  display: block;
  width: 100%;
  min-height: 560px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: #fff;
}

.EmailPreview__text {
  white-space: pre-wrap;
  font-size: 0.85em;
  padding: 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
}

.EmailPreview__notice {
  padding: 0.5rem 0.75rem;
  border-left: 3px solid var(--color-success);
  background: var(--color-bg-light);
}

/* ===== Sent-mail log ===== */
.EmailsSummary {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.75rem 0;
}

.EmailsSummary__stat {
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
}
.EmailsSummary__stat strong {
  font-size: 1.1em;
}
.EmailsSummary__stat.is-active {
  border-color: var(--color-primary);
  box-shadow: inset 0 0 0 1px var(--color-primary);
}
.EmailsSummary__stat--problem {
  border-color: var(--color-danger);
  color: var(--color-danger-dark);
}

.EmailsIndex__scroll {
  overflow-x: auto;
}

.EmailsIndex {
  margin-top: 0;
}
.EmailsIndex tr.is-problem td {
  background: var(--color-danger-light);
}

/* A phone has no room for five columns: each email becomes a stacked card. */
@media (max-width: 640px) {
  .EmailsIndex thead {
    display: none;
  }
  .EmailsIndex,
  .EmailsIndex tbody,
  .EmailsIndex tr,
  .EmailsIndex td {
    display: block;
  }
  .EmailsIndex tr {
    margin-bottom: 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
  }
  .EmailsIndex td {
    border: none;
    padding: 0.1rem 0;
  }
  .EmailsIndex tr.is-problem td {
    background: transparent;
  }
  .EmailsIndex tr.is-problem {
    background: var(--color-danger-light);
  }
}
.EmailsIndex__when {
  white-space: nowrap;
}

.EmailsIndex__to {
  overflow-wrap: anywhere;
}

.EmailsIndex__kind {
  font-size: 0.85em;
  color: var(--color-text-faint);
}

.EmailsIndex__scope {
  margin: 0.5rem 0;
}

.EmailShow__subject {
  overflow-wrap: anywhere;
}

.EmailShow__heading {
  font-size: 1.05rem;
  margin-top: 1.5rem;
}

.EmailShow__history {
  padding-left: 1.25rem;
}

.EmailShow__error {
  color: var(--color-danger);
}

.EmailResend {
  margin: 1rem 0 1.5rem;
}

.EmailResend__label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.EmailResend__row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.EmailResend__row input:not([type=submit]) {
  flex: 1 1 16rem;
  min-width: 0;
}

/* ===== Sale dock panel ===== */
.SaleEmails__list {
  list-style: none;
  margin: 0.25rem 0;
  padding: 0;
}
.SaleEmails__list li {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  padding: 0.15rem 0;
}

/* The folded line's "latest email and how it went", after the uppercase
   count. Ordinary case and weight: it is content, not part of the label. */
.SaleEmails__latest {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: 0.35rem;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.SaleEmails__latest .Badge {
  font-size: 0.85em;
}

/* The home dashboard (home/index). Its sections are the lists' own rows in
   BoxContainers; what is here is the strip of counts across the top and the
   week's calendar events. */
/* The size container: the whole width #main-content gives the page, so the
   query below reads the room actually left beside whichever docks are open. */
.HomeDashboardContainer {
  container-type: inline-size;
}

/* One column, at the width the app's other pages read at. */
.HomeDashboard {
  max-width: 800px;
}

.HomeDashboard__column {
  min-width: 0;
}

/* The column sets the width now; a BoxContainer's own 800px cap would leave a
   split column's boxes short of its edge. The single column is still held to
   800px by .HomeDashboard above. */
.HomeDashboard__column > .BoxContainer {
  max-width: none;
}

/* Two columns once there is room for both to be comfortable: the work column
   (pickups, pending sales, pull lists, emails) takes the larger share, the
   person's tasks and the calendar the rest. `start` so a short side column
   does not stretch to the work column's height. The sale dock opts out
   whatever the width: a sale open beside the page is what the rows are being
   read against, and they want the whole of what is left. */
@container (min-width: 1000px) {
  html:not(.sale-dock-open) .HomeDashboard:has(.HomeDashboard__columns.is-split) {
    max-width: 1440px;
  }
  html:not(.sale-dock-open) .HomeDashboard__columns.is-split {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    align-items: start;
    gap: 0 1.5rem;
  }
}
.HomeDashboard .PageHeader {
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.75rem;
}

.HomeDashboard__date {
  margin: 0;
  color: #527070;
}

/* At a glance: one tile per count, each a link to the page that lists it.
   auto-fill keeps the tiles a readable width at any size — two abreast on a
   phone, five or six on a desktop. */
.HomeGlance {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.6rem;
  margin: 1rem 0 1.25rem;
}

.HomeGlance__tile {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.65rem 0.8rem;
  background: #fffdf7;
  border: 1px solid #e3dccb;
  border-left: 4px solid #105151;
  border-radius: 10px;
  color: #1f3d3d;
  text-decoration: none;
}
.HomeGlance__tile:hover, .HomeGlance__tile:focus-visible {
  border-color: #105151;
}
.HomeGlance__tile.is-zero {
  border-left-color: #e3dccb;
}
.HomeGlance__tile.is-zero .HomeGlance__count {
  opacity: 0.4;
}
.HomeGlance__tile.is-alert {
  border-left-color: #ca8a04;
  background: rgb(248.64, 240.96, 224.88);
}

.HomeGlance__count {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.HomeGlance__label {
  font-size: 0.8rem;
  color: #527070;
}

/* The week's events, in their type's colour as the calendar draws them. */
.HomeEvents {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.HomeEvents__event {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.45rem 0.7rem;
  background: color-mix(in srgb, var(--event-color) 12%, transparent);
  border-left: 3px solid var(--event-color);
  border-radius: 6px;
}

.HomeEvents__when {
  display: grid;
  flex: none;
  width: 4.5rem;
  font-weight: 600;
  line-height: 1.2;
}

.HomeEvents__date {
  font-size: 0.75rem;
  font-weight: 400;
  color: #527070;
}

.HomeEvents__what {
  display: grid;
  min-width: 0;
  flex: 1;
  line-height: 1.25;
}

.HomeEvents__title {
  overflow-wrap: anywhere;
}

.HomeEvents__meta {
  font-size: 0.8rem;
  color: #527070;
}

.DemoBanner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 0.4rem 1rem;
  background: #e5c786;
  color: #1f3d3d;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
}
.DemoBanner__cta {
  color: #105151;
  font-weight: 700;
  text-decoration: underline;
}

.UserInitials {
  cursor: help;
  white-space: nowrap;
}

.UserAvatar {
  flex-shrink: 0;
  display: inline-flex;
  vertical-align: middle;
}
.UserAvatar__img {
  border-radius: 25%;
  object-fit: cover;
  display: block;
}
.UserAvatar__initials {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 25%;
  color: #fff;
  font-weight: 600;
  line-height: 1;
}

.UserProfile-card {
  --user-color: #105151;
  position: relative;
  background: #fff;
  border: 1px solid var(--user-color);
  border-top: 4px solid var(--user-color);
  border-radius: 10px;
  overflow: hidden;
}

.UserProfile-cardActions {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 1;
}

.UserProfile-editBtn {
  padding: 0.3rem 0.9rem;
  font-size: 0.85rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 6px;
  color: #1f3d3d;
  cursor: pointer;
}
.UserProfile-editBtn:hover {
  background: #faf7ee;
  color: #105151;
}

.UserProfile-formPanel {
  padding: 1.5rem;
}

.UserProfile-formHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}

.UserProfile-formTitle {
  font-size: 1rem;
  font-weight: 600;
  color: #1f3d3d;
}

.UserProfile-cancelBtn {
  padding: 0.3rem 0.9rem;
  font-size: 0.85rem;
  background: none;
  border: 1px solid #e3dccb;
  border-radius: 6px;
  color: #527070;
  cursor: pointer;
}
.UserProfile-cancelBtn:hover {
  background: #faf7ee;
  color: #1f3d3d;
}

.UserProfile-hero {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 1.5rem;
  border-bottom: 1px solid #e3dccb;
  background: linear-gradient(160deg, #fff 40%, #faf7ee 100%);
}

.UserProfile-avatar {
  flex-shrink: 0;
}

.UserProfile-avatarImg {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  border: 3px solid #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}

.UserProfile-avatarInitials {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: var(--user-color);
  color: #fff;
  font-size: 1.75rem;
  font-weight: 700;
  border: 3px solid #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}

.UserProfile-card:has(.UserProfile-cardActions) .UserProfile-hero {
  padding-right: 5.5rem;
}

.UserProfile-identity {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.UserProfile-name {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 700;
  color: #1f3d3d;
  line-height: 1.2;
}

.UserProfile-company {
  font-size: 0.9rem;
  color: #527070;
}

.UserProfile-sections {
  padding: 0 1.5rem;
}

.UserProfile-section {
  padding: 1rem 0;
  border-bottom: 1px solid #e3dccb;
}
.UserProfile-section:last-child {
  border-bottom: none;
}

.UserProfile-sectionTitle {
  margin: 0 0 0.6rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: #527070;
}

.UserProfile-dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1.25rem;
  margin: 0;
  font-size: 0.9rem;
}
.UserProfile-dl dt {
  color: #527070;
  font-weight: 500;
  white-space: nowrap;
}
.UserProfile-dl dd {
  margin: 0;
  color: #1f3d3d;
}

.PushSettings-device {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-bottom: 0.75rem;
}
.PushSettings-device .hint {
  flex-basis: 100%;
  margin: 0;
}

.PushSettings-status {
  margin: 0;
  font-size: 0.9rem;
  color: #1f3d3d;
}

.PushSettings-categories {
  display: grid;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.PushSettings-categories > .hint {
  margin: 0;
}

.PushSettings-category {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.9rem;
  cursor: pointer;
}
.PushSettings-category input {
  margin-top: 0.2rem;
}
.PushSettings-category > span {
  display: grid;
  gap: 0.1rem;
}
.PushSettings-category .hint {
  margin: 0;
}

.ContactCard {
  --user-color: #105151;
  padding: 0.9rem 1rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-left: 4px solid var(--user-color);
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  display: block;
  max-width: 26rem;
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}
.ContactCard__summary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0.85rem;
  cursor: pointer;
  list-style: none;
}
.ContactCard__summary::-webkit-details-marker {
  display: none;
}
.ContactCard__summary::marker {
  content: "";
}
.ContactCard__avatar {
  line-height: 0;
}
.ContactCard__identity {
  min-width: 0;
}
.ContactCard__name {
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1.25;
}
.ContactCard__name a {
  color: #1f3d3d;
  text-decoration: none;
}
.ContactCard__company {
  font-size: 0.9rem;
  color: #527070;
}
.ContactCard__chevron {
  display: inline-flex;
  color: #527070;
  transition: transform 0.15s ease;
}
.ContactCard[open] > .ContactCard__summary .ContactCard__chevron {
  transform: rotate(90deg);
}
.ContactCard__body {
  margin-top: 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid #e3dccb;
  padding-bottom: 0.15rem;
}
.ContactCard__empty {
  margin: 0;
  font-size: 0.9rem;
}
.ContactCard__footer {
  margin-top: 0.6rem;
  font-size: 0.85rem;
}

.ContactLines {
  display: grid;
  gap: 0.35rem;
  justify-items: start;
}

.ContactLines__line {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.95rem;
  overflow-wrap: anywhere;
  color: inherit;
  text-decoration: none;
}
.ContactLines__line:hover > span:last-child, .ContactLines__line:focus-visible > span:last-child {
  text-decoration: underline;
}

.ContactLines__line--phone {
  white-space: nowrap;
}

.ContactLines__glyph {
  display: inline-flex;
  flex: none;
  color: var(--user-color);
}

.PeopleTable .PeopleRow__avatar,
.PeopleTable .PeopleRow__place,
.PeopleTable .PeopleRow__glyph {
  display: none;
}
.PeopleTable .PeopleRow__link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: inherit;
}

@media (max-width: 767px) {
  .PeopleTable {
    display: block;
    border: 0;
  }
  .PeopleTable thead {
    display: none;
  }
  .PeopleTable tbody {
    display: grid;
    gap: 0.75rem;
  }
  .PeopleTable tr.PeopleRow {
    --user-color: #105151;
    padding: 0.9rem 1rem;
    background: #fff;
    border: 1px solid #e3dccb;
    border-left: 4px solid var(--user-color);
    border-radius: 10px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "avatar name    edit" "avatar company edit" "email  email   email" "phone  phone   phone" "place  place   place" "perms  perms   perms";
    column-gap: 0.85rem;
  }
  .PeopleTable td {
    display: block;
    border: 0;
    padding: 0;
    min-width: 0;
  }
  .PeopleTable .PeopleRow__avatar {
    display: block;
    grid-area: avatar;
    align-self: center;
  }
  .PeopleTable .PeopleRow__avatar a {
    display: block;
    line-height: 0;
  }
  .PeopleTable .PeopleRow__name {
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1.25;
    grid-area: name;
    align-self: end;
  }
  .PeopleTable .PeopleRow__name a {
    color: #1f3d3d;
    text-decoration: none;
  }
  .PeopleTable tr.PeopleRow:has(> .PeopleRow__company.is-blank) .PeopleRow__name {
    grid-row: 1/3;
    align-self: center;
  }
  .PeopleTable .PeopleRow__company {
    font-size: 0.9rem;
    color: #527070;
    grid-area: company;
    align-self: start;
  }
  .PeopleTable .PeopleRow__editLink {
    grid-area: edit;
    align-self: start;
    font-size: 1.1rem;
  }
  .PeopleTable td.is-blank {
    display: none;
  }
  .PeopleTable .PeopleRow__contact {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.95rem;
    overflow-wrap: anywhere;
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px solid #e3dccb;
  }
  .PeopleTable .PeopleRow__contact:not(.is-blank) ~ .PeopleRow__contact {
    margin-top: 0;
    padding-top: 0.35rem;
    border-top: 0;
  }
  .PeopleTable .PeopleRow__email {
    grid-area: email;
  }
  .PeopleTable .PeopleRow__phone {
    grid-area: phone;
  }
  .PeopleTable .PeopleRow__link {
    text-decoration: none;
  }
  .PeopleTable .PeopleRow__place {
    grid-area: place;
  }
  .PeopleTable .PeopleRow__glyph {
    display: inline-flex;
    color: var(--user-color);
  }
  .PeopleTable .PeopleRow__permissions {
    grid-area: perms;
    margin-top: 0.6rem;
    font-size: 1.05rem;
    letter-spacing: 0.15em;
  }
  .PeopleTable .PeopleRow__edit {
    grid-column: 1/-1;
  }
}
.UserProfilePageContainer {
  container-type: inline-size;
}

.UserProfilePage {
  max-width: 800px;
}

.UserProfilePage__main,
.UserProfilePage__side {
  min-width: 0;
}

@container (min-width: 1000px) {
  html:not(.sale-dock-open) .UserProfilePage.is-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    align-items: start;
    gap: 0 1.5rem;
    max-width: 1440px;
  }
  html:not(.sale-dock-open) .UserProfilePage.is-split .UserProfilePage__side > :first-child {
    margin-top: 0;
  }
}
.UserOrders,
.UserPanel {
  margin-top: 1rem;
  padding: 1rem 1.5rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 10px;
}
@media (max-width: 767px) {
  .UserOrders,
  .UserPanel {
    padding: 0.9rem 1rem;
  }
}

.UserOrders__summary {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
  color: #527070;
}
.UserOrders__table {
  width: 100%;
  font-size: 0.9rem;
}
.UserOrders__table th {
  font-size: 0.75rem;
}
.UserOrders__table .num {
  text-align: right;
}
.UserOrders__table tr.is-cancelled td {
  opacity: 0.55;
}
.UserOrders__more {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
}

.UserPanel__list {
  display: grid;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.UserPanel__item {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.45rem 0.5rem;
  border-radius: 6px;
}
.UserPanel__item.is-overdue, .UserPanel__item.is-problem {
  background: rgb(248.64, 240.96, 224.88);
}
.UserPanel__icon {
  display: inline-flex;
  flex: none;
  margin-top: 0.1rem;
  color: #527070;
}
.UserPanel__main {
  display: grid;
  flex: 1;
  min-width: 0;
  gap: 0.1rem;
}
.UserPanel__title {
  font-weight: 600;
  overflow-wrap: anywhere;
}
.UserPanel__meta {
  font-size: 0.8rem;
  color: #527070;
  overflow-wrap: anywhere;
}
.UserPanel .Badge {
  flex: none;
}
.UserPanel__more {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
}

.LeadBreadcrumb {
  font-size: 0.85rem;
  margin-bottom: 0.25rem;
}

.LeadProfile-card {
  --lead-color: #105151;
  --lead-color-soft: rgb(226.32, 234.12, 234.12);
  --lead-color-border: rgb(147.45, 176.7, 176.7);
  --lead-color-ink: #164949;
  position: relative;
  background: #fff;
  border: 1px solid var(--lead-color-border);
  border-top: 4px solid var(--lead-color);
  border-radius: 10px;
  overflow: hidden;
  margin-top: 1rem;
}
.LeadProfile-card--new {
  --lead-color: #527070;
  --lead-color-soft: rgb(234.24, 237.84, 237.84);
  --lead-color-border: rgb(177.15, 190.65, 190.65);
  --lead-color-ink: rgb(61.6, 91.6, 91.6);
}
.LeadProfile-card--contacted {
  --lead-color: #ca8a04;
  --lead-color-soft: rgb(248.64, 240.96, 224.88);
  --lead-color-border: rgb(231.15, 202.35, 142.05);
  --lead-color-ink: rgb(133.6, 107.2, 26.8);
}
.LeadProfile-card--demo-created {
  --lead-color: #0d6969;
  --lead-color-soft: rgb(225.96, 237, 237);
  --lead-color-border: rgb(146.1, 187.5, 187.5);
  --lead-color-ink: rgb(20.2, 87.4, 87.4);
}
.LeadProfile-card--converted {
  --lead-color: #1c723b;
  --lead-color-soft: rgb(227.76, 238.08, 231.48);
  --lead-color-border: rgb(152.85, 191.55, 166.8);
  --lead-color-ink: rgb(29.2, 92.8, 59.8);
}
.LeadProfile-card--declined {
  --lead-color: rgb(177, 75.5, 69.5);
  --lead-color-soft: rgb(245.64, 233.46, 232.74);
  --lead-color-border: rgb(219.9, 174.225, 171.525);
  --lead-color-ink: rgb(118.6, 69.7, 66.1);
}

.LeadProfile-cardActions {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 1;
}

.LeadProfile-editBtn {
  padding: 0.3rem 0.9rem;
  font-size: 0.85rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 6px;
  color: #1f3d3d;
  cursor: pointer;
}
.LeadProfile-editBtn:hover {
  background: #faf7ee;
  color: #105151;
}

.LeadProfile-formPanel {
  padding: 1.5rem;
}
.LeadProfile-formPanel .LeadForm-field {
  flex: 1 1 220px;
  flex-direction: column;
  gap: 0.15rem;
}
.LeadProfile-formPanel .LeadForm-field label {
  font-size: 0.8rem;
  font-weight: 600;
  color: #527070;
}
.LeadProfile-formPanel .LeadForm-field input, .LeadProfile-formPanel .LeadForm-field textarea {
  flex: 0 0 auto;
  width: 100%;
  padding: 0.5rem;
  font-size: 0.95rem;
}
.LeadProfile-formPanel .LeadForm-field .hint {
  margin-top: 0.15rem;
}

.LeadProfile-formHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}

.LeadProfile-formTitle {
  font-size: 1rem;
  font-weight: 600;
  color: #1f3d3d;
}

.LeadProfile-cancelBtn {
  padding: 0.3rem 0.9rem;
  font-size: 0.85rem;
  background: none;
  border: 1px solid #e3dccb;
  border-radius: 6px;
  color: #527070;
  cursor: pointer;
}
.LeadProfile-cancelBtn:hover {
  background: #faf7ee;
  color: #1f3d3d;
}

.LeadProfile-hero {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 1.5rem;
  padding-right: 6rem;
  border-bottom: 1px solid #e3dccb;
  background: linear-gradient(160deg, #fff 40%, var(--lead-color-soft) 100%);
}

.LeadProfile-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--lead-color);
  color: #fff;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  border: 3px solid #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}

.LeadProfile-identity {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
  flex: 1 1 auto;
}

.LeadProfile-name {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 700;
  color: #1f3d3d;
  line-height: 1.2;
}

.LeadProfile-business {
  font-size: 0.9rem;
  color: #527070;
}

.LeadProfile-email {
  font-size: 0.85rem;
  color: #527070;
}

.LeadStatusBadge {
  flex-shrink: 0;
  align-self: flex-start;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  background: #fff;
  color: var(--lead-color-ink);
  border: 1px solid var(--lead-color-border);
}

.LeadProfile-sections {
  padding: 0 1.5rem;
}

.LeadProfile-section {
  margin-top: 0;
  padding: 1rem 0;
  border-bottom: 1px solid #e3dccb;
}
.LeadProfile-section:last-child {
  border-bottom: none;
}

.LeadProfile-sectionTitle {
  margin: 0 0 0.6rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: #527070;
}

.LeadProfile-dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1.25rem;
  margin: 0;
  font-size: 0.9rem;
}
.LeadProfile-dl dt {
  color: #527070;
  font-weight: 500;
  white-space: nowrap;
}
.LeadProfile-dl dd {
  margin: 0;
  color: #1f3d3d;
  min-width: 0;
}

.LeadProfile-empty {
  color: #527070;
  font-style: italic;
}

.LeadProfile-notes {
  font-size: 0.9rem;
  color: #1f3d3d;
  background: #fffdf7;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  padding: 0.75rem 0.9rem;
}
.LeadProfile-notes p {
  margin: 0 0 0.5rem;
}
.LeadProfile-notes p:last-child {
  margin-bottom: 0;
}

.LeadFeatureChips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.LeadFeatureChip {
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.8rem;
  background: #faf7ee;
  border: 1px solid #e3dccb;
  color: #1f3d3d;
}

.LeadTimeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem;
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}

.LeadTimeline-step {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-left: 0.75rem;
  border-left: 3px solid #e3dccb;
}
.LeadTimeline-step.is-done {
  border-left-color: var(--lead-color);
}

.LeadTimeline-label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #527070;
}

.LeadTimeline-when {
  font-size: 0.85rem;
  color: #1f3d3d;
}

.LeadStatusActions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.LeadStatusActions-label {
  font-size: 0.8rem;
  color: #527070;
  margin-right: 0.15rem;
}

.LeadStatusActions-form {
  display: inline;
}

.LeadPanel {
  margin-top: 1.25rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
}

.LeadPanel-title {
  margin: 0 0 0.75rem;
  font-size: 1rem;
  font-weight: 600;
  color: #1f3d3d;
}

.LeadPanel-hint {
  font-size: 0.85rem;
  color: #527070;
  margin-bottom: 0.9rem;
}

.LeadPanel-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.85rem;
  background: #faf7ee;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  padding: 0.05rem 0.35rem;
}

.LeadStatusBadge--new {
  --lead-color: #527070;
  --lead-color-soft: rgb(234.24, 237.84, 237.84);
  --lead-color-border: rgb(177.15, 190.65, 190.65);
  --lead-color-ink: rgb(61.6, 91.6, 91.6);
}
.LeadStatusBadge--contacted {
  --lead-color: #ca8a04;
  --lead-color-soft: rgb(248.64, 240.96, 224.88);
  --lead-color-border: rgb(231.15, 202.35, 142.05);
  --lead-color-ink: rgb(133.6, 107.2, 26.8);
}
.LeadStatusBadge--converted {
  --lead-color: #1c723b;
  --lead-color-soft: rgb(227.76, 238.08, 231.48);
  --lead-color-border: rgb(152.85, 191.55, 166.8);
  --lead-color-ink: rgb(29.2, 92.8, 59.8);
}

.BetaProgram-invite {
  margin-bottom: 0.5rem;
}

.BetaProgram-directLink {
  margin-top: 0.6rem;
}

.BetaProgram-linkText {
  display: block;
  margin-top: 0.2rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  background: #fffdf7;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.68rem;
  line-height: 1.4;
  color: #527070;
  overflow-wrap: anywhere;
  word-break: break-all;
}

.BetaProgram-linkText.Copied {
  border-color: #1c723b;
  color: #1f3d3d;
}

.BetaProgram-subtitle {
  margin: 1.25rem 0 0.5rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: #527070;
}

.BetaProgram-survey {
  padding: 0.75rem 0;
  border-top: 1px solid #e3dccb;
}

.BetaProgram-surveyHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.BetaProgram-surveyName {
  font-weight: 600;
  font-size: 0.9rem;
}

.BetaProgram-meta {
  margin-top: 0.5rem;
  font-size: 0.8rem;
  color: #527070;
}

.BetaProgram-effective {
  font-size: 0.9rem;
  margin-bottom: 0.5rem;
}

.BetaProgram-ledger {
  font-size: 0.85rem;
}
.BetaProgram-ledger .Button--secondary {
  padding: 0.15rem 0.6rem;
  font-size: 0.8rem;
}

.BetaProgram-manualGrant {
  margin-top: 1rem;
  font-size: 0.9rem;
}
.BetaProgram-manualGrant summary {
  cursor: pointer;
  color: #527070;
}

.BetaProgram-freeText {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9rem;
}
.BetaProgram-freeText li + li {
  margin-top: 0.35rem;
}

.BetaProgram-grantForm {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.9rem;
  margin-top: 0.75rem;
}

.ProvisionDemo__missingName {
  font-size: 0.9rem;
  background: rgb(248.64, 240.96, 224.88);
  border: 1px solid #e5c786;
  border-radius: 8px;
  padding: 0.75rem 0.9rem;
  color: #1f3d3d;
}

.ProvisionDemo__form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.9rem;
}

.ProvisionDemo__field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  flex: 1 1 200px;
}
.ProvisionDemo__field label {
  font-size: 0.8rem;
  color: #527070;
}

@media (max-width: 767px) {
  .LeadProfile-hero {
    flex-wrap: wrap;
    padding-right: 1.5rem;
    padding-top: 3.25rem;
  }
  .LeadProfile-dl {
    grid-template-columns: 1fr;
    gap: 0.1rem;
  }
  .LeadProfile-dl dd {
    margin-bottom: 0.5rem;
  }
}
/* app/assets/stylesheets/customer_orders.scss */
/* ============================================
   CUSTOMER ORDER PAGE
   Uses the existing design system from colors.scss, forms.scss, tables.scss
   ============================================ */
.CustomerOrderPage {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #faf7ee;
}

/* ============================================
   HEADER - Sticky Top Bar
   ============================================ */
.OrderHeader {
  position: sticky;
  top: 0;
  background: #fff;
  border-bottom: 2px solid #e3dccb;
  padding: 1rem;
  margin: 1rem 0;
  z-index: 100;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.OrderHeader.hidden {
  display: none;
}

#main-content.UserSignedIn .OrderHeader {
  top: 4rem;
}

.OrderDisclaimer {
  text-align: center;
  font-size: 1.05rem;
  font-style: italic;
  font-weight: 500;
  color: rgb(11.793814433, 59.706185567, 59.706185567);
  background: rgb(203.268556701, 244.781443299, 244.781443299);
  border: 1px solid rgb(134.2932989691, 231.1567010309, 231.1567010309);
  border-radius: 6px;
  padding: 0.75rem 2rem;
  max-width: 800px;
  margin: 0.75rem auto;
}
.OrderDisclaimer p {
  margin: 0;
}
.OrderDisclaimer p + p {
  margin-top: 0.5rem;
}

.OrderHeader__container {
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  gap: 1rem;
  align-items: center;
}

.Logo {
  flex-shrink: 0;
  max-width: 100px;
  height: auto;
}

.OrderHeader__filter {
  display: flex;
  align-items: center;
  flex-direction: column;
  gap: 0.5rem;
  flex-grow: 1;
}

.SeasonSelectPage__notice {
  font-size: 1.2rem;
}

.SeasonSelector {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.SeasonSelector label {
  font-weight: 600;
  color: #1f3d3d;
  margin: 0;
}
.SeasonSelector select {
  padding: 0.5rem 1rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  font-size: 0.95rem;
  background: #fff;
  color: #1f3d3d;
  cursor: pointer;
}
.SeasonSelector select:focus {
  border-color: #105151;
  box-shadow: 0 0 0 3px rgba(16, 81, 81, 0.22);
}

/* Search and the filter button travel together — side by side on one line at
   every width, so the phone header stays two short rows tall. */
.OrderHeader__controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-width: 0;
}

.OrderSearch {
  flex: 1;
  min-width: 0;
}
.OrderSearch input {
  width: 100%;
  margin-top: 0;
  font-size: 1rem;
  line-height: 1.5;
  /* font-size/line-height set explicitly: the UA default for <input>
     ignores inherited text sizing, which left it a few px shorter than
     the SeasonInfo badge next to it. Otherwise inherits from forms.scss. */
}

/* ============================================
   FILTER FLYOUT
   One panel for every filter but the search box.
   Hangs off the button on a desktop; slides up
   from the bottom edge on a phone (see RESPONSIVE).
   ============================================ */
.OrderFilterMenu {
  position: relative;
  flex-shrink: 0;
}

.FilterButton {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.9rem;
  min-height: 2.6rem;
  border: 1px solid #e3dccb;
  border-radius: 4px;
  background: #fff;
  color: #1f3d3d;
  font-size: 1rem;
  line-height: 1.5;
  cursor: pointer;
  white-space: nowrap;
}
.FilterButton:hover {
  border-color: #105151;
}
.FilterButton[aria-expanded=true] {
  border-color: #105151;
  box-shadow: 0 0 0 3px rgba(16, 81, 81, 0.22);
}

.FilterButton--active {
  border-color: #105151;
  color: #105151;
}

.FilterButton__icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

.FilterButton__count {
  min-width: 1.3rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: #105151;
  color: #ffffff;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.3rem;
  text-align: center;
}
.FilterButton__count[hidden] {
  display: none;
}

.FilterPanel {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 2;
  width: 20rem;
  max-width: calc(100vw - 2rem);
  max-height: min(70vh, 34rem);
  overflow-y: auto;
  padding: 1rem;
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  text-align: left;
}
.FilterPanel[hidden] {
  display: none;
}

/* The sheet needs a title and a way out on a phone; the desktop dropdown is
   dismissed by clicking away from it and says what it is by where it sits. */
.FilterPanel__header {
  display: none;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.75rem;
}

.FilterPanel__heading {
  font-size: 1.05rem;
  font-weight: 700;
  color: #1f3d3d;
}

.FilterPanel__close {
  border: 0;
  background: none;
  padding: 0 0.25rem;
  font-size: 1.6rem;
  line-height: 1;
  color: #527070;
  cursor: pointer;
}

.FilterPanel__group + .FilterPanel__group {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid #e3dccb;
}

.FilterPanel__title {
  display: block;
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #527070;
}

.FilterPanel__options {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.FilterPanel__option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.25rem; /* a comfortable tap target in the sheet */
  margin: 0;
  font-weight: normal;
  color: #1f3d3d;
  cursor: pointer;
  user-select: none;
}
.FilterPanel__option input[type=checkbox] {
  width: 1.1rem;
  height: 1.1rem;
  cursor: pointer;
  flex-shrink: 0;
}

.FilterPanel__swatch {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  flex-shrink: 0;
}

.FilterPanel__select {
  width: 100%;
  margin: 0;
}

.FilterPanel__price {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.FilterPanel__price input {
  flex: 1;
  min-width: 0;
  margin: 0;
}

.FilterPanel__prefix {
  color: #527070;
  font-weight: 600;
}

.FilterPanel__hint {
  margin: 0.35rem 0 0;
  font-size: 0.75rem;
  color: #527070;
}

.FilterPanel__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid #e3dccb;
}

.FilterPanel__clear {
  border: 0;
  background: none;
  padding: 0.4rem 0;
  color: rgb(15.2, 76.95, 76.95);
  font-size: 0.9rem;
  text-decoration: underline;
  cursor: pointer;
}

.FilterPanel__done {
  padding: 0.5rem 1.1rem;
  border: 1px solid #105151;
  border-radius: 4px;
  background: #105151;
  color: #ffffff;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
.FilterPanel__done:hover {
  background: rgb(18.7249484536, 94.7950515464, 94.7950515464);
}

/* Only ever seen behind the phone sheet — the desktop dropdown leaves the page
   reachable underneath it. */
.FilterBackdrop {
  display: none;
}

.EmptyState--noMatches {
  margin-top: 1rem;
}
.EmptyState--noMatches .FilterPanel__clear {
  font-size: 1rem;
}

/* ============================================
   MAIN CONTENT
   ============================================ */
.OrderForm {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.OrderTableSection {
  flex: 1;
  padding: 2rem 1rem;
  padding-bottom: 100px; /* Space for sticky footer */
}
.OrderTableSection.hidden {
  display: none;
}

.OrderTableSection__container {
  max-width: 1400px;
  margin: 0 auto;
}

.EmptyState {
  text-align: center;
  padding: 4rem 2rem;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.EmptyState p {
  color: #527070;
  font-size: 1.1rem;
}

/* ============================================
   STOCK TYPE SECTIONS
   ============================================ */
.OrderTableSection .StockTypeList {
  display: grid;
  gap: 1rem;
  background: none;
}

.StockTypeSection {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.StockTypeSection__header {
  background: var(--st-color-header, #0a5454);
  color: #ffffff;
  padding: 1rem 1.5rem;
  margin: 0;
  font-size: 1.3rem;
  font-weight: 600;
  position: relative;
  user-select: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.StockTypeSection__header:hover {
  filter: brightness(0.9);
}

.StockTypeSection__increment,
.StockTypeSection__pricing-note {
  font-size: 0.85rem;
  font-weight: normal;
  color: #ffffff;
  background-color: rgba(0, 0, 0, 0.22);
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  white-space: nowrap;
}

.StockTypeSection__order-note {
  flex-basis: 100%;
  font-size: 0.85rem;
  font-weight: normal;
  line-height: 1.4;
  color: #ffffff;
  background-color: rgba(0, 0, 0, 0.22);
  padding: 0.35rem 0.6rem;
  border-radius: 4px;
  white-space: pre-line;
}

.StockTypeSection__chevron {
  display: inline-block;
  transition: transform 0.2s ease;
  margin-right: 0.5rem;
  font-size: 0.8em;
}
.StockTypeSection__chevron.is-open {
  transform: rotate(0deg);
}
.StockTypeSection__chevron:not(.is-open) {
  transform: rotate(-90deg);
}

.StockTypeSection [data-expand-row-target=details][hidden] {
  display: none !important;
}

/* ============================================
   ORDER TABLE
   Extends table styles from tables.scss
   ============================================ */
.OrderTable {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0;
}
.OrderTable thead {
  background: #fffdf7;
  border-bottom: 2px solid #e3dccb;
}
.OrderTable thead th {
  padding: 0.75rem 1rem;
  text-align: left;
  font-weight: 600;
  color: #1f3d3d;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: #fffdf7; /* Override default table th background */
  border: none;
}
.OrderTable tbody {
  /* A size is two rows — its prices and its stock count — so hovering either
     lights both. The pair is always adjacent (see customer/sales/_species_row),
     which is what lets `+` reach forwards and `:has(+ …)` reach back. The
     species header row is excluded — it's not an orderable size, so it
     shouldn't highlight on hover. */
}
.OrderTable tbody tr {
  border-bottom: 1px solid #e3dccb;
  background: var(--st-color-row, transparent);
}
.OrderTable tbody tr.OrderRow--small {
  background: rgb(255, 253.06, 247.24);
}
.OrderTable tbody tr.OrderRow:not(.OrderRow--speciesHeader):hover,
.OrderTable tbody tr.OrderRow--size:hover + tr.OrderRow--stock,
.OrderTable tbody tr.OrderRow--size:has(+ tr.OrderRow--stock:hover) {
  background: #fffdf7;
}
.OrderTable tbody td {
  padding: 1rem;
  vertical-align: top;
  border: none; /* Override default table borders */
}

/* Column widths (price tier columns are auto-width) */
.OrderTable .col-info {
  width: 2rem;
}
.OrderTable .col-species {
  width: 25%;
}
.OrderTable .col-size {
  width: 8%;
}
.OrderTable .col-quantity {
  width: 15%;
  text-align: right;
}

/* Make price tier columns compact and centered */
.col-price-tier {
  min-width: 80px;
  font-weight: 600;
  color: var(--color-primary);
  white-space: nowrap;
}

/* Header styling for price tiers */
.OrderTable thead th.col-price-tier {
  font-size: 0.85rem;
  background: color-mix(in srgb, var(--color-primary) 10%, var(--color-bg-light));
}

/* ============================================
   SPECIES NAMES
   ============================================ */
.SpeciesName {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  /* The order form runs the names along one line — that table already gives a
     species its own rows for availability and prices. Wraps on narrow screens. */
}
.SpeciesName--indent {
  padding-left: 1.5rem;
  position: relative;
}
.SpeciesName--indent::before {
  content: "↳";
  position: absolute;
  left: 0.5rem;
  color: #527070;
}
.SpeciesName--inline {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.5rem;
  row-gap: 0.15rem;
  /* Sized against the cell, not the root, so the whole line scales together
     as the table compresses — the shared rem-based rules don't, which leaves
     the common name larger than the latin one on a tablet. The accession
     keeps the default weight: it identifies the plant, it isn't a subtitle. */
}
.SpeciesName--inline .SpeciesName__common,
.SpeciesName--inline .SpeciesName__accession {
  font-size: 0.9em;
}

/* When the species can be picked up. Sits at the end of the name line at every
   width — including a phone, if it fits — and drops onto its own line whole
   rather than breaking mid-window, which is what the nowrap buys. */
.SpeciesAvailability {
  font-size: 0.9em;
  color: #527070;
  font-style: italic;
  white-space: nowrap;
}

.SpeciesName__latin {
  font-weight: 600;
  font-style: italic;
  color: #1f3d3d;
}

.SpeciesName__common {
  font-size: 0.9rem;
  color: #527070;
}

/* Which size of the plant this line is — only rendered when the stock type
   has more than one, so single-size receipts read exactly as before. */
.SpeciesName__size {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #527070;
}

/* ============================================
   AVAILABILITY
   ============================================ */
.availability-count {
  font-weight: 600;
  font-style: normal;
  color: #1f3d3d;
}

.availability-limited {
  color: rgb(161.6, 110.4, 3.2);
  font-style: italic;
}

/* ============================================
   PRICING TIERS
   ============================================ */
.PricingTiers {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.PricingTier {
  display: flex;
  gap: 0.5rem;
  font-size: 0.9rem;
}

.PricingTier__range {
  color: #527070;
  min-width: 80px;
}

.PricingTier__price {
  font-weight: 600;
  color: #105151;
}

.no-pricing {
  color: #527070;
  font-style: italic;
}

/* ============================================
   QUANTITY INPUT
   ============================================ */
.QuantityInput {
  width: 100%;
  max-width: 120px;
  padding: 0.5rem;
  border: 2px solid #e3dccb;
  border-radius: 4px;
  font-size: 1rem;
  text-align: center;
  background: #fff;
}
.QuantityInput:focus {
  border-color: #105151;
  box-shadow: 0 0 0 3px rgba(16, 81, 81, 0.22);
}
.QuantityInput.input-adjusted {
  border-color: #ca8a04;
  animation: pulse 0.3s ease;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
}
/* ============================================
   QUANTITY ADJUSTMENT TOAST
   Pops out of the field that was rounded rather than off in a corner —
   quantity_input_controller.js fixes it to the field's edge and picks the
   direction, this only draws it and slides it clear.
   ============================================ */
.QuantityToast {
  position: fixed;
  z-index: 1000;
  max-width: min(20rem, 100vw - 1rem);
  padding: 0.55rem 0.85rem;
  background: rgb(151.5, 103.5, 3);
  color: white;
  border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.22);
  font-size: 0.85rem;
  line-height: 1.35;
  text-align: right;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.18s ease, transform 0.24s cubic-bezier(0.2, 0.8, 0.3, 1);
  /* The pointer back at the field, tucked under the body so only the tip shows */
  /* Both directions start tucked behind the field and slide out past its edge */
}
.QuantityToast strong {
  display: block;
  font-weight: 600;
}
.QuantityToast span {
  display: block;
  opacity: 0.85;
  font-size: 0.8rem;
}
.QuantityToast::after {
  content: "";
  position: absolute;
  left: var(--arrow-x, 50%);
  width: 0.6rem;
  height: 0.6rem;
  margin-left: -0.3rem;
  background: inherit;
  transform: rotate(45deg);
}
.QuantityToast.QuantityToast--below {
  transform: translateY(-0.6rem) scale(0.96);
}
.QuantityToast.QuantityToast--below::after {
  top: -0.2rem;
}
.QuantityToast.QuantityToast--below.is-shown {
  transform: translateY(0.45rem) scale(1);
}
.QuantityToast.QuantityToast--above {
  transform: translateY(0.6rem) scale(0.96);
}
.QuantityToast.QuantityToast--above::after {
  bottom: -0.2rem;
}
.QuantityToast.QuantityToast--above.is-shown {
  transform: translateY(-0.45rem) scale(1);
}
.QuantityToast.is-shown {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .QuantityToast,
  .QuantityToast.is-shown {
    transition: opacity 0.18s ease;
    transform: none;
  }
}
/* Every quantity cell spans its size's price row and the stock row below it, so
   the field sits centered against the pair — prices level with its top edge, the
   inventory count level with its bottom. */
.OrderTable tbody td.col-quantity[rowspan] {
  vertical-align: middle;
  padding: 0.5rem 1rem;
}
.OrderTable tbody td.col-quantity[rowspan] .QuantityInput {
  text-align: right;
  width: 100%;
  max-width: 140px;
  padding: 0.6rem 0.75rem;
  font-size: 1.05rem;
  min-height: 50px;
}

/* ============================================
   SPECIES BLOCKS
   Every species renders the same way whether it offers one size or several: a
   header row carrying the photo, the name stack and the pickup window, then a
   pair of rows per shop-visible size — its prices, then how much of it there
   is — with the quantity field spanning that pair.
   ============================================ */
/* The border lives on the row as well as the cell — under border-collapse a
   `none` on the td alone loses to the tr's solid, drawing a line between the
   header and the sizes it belongs to. */
.OrderTable tbody tr.OrderRow--speciesHeader {
  border-bottom: none;
}
.OrderTable tbody tr.OrderRow--speciesHeader td {
  padding-bottom: 0.15rem;
  border-bottom: none;
}

/* Gutter holding the species info button. It keeps its width when a species has
   no preview to show, so every name in the table starts at the same x. */
.OrderTable thead th.col-info,
.OrderTable tbody td.col-info {
  padding-left: 0.75rem;
  padding-right: 0;
  text-align: center;
  vertical-align: top;
}

/* Block-level rather than inline: an inline button is positioned against the
   cell's own baseline strut, which doesn't track the name cell's font size, so
   the icon drifted off the name as the table shrank. As a block it starts at
   the top of the cell's content box — exactly where the name's first line
   starts — and being one line tall (see .SpeciesInfoBtn-trigger) it centers on
   that line at every width. */
.OrderTable tbody td.col-info .SpeciesInfoBtn {
  display: flex;
  justify-content: center;
  margin-right: 0; /* the column is the spacing now */
}

/* The priced row opens a size and the stock row closes it, so the two sit tight
   against each other and the separators all live on the stock row. */
.OrderTable tbody tr.OrderRow--size {
  border-bottom: none;
}
.OrderTable tbody tr.OrderRow--size td {
  padding-top: 0.2rem;
  padding-bottom: 0.1rem;
}

.OrderTable tbody tr.OrderRow--stock {
  /* Between one size and the next of the same species — lighter than the rule
     that separates species. */
  border-bottom: 1px dotted #e3dccb;
}
.OrderTable tbody tr.OrderRow--stock td {
  padding-top: 0;
  padding-bottom: 0.4rem;
}

/* A block ends on its last stock row, so that row carries the separator
   between species. */
.OrderTable tbody tr.OrderRow--stock:last-child,
.OrderTable tbody tr.OrderRow--stock:has(+ tr.OrderRow--speciesHeader) {
  border-bottom: 1px solid #e3dccb;
}
.OrderTable tbody tr.OrderRow--stock:last-child td,
.OrderTable tbody tr.OrderRow--stock:has(+ tr.OrderRow--speciesHeader) td {
  padding-bottom: 0.75rem;
}

.OrderTable td.col-species--size,
.OrderTable td.col-stock {
  padding-left: 1.25rem;
}

.SizeName {
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #527070;
}

/* How much of this size there is, replacing the old Available column: it reads
   under the size's own prices instead of off to the side. */
.OrderTable tbody td.col-stock {
  font-size: 0.85rem;
  color: #527070;
  font-style: italic;
  white-space: nowrap;
}

/* ============================================
   SHARED CUSTOMER SHOP PATTERNS
   Used across the form, review, and confirmation pages.
   ============================================ */
.CustomerShop {
  background: #faf7ee;
  padding: 2rem 1rem;
}

.CustomerShopCard {
  margin: 0 auto;
  background: #fff;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* ============================================
   CUSTOMER FORM SECTION
   ============================================ */
.CustomerFormSection.hidden {
  display: none;
}

.CustomerFormSection__wrapper {
  max-width: 600px;
  margin: 0 auto;
}

.CustomerFormSection__container {
  max-width: 600px;
}
.CustomerFormSection__container h2 {
  margin-top: 0;
  color: #1f3d3d;
}

.CustomerFormSection__subtitle {
  color: #527070;
  margin-bottom: 2rem;
}

.CustomerFormSection__legend {
  display: block;
  font-size: 0.85rem;
  margin-top: 0.25rem;
}

.CustomerFormSection__mark {
  color: rgb(177, 75.5, 69.5);
}

.BackButton {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 2rem;
}

.CustomerFields {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.Field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  /* Input styles inherited from forms.scss */
}
.Field label {
  font-weight: 600;
  color: #1f3d3d;
  display: block;
  margin: 0;
}
.Field--required label::after {
  content: " *";
  color: rgb(177, 75.5, 69.5);
}

.FieldHint {
  font-size: 0.85rem;
  color: #527070;
  font-style: italic;
}

.SubmitButton {
  padding: 1rem 2rem;
  font-size: 1.1rem;
  font-weight: 600;
}

.RecaptchaDisclosure {
  font-size: 0.75rem;
  color: #527070;
  margin-top: 0.5rem;
}
.RecaptchaDisclosure a {
  color: inherit;
  text-decoration: underline;
}

.grecaptcha-badge {
  visibility: hidden !important;
}

/* ============================================
   FOOTER - Sticky Bottom Bar
   ============================================ */
.OrderFooter {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  border-top: 2px solid #e3dccb;
  padding: 0.5rem 1rem;
  z-index: 100;
  box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
}
.OrderFooter.hidden {
  display: none;
}

.OrderFooter__container {
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.OrderSummary {
  display: flex;
  justify-content: right;
  align-items: center;
  gap: 1rem;
  flex: 1;
  min-width: 0;
}

.OrderSummary__quantities {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: nowrap;
  font-size: 1.1rem;
  color: #1f3d3d;
}

.QuantitySummary__label {
  font-weight: 600;
  white-space: nowrap;
  margin-right: 0.1rem;
}

.QuantitySummary__item {
  white-space: nowrap;
  font-weight: 600;
}

.QuantitySummary__dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 0.25rem;
  vertical-align: middle;
  border: 1px solid rgba(0, 0, 0, 0.15);
}

.QuantitySummary__empty {
  color: #527070;
  font-style: italic;
}

.OrderSummary__total {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.2rem;
  font-weight: 600;
  white-space: nowrap;
}

.OrderSummary__label {
  color: #1f3d3d;
}

.OrderSummary__amount {
  color: #105151;
}

.CheckoutButton {
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  font-weight: 600;
  white-space: nowrap;
}

/* ============================================
   CONFIRMATION PAGE
   ============================================ */
.OrderConfirmation {
  min-height: 100vh;
  padding-top: 3rem;
}

.OrderConfirmation__container {
  max-width: 800px;
  padding: 3rem;
}

.OrderConfirmation__icon {
  text-align: center;
  color: #105151;
  margin-bottom: 2rem;
}
.OrderConfirmation__icon svg {
  display: inline-block;
}

.OrderConfirmation__title {
  text-align: center;
  color: #1f3d3d;
  margin-bottom: 2rem;
}

.OrderConfirmation__details {
  text-align: center;
  margin-bottom: 3rem;
}
.OrderConfirmation__details p {
  margin: 1rem 0;
  line-height: 1.6;
}

.OrderConfirmation__number {
  font-size: 1.2rem;
}
.OrderConfirmation__number strong {
  color: #105151;
}

.OrderConfirmation__message {
  font-size: 1.1rem;
  color: #1f3d3d;
}

.OrderConfirmation__notice {
  background: rgb(252.6388349515, 214.8601941748, 135.7611650485);
  border: 1px solid #ca8a04;
  border-radius: 4px;
  padding: 1rem;
  margin: 1.5rem 0;
}
.OrderConfirmation__notice p {
  margin: 0;
  color: rgb(141.4, 96.6, 2.8);
}

.OrderConfirmation__deposit {
  color: #527070;
  font-style: italic;
}

.OrderConfirmation__summary {
  border-top: 2px solid #e3dccb;
  padding-top: 2rem;
}
.OrderConfirmation__summary h2, .OrderConfirmation__summary h3 {
  color: #1f3d3d;
  margin-bottom: 1rem;
}
.OrderConfirmation__summary h3 {
  font-size: 1.2rem;
  margin-top: 2rem;
}

.OrderSummary__contact,
.OrderSummary__notes {
  overflow-wrap: anywhere;
  margin-bottom: 2rem;
}
.OrderSummary__contact p,
.OrderSummary__notes p {
  margin: 0.5rem 0;
  line-height: 1.6;
}

.OrderSummary__items {
  margin-top: 2rem;
}

.ConfirmationTable {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
}
.ConfirmationTable thead {
  background: #fffdf7;
  border-bottom: 2px solid #e3dccb;
}
.ConfirmationTable thead th {
  padding: 0.75rem;
  text-align: left;
  font-weight: 600;
  color: #1f3d3d;
  border: none;
}
.ConfirmationTable thead th.num {
  text-align: right;
}
.ConfirmationTable tbody tr {
  border-bottom: 1px solid #e3dccb;
}
.ConfirmationTable tbody td {
  padding: 0.75rem;
  border: none;
}
.ConfirmationTable tbody td.num {
  text-align: right;
}
.ConfirmationTable tbody td small {
  color: #527070;
  font-style: italic;
}

.OrderConfirmation__actions {
  text-align: center;
  margin-top: 3rem;
}

/* Button classes are defined in forms.scss, we just use them */
/* ============================================
   UTILITY
   ============================================ */
.hidden {
  display: none !important;
}

/* ============================================
   SEASON SELECT PAGE
   ============================================ */
.SeasonSelectPage {
  min-height: 100vh;
  background: #faf7ee;
  padding: 3rem 1rem;
}

.SeasonSelectPage__container {
  max-width: 600px;
  margin: 0 auto;
}

.SeasonSelectPage__logo {
  text-align: center;
  margin-bottom: 2rem;
}

.SeasonSelectPage__header {
  text-align: center;
  margin-bottom: 2rem;
}
.SeasonSelectPage__header h1 {
  margin-bottom: 1rem;
  color: #1f3d3d;
}

.SeasonExplainer {
  background: #fffdf7;
  border-left: 4px solid #105151;
  padding: 1.5rem;
  margin: 2rem 0;
  border-radius: 4px;
  text-align: left;
}
.SeasonExplainer p {
  margin-bottom: 1rem;
  font-size: 1.05em;
  line-height: 1.6;
  color: #1f3d3d;
}
.SeasonExplainer p:last-child {
  margin-bottom: 0;
}
.SeasonExplainer strong {
  color: #1f3d3d;
}

.SeasonOptions {
  display: flex;
  gap: 1.5rem;
  flex-direction: column;
}

.SeasonCard {
  display: block;
  padding: 2rem;
  border: 2px solid #e3dccb;
  border-radius: 8px;
  text-decoration: none;
  background: #fff;
  transition: all 0.2s ease;
}
.SeasonCard:hover {
  border-color: #105151;
  box-shadow: 0 4px 12px rgba(16, 81, 81, 0.15);
  transform: translateY(-2px);
}

.SeasonCard__content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.SeasonCard__info {
  flex: 1;
}

.SeasonCard__title {
  margin: 0 0 0.5rem 0;
  color: #105151;
  font-size: 1.5rem;
}

.SeasonCard__dates {
  margin: 0;
  color: #527070;
  font-size: 0.95em;
}

.SeasonCard__arrow {
  font-size: 1.5rem;
  color: #105151;
}

/* ============================================
   SEASON INFO COMPONENT (in header)
   ============================================ */
.SeasonInfo {
  padding: 0.5rem 1rem;
  background: #fffdf7;
  border-radius: 4px;
  border: 1px solid #e3dccb;
  cursor: default;
}

.SeasonInfo__link {
  text-decoration: none;
  color: #105151;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  transition: color 0.2s ease;
}
.SeasonInfo__link:hover {
  color: rgb(13.6, 68.85, 68.85);
}

.SeasonInfo__arrow {
  display: inline-block;
}

.SeasonInfo__text {
  display: inline-block;
}

/* ============================================
   REVIEW PAGE - STOCK TYPE SECTIONS
   ============================================ */
.ReviewStockTypeSection {
  margin-bottom: 1.5rem;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.ReviewStockTypeSection__header {
  padding: 0.6rem 1rem;
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: #1f3d3d;
  background: #fffdf7;
  border-bottom: 1px solid #e3dccb;
}

.ReviewGrandTotal {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
  font-size: 1.2rem;
  font-weight: 600;
  border-top: 2px solid #e3dccb;
  margin-top: 0.5rem;
}

.ReviewGrandTotal__label {
  color: #1f3d3d;
}

.ReviewGrandTotal__amount {
  color: #105151;
  font-size: 1.3rem;
  font-weight: bold;
}

.ReviewGrandTotal__hint {
  text-align: right;
  margin: -0.5rem 0 0.5rem;
  padding: 0 1rem;
  font-size: 0.9rem;
  color: #527070;
}

.OrderConfirmationDisclaimer {
  text-align: right;
  padding: 0 1rem;
  font-size: 1.2rem;
  color: #527070;
}

/* ============================================
   ORDER REVIEW PAGE
   ============================================ */
.OrderReviewPage {
  min-height: 100vh;
}

.OrderReviewPage__container {
  max-width: 900px;
  margin: 0 auto;
}

.OrderReviewPage__title {
  margin-bottom: 2rem;
  color: #1f3d3d;
}

.OrderDetails,
.OrderItemsList,
.ContactInfo {
  background: #fff;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  margin-bottom: 2rem;
}

.OrderDetails__heading,
.OrderItemsList__heading,
.ContactInfo__heading {
  margin-top: 0;
  margin-bottom: 1.5rem;
  font-size: 1.5rem;
  color: #1f3d3d;
}

.OrderDetails__item,
.ContactInfo__item {
  margin-bottom: 1.5rem;
  line-height: 1.6;
}
.OrderDetails__item:last-child,
.ContactInfo__item:last-child {
  margin-bottom: 0;
}
.OrderDetails__item strong,
.ContactInfo__item strong {
  color: #1f3d3d;
}

.OrderDetails__subtext {
  color: #527070;
  margin-left: 0.5rem;
}

.OrderDetails__notes {
  overflow-wrap: anywhere;
  margin-top: 0.5rem;
  padding: 1rem;
  background: #fffdf7;
  border-radius: 4px;
  border: 1px solid #e3dccb;
}

.ReviewTable {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0;
}
.ReviewTable thead {
  background: #fffdf7;
  border-bottom: 2px solid #e3dccb;
}
.ReviewTable thead th {
  padding: 0.75rem;
  text-align: left;
  font-weight: 600;
  color: #1f3d3d;
  background-color: unset;
  border: none;
}
.ReviewTable thead th.num {
  text-align: right;
}
.ReviewTable tbody tr {
  border-bottom: 1px solid #e3dccb;
}
.ReviewTable tbody tr:hover {
  background: #fffdf7;
}
.ReviewTable tbody td {
  padding: 0.75rem;
  border: none;
}
.ReviewTable tbody td.num {
  text-align: right;
}
.ReviewTable tfoot {
  border-top: 2px solid #e3dccb;
  background: #fffdf7;
}
.ReviewTable tfoot tr td {
  padding: 1rem 0.75rem;
}

.OrderTotal__label {
  text-align: right;
}

.OrderTotal__amount {
  text-align: right;
  color: #105151;
}

.ConfirmForm {
  text-align: center;
  margin-top: 2rem;
}

.ConfirmButton {
  background: #105151;
  color: white;
  border: none;
  padding: 1rem 3rem;
  font-size: 1.1rem;
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.2s ease;
}

/* ============================================
   CONFIRMATION PAGE ENHANCEMENTS
   ============================================ */
.OrderConfirmation__wantedAt {
  font-size: 1.05rem;
  color: #1f3d3d;
}

.ConfirmationTable tfoot {
  border-top: 2px solid #e3dccb;
  background: #fffdf7;
}
.ConfirmationTable tfoot tr td {
  padding: 1rem 0.75rem;
}

/* ============================================
   RESPONSIVE
   All media queries gathered here so they
   cascade after every base rule above.
   ============================================ */
@media (max-width: 1024px) {
  .OrderTableSection__container, .StockTypeSection {
    overflow-x: auto;
  }
}
@media (min-width: 769px) {
  .OrderHeader__filter {
    flex-direction: row;
    align-items: left;
    justify-content: flex-end;
    gap: 1rem;
  }
}
@media (max-width: 768px) {
  .OrderTableSection {
    padding: 2rem 0;
  }
  .OrderTable .col-info {
    width: 1.5rem;
  }
  .OrderTable thead th.col-info,
  .OrderTable tbody td.col-info {
    padding-left: 0.3rem;
  }
  .OrderHeader__container {
    align-items: center;
    gap: 0.25rem;
  }
  .OrderFooter__container {
    flex-wrap: wrap;
    gap: 0.25rem;
  }
  .OrderHeader__filter {
    align-items: normal;
  }
  .OrderHeader__filter .SeasonSelector label {
    display: none;
  }
  /* Same panel, re-anchored: a sheet on the bottom edge, where a thumb is,
     instead of a dropdown hanging off a button at the top of the screen. */
  /* The word goes, the funnel stays: it buys the search box a good 60px, which
     is the difference between reading a species name in the field and not.
     Hidden rather than removed so the button keeps its name for a screen
     reader — a bare icon and a count would announce as "1". */
  .FilterButton__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .FilterButton {
    gap: 0.3rem;
    padding: 0.5rem 0.6rem;
    font-size: 0.9rem;
  }
  .FilterPanel {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    max-width: none;
    max-height: 85vh;
    border-radius: 12px 12px 0 0;
    border-bottom: 0;
    padding-bottom: calc(1rem + env(safe-area-inset-bottom));
    box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.25);
  }
  /* The sheet is taller than it is scrollable in one thumb-swipe, so its way
     out rides along at the top instead of sitting at the end of the list.
     top cancels the negative margin rather than being 0: sticky parks the
     MARGIN box at the offset, so top: 0 would hold the bar a whole 1rem down
     the sheet and let the list scroll through the gap above it. The two must
     move together. */
  .FilterPanel__header {
    display: flex;
    position: sticky;
    top: -1rem;
    z-index: 1;
    margin: -1rem -1rem 0.5rem;
    padding: 0.75rem 1rem;
    background: #fff;
    border-bottom: 1px solid #e3dccb;
  }
  .FilterBackdrop:not([hidden]) {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 1;
    background: rgba(0, 0, 0, 0.4);
  }
  /* The header owns the sheet's stacking context, and it is pinned at the same
     z-index as the totals bar — which, coming later in the document, would
     otherwise paint straight through the sheet sitting over it. */
  body.is-filterSheetOpen {
    overflow: hidden;
  }
  body.is-filterSheetOpen .OrderHeader {
    z-index: 300;
  }
  .OrderSummary {
    flex-basis: 100%;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.25rem;
  }
  .OrderSummary__quantities {
    flex-basis: 100%;
    flex-wrap: wrap;
    justify-content: left;
  }
  .OrderSummary__total {
    font-size: 1rem;
  }
  .CheckoutButton {
    padding: 0.5rem 1rem;
    font-size: 0.9rem;
  }
  .OrderTable {
    min-width: 0px;
    font-size: 0.85rem;
  }
  .OrderTable thead th, .OrderTable tbody td {
    padding: 0.25rem;
    font-size: 0.8rem;
    min-width: 30px;
  }
  .col-species {
    width: auto;
  }
  .OrderTable tbody td.col-quantity[rowspan] {
    padding: 0.25rem;
  }
  .OrderTable tbody td.col-quantity[rowspan] .QuantityInput {
    padding: 0.25rem;
    font-size: 0.8rem;
    min-height: 36px;
  }
  /* The name line is the block's heading — on a phone the whole table drops to
     0.8rem, which flattens it into the prices and stock under it. Sizing the
     cell (not the spans) keeps the common name and pickup window scaling off
     the latin name as one unit. */
  .OrderTable tbody tr.OrderRow--speciesHeader td.col-species {
    font-size: 0.95rem;
  }
  .OrderTable tbody tr.OrderRow--speciesHeader td.col-species .SpeciesAvailability {
    font-size: 0.8em;
  }
  /* The gutter is sized off the names it stands next to, not off the table: the
     info button's box is one text line tall in em, so it only lands centered on
     the name when both cells carry the same font-size. The `tbody td` rule
     above would otherwise drop this cell to 0.8rem on its own. */
  .OrderTable tbody tr.OrderRow--speciesHeader td.col-info {
    font-size: 0.95rem;
  }
  /* Size rows stay tappable on a phone even as the rest of the table shrinks. */
  .OrderTable td.col-species--size,
  .OrderTable td.col-stock {
    padding-left: 0.5rem;
  }
  .SizeName {
    font-size: 0.7rem;
  }
  /* Subordinate to the heading above it, not competing with it. */
  .OrderTable tbody td.col-stock {
    font-size: 0.65rem;
  }
  .QuantityToast {
    font-size: 0.8rem;
    padding: 0.45rem 0.7rem;
  }
  .QuantityToast span {
    font-size: 0.75rem;
  }
  .ReviewTable {
    font-size: 0.85rem;
  }
  .ReviewTable thead th,
  .ReviewTable tbody td,
  .ReviewTable tfoot td {
    padding: 0 0.5rem;
  }
  .OrderTotal,
  .ReviewGrandTotal {
    font-size: 1rem;
  }
  .OrderTotal .OrderTotal__amount,
  .OrderTotal .ReviewGrandTotal__amount,
  .ReviewGrandTotal .OrderTotal__amount,
  .ReviewGrandTotal .ReviewGrandTotal__amount {
    font-size: 1.1rem;
  }
}
@media (max-width: 480px) {
  .OrderTable thead th.col-info,
  .OrderTable tbody td.col-info {
    padding-left: 0.2rem;
  }
  .CustomerShop {
    padding: 0.75rem 0;
  }
  .CustomerShopCard,
  .OrderDetails,
  .OrderItemsList,
  .ContactInfo {
    padding: 0.75rem;
    border-radius: 0;
    margin-bottom: 0.75rem;
  }
  .OrderReviewPage__title {
    margin-bottom: 1rem;
    font-size: 1.3rem;
    padding: 0 0.75rem;
  }
  .BackButton {
    margin-bottom: 1rem;
    margin-left: 0.75rem;
  }
  .ReviewStockTypeSection {
    border-radius: 0;
  }
  .ReviewTable {
    font-size: 0.5rem;
  }
  .ReviewTable thead th,
  .ReviewTable tbody td,
  .ReviewTable tfoot td {
    padding: 0.2rem 0.25rem;
  }
  .OrderTotal,
  .ReviewGrandTotal {
    font-size: 0.85rem;
    padding: 0.5rem 0.75rem;
  }
  .OrderTotal .OrderTotal__amount,
  .OrderTotal .ReviewGrandTotal__amount,
  .ReviewGrandTotal .OrderTotal__amount,
  .ReviewGrandTotal .ReviewGrandTotal__amount {
    font-size: 0.95rem;
  }
  .ConfirmForm {
    padding: 0 0.75rem;
  }
}
@media (max-width: 464px) {
  .OrderTable thead th,
  .OrderTable tbody td {
    padding: 0.2rem;
  }
  .OrderTable thead th.col-price-tier {
    padding: 0.1rem;
  }
  .OrderForm thead th,
  .OrderForm tbody td,
  .OrderForm .OrderTable thead th.col-price-tier,
  .OrderForm .QuantityInput,
  .ReviewTable thead th,
  .ReviewTable tbody td,
  .ReviewTable .OrderTable thead th.col-price-tier,
  .ReviewTable .QuantityInput {
    font-size: 0.5rem;
  }
  /* The rest of the table compresses to fit its columns; the heading spans the
     full width, so it holds a readable size and carries the hierarchy on its
     own. The common name is left off the list above so it keeps scaling off
     this rather than collapsing to the body size. */
  .OrderTable tbody tr.OrderRow--speciesHeader td.col-species,
  .OrderTable tbody tr.OrderRow--speciesHeader td.col-info {
    font-size: 0.85rem;
  }
  .OrderTable tbody td.col-stock {
    font-size: 0.6rem;
  }
}
.SpeciesInfoBtn {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  margin-right: 0.35rem;
}

.SpeciesInfoBtn-trigger {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 0;
  border: 0;
  background: transparent;
  font-family: inherit;
  line-height: 1;
  vertical-align: middle;
  cursor: pointer;
  font-size: 1em;
  height: 1.5em;
  width: 1.5em;
  border-radius: 50%;
  color: var(--color-primary);
  transition: color 0.12s ease, background-color 0.12s ease;
}
.SpeciesInfoBtn-trigger::after {
  content: "";
  position: absolute;
  inset: -0.4rem;
}
.SpeciesInfoBtn-trigger:hover, .SpeciesInfoBtn-trigger:focus-visible {
  color: var(--color-primary-bright);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
}
.SpeciesInfoBtn-trigger:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.SpeciesInfoBtn-icon {
  display: block;
  width: 1.15em;
  height: 1.15em;
}

.SpeciesInfoDialog {
  border-radius: 8px;
  max-width: min(95vw, 34rem);
}
.SpeciesInfoDialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

.SpeciesInfoDialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid #e3dccb;
  flex-shrink: 0;
  gap: 0.5rem;
}

.SpeciesInfoDialog-title {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.SpeciesInfoDialog-common {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}

.SpeciesInfoDialog-latin {
  margin: 0;
  font-size: 0.8rem;
  color: #527070;
}

.SpeciesInfoDialog-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: #527070;
  padding: 0 0.4rem 0.25rem;
  flex-shrink: 0;
}
.SpeciesInfoDialog-close:hover {
  color: #1f3d3d;
}

.SpeciesInfoDialog-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overflow-wrap: break-word;
}

.SpeciesInfoDialog-gallery {
  background: #111;
}

.SpeciesInfoDialog-imageWrap {
  position: relative;
}

.SpeciesInfoDialog-image {
  width: 100%;
  max-height: 50vh;
  object-fit: contain;
  display: block;
}

.SpeciesInfoDialog-loading {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.4);
}
.SpeciesInfoDialog-loading.is-loading {
  display: flex;
}
.SpeciesInfoDialog-loading::after {
  content: "";
  width: 2rem;
  height: 2rem;
  border: 3px solid rgba(255, 255, 255, 0.25);
  border-top-color: #fff;
  border-radius: 50%;
  animation: sid-spin 0.7s linear infinite;
}

@keyframes sid-spin {
  to {
    transform: rotate(360deg);
  }
}
.SpeciesInfoDialog-thumbs {
  display: flex;
  gap: 0.35rem;
  padding: 0.5rem 0.6rem;
  background: #1a1a1a;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.SpeciesInfoDialog-thumb {
  appearance: none;
  -webkit-appearance: none;
  flex-shrink: 0;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 3px;
  background: transparent;
  cursor: pointer;
  overflow: hidden;
  line-height: 0;
  transition: border-color 0.15s;
}
.SpeciesInfoDialog-thumb img {
  width: 3rem;
  height: 3rem;
  object-fit: cover;
  display: block;
  opacity: 0.55;
  transition: opacity 0.15s;
}
.SpeciesInfoDialog-thumb:hover img {
  opacity: 0.85;
}
.SpeciesInfoDialog-thumb.is-active {
  border-color: #fff;
}
.SpeciesInfoDialog-thumb.is-active img {
  opacity: 1;
}

.SpeciesInfoDialog-caption {
  padding: 0.5rem 0.75rem;
  margin: 0;
  font-size: 0.8rem;
  color: #bbb;
  min-height: 1.6rem;
}

.SpeciesInfoDialog-text {
  overflow-wrap: anywhere;
  padding: 0.85rem 1.25rem 1.25rem;
}

.SpeciesInfoDialog-description,
.SpeciesInfoDialog-salesNotes {
  font-size: 0.9rem;
  line-height: 1.5;
  color: #1f3d3d;
}
.SpeciesInfoDialog-description p,
.SpeciesInfoDialog-salesNotes p {
  margin: 0 0 0.5em;
}

.SpeciesInfoDialog-salesNotes {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid #e3dccb;
}

/* app/assets/stylesheets/customer_layout.scss */
/* ============================================
   CUSTOMER LAYOUT FOOTER
   ============================================ */
.CustomerFooter {
  text-align: center;
  padding: 1.5rem 1rem calc(max(2rem, env(safe-area-inset-bottom)) + var(--order-footer-height, 0px));
  color: #527070;
  font-size: 0.8rem;
}

.CustomerFooter__links {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.CustomerFooter__links a {
  color: #527070;
  text-decoration: none;
}
.CustomerFooter__links a:hover {
  text-decoration: underline;
}

.CustomerFooter__sep {
  color: #527070;
  opacity: 0.5;
}

.CustomerFooter__brand {
  margin-top: 0.75rem;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: 0.5rem 0.9rem 0.15rem;
  color: inherit;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: 10px;
  transition: border-color 0.15s ease;
}
.CustomerFooter__brand:hover, .CustomerFooter__brand:focus-visible {
  border-color: #0d6969;
  text-decoration: none;
}

.CustomerFooter__poweredBy {
  font-weight: 600;
  letter-spacing: 0.03em;
  color: #527070;
}

.CustomerFooter__logomark {
  display: block;
  width: 5rem;
  height: auto;
  margin-top: -8px;
}

/* ============================================
   CUSTOMER CONTACT BANNER
   ============================================ */
.CustomerContactBanner {
  text-align: center;
  font-style: italic;
  font-size: 0.95rem;
  color: #527070;
  padding: 0.4rem 1rem;
}
.CustomerContactBanner a {
  color: #527070;
}
.CustomerContactBanner a:hover {
  text-decoration: underline;
}

/* ============================================
   CUSTOMER HEADER (replaces Navbar on customer/session pages)
   ============================================ */
#CustomerHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 1rem;
  font-size: 1.1rem;
}

.CustomerHeader__left {
  flex: 1;
}

.CustomerHeader__center {
  flex: 2;
  text-align: center;
}

.CustomerHeader__right {
  flex: 1;
  text-align: right;
  white-space: nowrap;
}

/* Large devices (desktops) */
@media (min-width: 992px) {
  #CustomerHeader {
    padding: 0.5rem 4rem;
  }
}
/* app/assets/stylesheets/public_layout.scss */
/* ============================================
   PUBLIC LAYOUT SHELL

   The untenanted surface (welcome.cropcache.com): a logo, one short panel,
   a footer. No nav, no docks, no tenant chrome.

   Sticky footer — the pages here are a few lines long, so without this the
   copyright floats in the middle of an empty viewport.
   ============================================ */
.PublicBody {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: 0;
}

/* ============================================
   PUBLIC LAYOUT HEADER
   ============================================ */
.PublicHeader {
  display: flex;
  justify-content: center;
  padding: 2rem 1rem 1rem;
}

.PublicHeader__brand {
  display: inline-block;
  line-height: 0;
}
.PublicHeader__brand:hover {
  text-decoration: none;
}

.PublicHeader__logo {
  display: block;
  width: 100%;
  max-width: 240px;
  max-height: 160px;
  height: auto;
  object-fit: contain;
}

/* ============================================
   PUBLIC MAIN

   The <main> carries id="main-content", which otherwise inherits the ADMIN
   layout rules in application.scss (dock-aware max-width, `margin: 4rem` at
   >=992px). Those assume a signed-in tenant shell and shove this content off
   to the left. The id selector outranks a bare class, so the override has to
   be id-qualified.
   ============================================ */
#main-content.PublicMain {
  flex: 1;
  width: 100%;
  max-width: 34rem;
  margin: 0 auto;
  padding: 0 1.25rem;
  transition: none;
}

/* ============================================
   PUBLIC PANEL

   The content block on every public page (thanks, error).
   ============================================ */
.PublicPanel {
  background: #fff;
  border: 1px solid #e3dccb;
  border-radius: 12px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  padding: 2rem 1.75rem;
  text-align: center;
}
.PublicPanel .Button {
  display: inline-block;
  margin-top: 0.5rem;
}

.PublicPanel__heading {
  margin-bottom: 0.75rem;
  font-size: 1.5rem;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.PublicPanel__lead {
  margin-bottom: 1.25rem;
  color: #1f3d3d;
}
.PublicPanel__lead a {
  overflow-wrap: anywhere;
  text-decoration: underline;
}

.PublicPanel__errors {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0.75rem 1rem;
  text-align: left;
  background: rgb(240.3, 202.15, 195.85);
  border: 1px solid rgb(177, 75.5, 69.5);
  border-radius: 8px;
  color: #5d091f;
}
.PublicPanel__errors li + li {
  margin-top: 0.35rem;
}

/* ============================================
   PUBLIC SURVEY

   The tokenized pre-account survey. The base panel centers its short thanks
   pages; a form full of questions reads better left-aligned.
   ============================================ */
.PublicPanel--survey {
  text-align: left;
}
.PublicPanel--survey .PublicPanel__heading,
.PublicPanel--survey .PublicPanel__lead {
  text-align: center;
}

.SurveyBanner {
  margin-bottom: 1.25rem;
  padding: 0.75rem 1rem;
  background: rgb(227.76, 238.08, 231.48);
  border: 1px solid #1c723b;
  border-radius: 8px;
}
.SurveyBanner strong {
  display: block;
  margin-bottom: 0.25rem;
}

.SurveyQuestions {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
}

.SurveyQuestion {
  padding: 1.25rem 0;
  border-top: 1px solid #e3dccb;
}
.SurveyQuestion--missing {
  border-left: 3px solid rgb(177, 75.5, 69.5);
  padding-left: 0.85rem;
  margin-left: -1rem;
}

.SurveyQuestion__prompt {
  margin: 0 0 0.35rem;
  font-weight: 600;
}

.SurveyQuestion__optional {
  font-weight: 400;
  color: #527070;
  font-size: 0.85em;
}

.SurveyQuestion__hint {
  margin: 0 0 0.5rem;
  color: #527070;
  font-size: 0.9rem;
}

.SurveyQuestion__missingNote {
  margin: 0 0 0.5rem;
  color: #5d091f;
  font-size: 0.9rem;
}

.SurveyQuestion__options {
  list-style: none;
  margin: 0;
  padding: 0;
}

.SurveyQuestion__option label {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.3rem 0;
  cursor: pointer;
}
.SurveyQuestion__option input[type=radio],
.SurveyQuestion__option input[type=checkbox] {
  flex-shrink: 0;
}

.SurveyQuestion__input,
.SurveyQuestion__textarea {
  width: 100%;
}

.SurveyQuestion__input--detail {
  margin: 0.25rem 0 0.25rem 1.6rem;
  width: calc(100% - 1.6rem);
}

.SurveyFooter {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  margin-top: 1.5rem;
}

/* ============================================
   PUBLIC FOOTER
   ============================================ */
.PublicFooter {
  padding: 2rem 1.25rem max(1.5rem, env(safe-area-inset-bottom));
  text-align: center;
  color: #527070;
  font-size: 0.8rem;
}

.PublicFooter__links {
  margin: 0.4rem 0 0;
}

.PublicFooter__link {
  color: inherit;
  text-decoration: underline;
}

/* Small devices (phones) */
@media (max-width: 767px) {
  .PublicHeader {
    padding: 1.5rem 1rem 0.75rem;
  }
  .PublicHeader__logo {
    max-width: 180px;
    max-height: 120px;
  }
  .PublicPanel {
    padding: 1.5rem 1.25rem;
  }
  .PublicPanel__heading {
    font-size: 1.3rem;
  }
}
/* Short/landscape viewports — reclaim the vertical space the logo eats */
@media (max-height: 480px) {
  .PublicHeader {
    padding: 1rem 1rem 0.5rem;
  }
  .PublicHeader__logo {
    max-width: 150px;
    max-height: 90px;
  }
}
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-body);
  background-color: #faf7ee;
  color: #1f3d3d;
  padding: 1rem;
  line-height: 1.5;
  overflow-wrap: break-word;
}

.LatinName {
  font-style: italic;
}

img, svg, video, canvas, iframe {
  max-width: 100%;
}

input, select, textarea {
  max-width: 100%;
}

.table-responsive {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.CallLink {
  text-decoration: none;
  margin-left: 0.25rem;
}

@media (max-width: 767px) {
  .HideOnMobile {
    display: none !important;
  }
  .RowEditBox {
    float: none;
    width: 100%;
    max-width: 100%;
  }
}
section {
  margin-top: 1rem;
}

fieldset {
  padding: 1rem;
}

a {
  color: #105151;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

h1, h2, h3, h4 {
  color: #105151;
  margin-bottom: 0.5rem;
}

.PageHeader {
  display: flex;
  justify-content: left;
  align-items: center;
  gap: 1rem;
}

.PageHeader h1 {
  margin: 0;
}

.PageHeaderActions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* A thin menu strip at the top of a page — under the navbar, above the heading —
   for the setup pages that hang off it ("Manage categories" on species, "Manage
   accessions" on lots and pricing). It is the first thing in the page so it
   reads as chrome rather than content: small, quiet, closed by a hairline. */
.PageMenu {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 0.75rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--color-border);
  font-size: 0.85rem;
}
.PageMenu a {
  opacity: 0.8;
}
.PageMenu a:hover {
  opacity: 1;
}

.SettingsLink {
  font-size: 1.5rem;
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.2s;
}

.SettingsLink:hover {
  opacity: 1;
}

hr.dotted {
  border-top: 2px dotted var(--color-border);
}

hr.dashed {
  border: 0;
  border-top: 2px solid transparent;
  border-image: repeating-linear-gradient(to right, var(--color-border) 0 20px, transparent 20px 40px) 100% 1;
}

hr.dashed.light {
  border: 0;
  border-top: 2px solid transparent;
  border-image: repeating-linear-gradient(to right, var(--color-bg-light) 0 20px, transparent 20px 40px) 100% 1;
}

.container {
  max-width: 900px;
  margin: 0 auto;
  padding: 1rem;
  background: white;
  border-radius: 8px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
}

.BoxContainer {
  background-color: #faf7ee;
  border: 1px solid #e3dccb;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  color: #1f3d3d;
  margin-bottom: 2rem;
  max-width: 800px;
}
.BoxContainer.Accent {
  background-color: #caf35b;
  color: #1f3d3d;
}
.BoxContainer.Primary {
  background-color: #105151;
  color: #ffffff;
}
.BoxContainer.Small {
  padding: 0.1rem 0.6rem;
  margin-bottom: 0.1rem;
}
.BoxContainer.HoverGlow:hover {
  border: 1px solid #ffffff;
}

.BoxContainer.Light {
  background-color: rgb(19.7361702128, 165.7838297872, 165.7838297872);
}

.BoxContainer.Dark {
  background-color: #ece5d3;
}

.MediumContentContainer {
  max-width: 800px;
}

#main-content {
  margin: 1rem;
  padding-bottom: max(1rem, env(safe-area-inset-bottom));
  max-width: var(--main-content-width-when-dock-closed);
  transition: max-width var(--dock-transition-duration) var(--dock-transition-ease), margin-left var(--dock-transition-duration) var(--dock-transition-ease), margin-right var(--dock-transition-duration) var(--dock-transition-ease);
  will-change: max-width, margin-left, margin-right; /* hint for smoother anims */
}

#main-content.UserSignedIn {
  margin: calc(var(--app-header-height) + 1rem) 1rem 0 1rem;
}

html.sale-dock-open #main-content.UserSignedIn {
  max-width: var(--main-content-width-when-dock-open);
  margin-left: 0.5rem;
  margin-right: auto;
  overflow: auto;
}

/* Notification dock pushes main content right (desktop only) */
@media (min-width: 768px) {
  html.notification-dock-open #main-content.UserSignedIn {
    margin-left: calc(var(--notif-dock-width) + 0.5rem);
  }
}
/* Wide screens (≥1280px): true 3-column when both docks open */
@media (min-width: 1280px) {
  html.notification-dock-open.sale-dock-open #main-content.UserSignedIn {
    margin-left: calc(var(--notif-dock-width) + 0.5rem);
    max-width: calc(100vw - var(--notif-dock-width) - var(--dock-width-closed) - 1rem);
  }
}
/* A slow navigation or save inside the page: fade the content so the click
   visibly registered. Turbo sets aria-busy on the frame for both. The delay
   keeps quick responses from flickering; pointer events stay on. */
#main_content {
  transition: opacity 0.15s;
}

#main_content[aria-busy=true] {
  opacity: 0.6;
  cursor: progress;
  transition: opacity 0.2s 0.3s;
}

/* Turbo disables the submit button while its form is in flight; make that read
   as "working" rather than "unavailable". */
form[aria-busy=true] :is(button, input)[type=submit]:disabled {
  cursor: progress;
  opacity: 0.6;
}

/* kill transitions while we hydrate */
html.no-transition #main-content,
html.no-transition #SaleDock,
html.no-transition #NotificationDock {
  transition: none !important;
}

/* Respect users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
  #main-content, #SaleDock {
    transition: none !important;
  }
}
/* Print: lock the layout, no animations */
@media print {
  #main-content {
    max-width: var(--main-content-width-when-dock-open);
    margin-left: 0.5rem;
    margin-right: auto;
    transition: none !important;
  }
}
/* Small devices (phones) */
@media (max-width: 767px) {
  body {
    padding: 0;
  }
}
/* Medium devices (tablets) */
/* Large devices (desktops) */
@media (min-width: 992px) {
  #main-content {
    margin: 4rem 4rem 0 4rem;
  }
}
.Hidden {
  display: none;
}

/* Inline "show more" for a long string, built on <details> so it needs no JS
   and survives arriving by turbo stream (the jQuery-bound .Voggle toggles do
   not).

   Both lengths live inside the <summary> and swap on [open]. The obvious
   shape — short text in the summary, the rest as the details' content — cannot
   put the toggle after the text it opens, and laying the element out as a
   reversed flex column to fix that breaks the closed state: a <details> with
   `display: flex` stops hiding its content in Chrome. With nothing outside the
   summary there is nothing to hide, so this one lays out however it likes. */
.TruncatedDisclosure {
  display: inline;
}
.TruncatedDisclosure > summary {
  display: inline;
  cursor: pointer;
  list-style: none;
}
.TruncatedDisclosure > summary::-webkit-details-marker {
  display: none;
}
.TruncatedDisclosure .TruncatedDisclosure__full {
  display: none;
}
.TruncatedDisclosure[open] .TruncatedDisclosure__head {
  display: none;
}
.TruncatedDisclosure[open] .TruncatedDisclosure__full {
  display: inline;
}
.TruncatedDisclosure[open] .TruncatedDisclosure__toggle::after {
  content: "show less";
}
.TruncatedDisclosure .TruncatedDisclosure__toggle {
  white-space: nowrap;
  text-decoration: underline;
  opacity: 0.8;
}
.TruncatedDisclosure .TruncatedDisclosure__toggle::after {
  content: "show more";
}

.FloatLeft {
  float: left;
}

.FloatRight {
  float: right;
}

.AlignLeft {
  text-align: left;
}

.AlignRight {
  text-align: right;
}

.Center {
  text-align: center;
}

.NoWrap {
  white-space: nowrap;
}

.FullWidth {
  width: 100%;
  max-width: 100%;
}

.Pointer {
  cursor: pointer;
}

.bold {
  font-weight: bold;
}

.italic {
  font-style: italic;
}

.hint {
  font-size: 0.8rem;
  color: var(--color-text-faint);
}

.LeftBorder {
  border-left: 2px dashed #e3dccb;
  padding-left: 0.5rem;
}

.NoBorder {
  border: none;
}

.Warning {
  color: var(--color-warning);
}

.Margin {
  margin: 1rem;
}

.MarginSmall {
  margin: 0.5rem;
}

.MarginLarge {
  margin: 2rem;
}

.MarginTop {
  margin-top: 1rem;
}

.MarginTopSmall {
  margin-top: 0.5rem;
}

.MarginTopLarge {
  margin-top: 2rem;
}

.MarginRight {
  margin-right: 1rem;
}

.MarginRightSmall {
  margin-right: 0.5rem;
}

.MarginRightLarge {
  margin-right: 2rem;
}

.MarginBottom {
  margin-bottom: 1rem;
}

.MarginBottomSmall {
  margin-bottom: 0.5rem;
}

.MarginBottomLarge {
  margin-bottom: 2rem;
}

.MarginLeft {
  margin-left: 1rem;
}

.MarginLeftSmall {
  margin-left: 0.5rem;
}

.MarginLeftLarge {
  margin-left: 2rem;
}

.CancelEditButton {
  position: absolute;
  top: 0.25rem;
  right: 0.5rem;
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  padding: 0;
}
.CancelEditButton:hover {
  opacity: 0.7;
}

.DemoText {
  color: var(--color-warning);
  font-weight: normal;
}

.DemoTextPillContainer {
  padding: 2px 4px;
  border-radius: 12px;
  background-color: var(--color-warning-light);
  text-align: center;
  width: 5rem;
}
.DemoTextPillContainer .DemoText {
  font-weight: bold;
  text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
}

.ClickToCopy {
  cursor: pointer;
}

.ClickToCopy:hover {
  opacity: 0.8;
}

.ShowOnParentHover {
  visibility: hidden;
}

.ShowOnParentHoverParent:hover .ShowOnParentHover {
  visibility: visible;
}

.PermissionIcons, .NoteIcon {
  cursor: default;
}

.PermissionGlyph {
  display: inline-block;
  width: 1.15em;
  height: 1.15em;
  vertical-align: -0.2em;
}

.DeleteButtonForm {
  display: inline;
}

.DeleteButtonIcon {
  background: none;
  border: none;
  padding: 0;
  font-size: 1.2rem;
  color: rgb(177, 75.5, 69.5);
  cursor: pointer;
  text-decoration: none;
}
.DeleteButtonIcon:hover {
  text-decoration: underline;
  color: #5d091f;
}

.IconButton {
  position: relative;
  top: -5px;
  display: inline-flex;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  padding: 0rem;
  padding-top: 2px;
  border: 1px solid #e3dccb;
  background: #fff;
  cursor: pointer;
  color: #1f3d3d;
  line-height: 1;
  user-select: none;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.05s ease;
}

.IconButton--danger {
  background: rgb(240.3, 202.15, 195.85);
  border-color: rgb(227.7, 192.175, 190.075);
  color: #5d091f;
}

.IconButton--danger:hover {
  background: rgb(240.96, 222.69, 221.61);
}

.IconButton--danger:focus-visible {
  outline: 2px solid rgb(177, 75.5, 69.5);
  outline-offset: 2px;
}

.FlashOnce {
  animation: flash-bg 1.2s ease-in-out;
}

@keyframes flash-bg {
  0% {
    background-color: rgb(236.45, 250.8, 197.6);
  }
  50% {
    background-color: rgb(220.55, 247.2, 148.4);
  }
  100% {
    background-color: transparent;
  }
}
.StagingHint {
  margin-top: 1.25rem;
  text-align: left;
  background: rgb(235.88, 241.08, 241.08);
  border: 1px dashed rgb(142.6, 164.4, 154.2);
  border-radius: 0.5rem;
  padding: 0.75rem 0.875rem;
}
.StagingHint p {
  margin: 0 0 0.5rem 0;
  font-size: 0.9rem;
  color: #1f3d3d;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.StagingHint .EnvBadge {
  display: inline-block;
  padding: 0.15rem 0.4rem;
  border-radius: 0.375rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #ffffff;
  background: #105151;
  line-height: 1;
}

.StagingHintList {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.4rem;
}
.StagingHintList li {
  display: block;
}
.StagingHintList code {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 0.45rem 0.5rem;
  border: 1px solid #e3dccb;
  border-radius: 0.375rem;
  background: #fffdf7;
  color: #1f3d3d;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 0.9rem;
  user-select: all;
  overflow-x: auto;
  white-space: nowrap;
}
.StagingHintList code:hover {
  border-color: rgb(216.29, 206.6125, 183.11);
}

.ResultItem {
  padding: 0.75rem 1rem;
  cursor: pointer;
  border-bottom: 1px solid #e3dccb;
  transition: background-color 0.15s ease;
}

.ResultItem:hover {
  background-color: #fffdf7;
}

.ResultItem:last-child {
  border-bottom: none;
}

.ResultItem__primary {
  font-size: 0.95rem;
  line-height: 1.4;
  color: #1f3d3d;
  margin-bottom: 0.25rem;
}

.ResultItem__primary strong {
  font-weight: 600;
}

.ResultItem__secondary {
  font-size: 0.85rem;
  line-height: 1.3;
  color: #527070;
}

/* Optional: Add a subtle highlight on focus for accessibility */
.ResultItem:focus {
  outline: 2px solid #105151;
  outline-offset: -2px;
  background-color: rgba(16, 81, 81, 0.08);
}
