/* The theme's stylesheet initializes tailwindcss and imports the theme's default styles.

   The $ThemeStylesheet path is evaluated via a postcss resolver, which finds the theme's
   main stylesheet within the theme's gem.
   
   To control the order of the tailwindcss imports further, you can eject the theme's
   stylesheet locally using the following command, which will take precedence.
   > rake bullet_train:themes:light:eject_css

   Read more: https://bullettrain.co/docs/stylesheets
*/
/*
 * This is an extra level of indirection because for some reason using @tailwind directives directly inside this file doesn't work.
 * When we move to v4 we should be able to just to `@import "tailwindcss"` here.
 */
*, ::before, ::after{
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}
::backdrop{
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}
/* ! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com
*/
/*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/
*,
::before,
::after {
  box-sizing: border-box; /* 1 */
  border-width: 0; /* 2 */
  border-style: solid; /* 2 */
  border-color: #e5e7eb; /* 2 */
}
::before,
::after {
  --tw-content: '';
}
/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/
html,
:host {
  line-height: 1.5; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
  -moz-tab-size: 4; /* 3 */
  -o-tab-size: 4;
     tab-size: 4; /* 3 */
  font-family: 'Inter', ui-sans-serif, system-ui, sans-serif; /* 4 */
  font-feature-settings: normal; /* 5 */
  font-variation-settings: normal; /* 6 */
  -webkit-tap-highlight-color: transparent; /* 7 */
}
/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/
body {
  margin: 0; /* 1 */
  line-height: inherit; /* 2 */
}
/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/
hr {
  height: 0; /* 1 */
  color: inherit; /* 2 */
  border-top-width: 1px; /* 3 */
}
/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr:where([title]) {
  -webkit-text-decoration: underline dotted;
          text-decoration: underline dotted;
}
/*
Remove the default font size and weight for headings.
*/
h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}
/*
Reset links to optimize for opt-in styling instead of opt-out.
*/
a {
  color: inherit;
  text-decoration: inherit;
}
/*
Add the correct font weight in Edge and Safari.
*/
b,
strong {
  font-weight: bolder;
}
/*
1. Use the user's configured `mono` font-family by default.
2. Use the user's configured `mono` font-feature-settings by default.
3. Use the user's configured `mono` font-variation-settings by default.
4. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
  font-family: 'Geist Mono', ui-monospace, monospace; /* 1 */
  font-feature-settings: normal; /* 2 */
  font-variation-settings: normal; /* 3 */
  font-size: 1em; /* 4 */
}
/*
Add the correct font size in all browsers.
*/
small {
  font-size: 80%;
}
/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/
sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}
sub {
  bottom: -0.25em;
}
sup {
  top: -0.5em;
}
/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/
table {
  text-indent: 0; /* 1 */
  border-color: inherit; /* 2 */
  border-collapse: collapse; /* 3 */
}
/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/
button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-feature-settings: inherit; /* 1 */
  font-variation-settings: inherit; /* 1 */
  font-size: 100%; /* 1 */
  font-weight: inherit; /* 1 */
  line-height: inherit; /* 1 */
  letter-spacing: inherit; /* 1 */
  color: inherit; /* 1 */
  margin: 0; /* 2 */
  padding: 0; /* 3 */
}
/*
Remove the inheritance of text transform in Edge and Firefox.
*/
button,
select {
  text-transform: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/
button,
input:where([type='button']),
input:where([type='reset']),
input:where([type='submit']) {
  -webkit-appearance: button; /* 1 */
  background-color: transparent; /* 2 */
  background-image: none; /* 2 */
}
/*
Use the modern Firefox focus style for all focusable elements.
*/
:-moz-focusring {
  outline: auto;
}
/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/
:-moz-ui-invalid {
  box-shadow: none;
}
/*
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
  vertical-align: baseline;
}
/*
Correct the cursor style of increment and decrement buttons in Safari.
*/
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
  height: auto;
}
/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
[type='search'] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}
/*
Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
  -webkit-appearance: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}
/*
Add the correct display in Chrome and Safari.
*/
summary {
  display: list-item;
}
/*
Removes the default spacing and border for appropriate elements.
*/
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
  margin: 0;
}
fieldset {
  margin: 0;
  padding: 0;
}
legend {
  padding: 0;
}
ol,
ul,
menu {
  list-style: none;
  margin: 0;
  padding: 0;
}
/*
Reset default styling for dialogs.
*/
dialog {
  padding: 0;
}
/*
Prevent resizing textareas horizontally by default.
*/
textarea {
  resize: vertical;
}
/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/
input::-moz-placeholder, textarea::-moz-placeholder {
  opacity: 1; /* 1 */
  color: #9ca3af; /* 2 */
}
input::placeholder,
textarea::placeholder {
  opacity: 1; /* 1 */
  color: #9ca3af; /* 2 */
}
/*
Set the default cursor for buttons.
*/
button,
[role="button"] {
  cursor: pointer;
}
/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
  cursor: default;
}
/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
   This can trigger a poorly considered lint error in some tools but is included by design.
*/
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block; /* 1 */
  vertical-align: middle; /* 2 */
}
/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/
img,
video {
  max-width: 100%;
  height: auto;
}
/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden]:where(:not([hidden="until-found"])) {
  display: none;
}
input:where([type='text']),input:where(:not([type])),input:where([type='email']),input:where([type='url']),input:where([type='password']),input:where([type='number']),input:where([type='date']),input:where([type='datetime-local']),input:where([type='month']),input:where([type='search']),input:where([type='tel']),input:where([type='time']),input:where([type='week']),select:where([multiple]),textarea,select{
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background-color: #fff;
  border-color: #6b7280;
  border-width: 1px;
  border-radius: 0px;
  padding-top: 0.5rem;
  padding-right: 0.75rem;
  padding-bottom: 0.5rem;
  padding-left: 0.75rem;
  font-size: 1rem;
  line-height: 1.5rem;
  --tw-shadow: 0 0 #0000;
}
input:where([type='text']):focus, input:where(:not([type])):focus, input:where([type='email']):focus, input:where([type='url']):focus, input:where([type='password']):focus, input:where([type='number']):focus, input:where([type='date']):focus, input:where([type='datetime-local']):focus, input:where([type='month']):focus, input:where([type='search']):focus, input:where([type='tel']):focus, input:where([type='time']):focus, input:where([type='week']):focus, select:where([multiple]):focus, textarea:focus, select:focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: #2563eb;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  border-color: #2563eb;
}
input::-moz-placeholder, textarea::-moz-placeholder{
  color: #6b7280;
  opacity: 1;
}
input::placeholder,textarea::placeholder{
  color: #6b7280;
  opacity: 1;
}
::-webkit-datetime-edit-fields-wrapper{
  padding: 0;
}
::-webkit-date-and-time-value{
  min-height: 1.5em;
  text-align: inherit;
}
::-webkit-datetime-edit{
  display: inline-flex;
}
::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{
  padding-top: 0;
  padding-bottom: 0;
}
select{
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  background-position: right 0.5rem center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
  padding-right: 2.5rem;
  -webkit-print-color-adjust: exact;
          print-color-adjust: exact;
}
select:where([multiple]),select:where([size]:not([size="1"])){
  background-image: initial;
  background-position: initial;
  background-repeat: unset;
  background-size: initial;
  padding-right: 0.75rem;
  -webkit-print-color-adjust: unset;
          print-color-adjust: unset;
}
input:where([type='checkbox']),input:where([type='radio']){
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  padding: 0;
  -webkit-print-color-adjust: exact;
          print-color-adjust: exact;
  display: inline-block;
  vertical-align: middle;
  background-origin: border-box;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  flex-shrink: 0;
  height: 1rem;
  width: 1rem;
  color: #2563eb;
  background-color: #fff;
  border-color: #6b7280;
  border-width: 1px;
  --tw-shadow: 0 0 #0000;
}
input:where([type='checkbox']){
  border-radius: 0px;
}
input:where([type='radio']){
  border-radius: 100%;
}
input:where([type='checkbox']):focus,input:where([type='radio']):focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
  --tw-ring-offset-width: 2px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: #2563eb;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
input:where([type='checkbox']):checked,input:where([type='radio']):checked{
  border-color: transparent;
  background-color: currentColor;
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
}
input:where([type='checkbox']):checked{
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
@media (forced-colors: active) {
  input:where([type='checkbox']):checked{
    -webkit-appearance: auto;
       -moz-appearance: auto;
            appearance: auto;
  }
}
input:where([type='radio']):checked{
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
}
@media (forced-colors: active) {
  input:where([type='radio']):checked{
    -webkit-appearance: auto;
       -moz-appearance: auto;
            appearance: auto;
  }
}
input:where([type='checkbox']):checked:hover,input:where([type='checkbox']):checked:focus,input:where([type='radio']):checked:hover,input:where([type='radio']):checked:focus{
  border-color: transparent;
  background-color: currentColor;
}
input:where([type='checkbox']):indeterminate{
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
  border-color: transparent;
  background-color: currentColor;
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
}
@media (forced-colors: active) {
  input:where([type='checkbox']):indeterminate{
    -webkit-appearance: auto;
       -moz-appearance: auto;
            appearance: auto;
  }
}
input:where([type='checkbox']):indeterminate:hover,input:where([type='checkbox']):indeterminate:focus{
  border-color: transparent;
  background-color: currentColor;
}
input:where([type='file']){
  background: unset;
  border-color: inherit;
  border-width: 0;
  border-radius: 0;
  padding: 0;
  font-size: unset;
  line-height: inherit;
}
input:where([type='file']):focus{
  outline: 1px solid ButtonText;
  outline: 1px auto -webkit-focus-ring-color;
}
.container{
  width: 100%;
}
@media (min-width: 640px){
  .container{
    max-width: 640px;
  }
}
@media (min-width: 768px){
  .container{
    max-width: 768px;
  }
}
@media (min-width: 1024px){
  .container{
    max-width: 1024px;
  }
}
@media (min-width: 1280px){
  .container{
    max-width: 1280px;
  }
}
@media (min-width: 1536px){
  .container{
    max-width: 1536px;
  }
}
.form-input,.form-textarea,.form-select,.form-multiselect{
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background-color: #fff;
  border-color: #6b7280;
  border-width: 1px;
  border-radius: 0px;
  padding-top: 0.5rem;
  padding-right: 0.75rem;
  padding-bottom: 0.5rem;
  padding-left: 0.75rem;
  font-size: 1rem;
  line-height: 1.5rem;
  --tw-shadow: 0 0 #0000;
}
.form-input:focus, .form-textarea:focus, .form-select:focus, .form-multiselect:focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: #2563eb;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  border-color: #2563eb;
}
.form-select{
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  background-position: right 0.5rem center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
  padding-right: 2.5rem;
  -webkit-print-color-adjust: exact;
          print-color-adjust: exact;
}
.form-select:where([size]:not([size="1"])){
  background-image: initial;
  background-position: initial;
  background-repeat: unset;
  background-size: initial;
  padding-right: 0.75rem;
  -webkit-print-color-adjust: unset;
          print-color-adjust: unset;
}
.prose{
  color: var(--tw-prose-body);
  max-width: 65ch;
}
.prose :where(p):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 1.25em;
  margin-bottom: 1.25em;
}
.prose :where([class~="lead"]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-lead);
  font-size: 1.25em;
  line-height: 1.6;
  margin-top: 1.2em;
  margin-bottom: 1.2em;
}
.prose :where(a):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-links);
  text-decoration: underline;
  font-weight: 500;
}
.prose :where(strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-bold);
  font-weight: 600;
}
.prose :where(a strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(blockquote strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(thead th strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(ol):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: decimal;
  margin-top: 1.25em;
  margin-bottom: 1.25em;
  padding-inline-start: 1.625em;
}
.prose :where(ol[type="A"]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: upper-alpha;
}
.prose :where(ol[type="a"]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: lower-alpha;
}
.prose :where(ol[type="A" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: upper-alpha;
}
.prose :where(ol[type="a" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: lower-alpha;
}
.prose :where(ol[type="I"]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: upper-roman;
}
.prose :where(ol[type="i"]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: lower-roman;
}
.prose :where(ol[type="I" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: upper-roman;
}
.prose :where(ol[type="i" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: lower-roman;
}
.prose :where(ol[type="1"]):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: decimal;
}
.prose :where(ul):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  list-style-type: disc;
  margin-top: 1.25em;
  margin-bottom: 1.25em;
  padding-inline-start: 1.625em;
}
.prose :where(ol > li):not(:where([class~="not-prose"],[class~="not-prose"] *))::marker{
  font-weight: 400;
  color: var(--tw-prose-counters);
}
.prose :where(ul > li):not(:where([class~="not-prose"],[class~="not-prose"] *))::marker{
  color: var(--tw-prose-bullets);
}
.prose :where(dt):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-headings);
  font-weight: 600;
  margin-top: 1.25em;
}
.prose :where(hr):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  border-color: var(--tw-prose-hr);
  border-top-width: 1px;
  margin-top: 3em;
  margin-bottom: 3em;
}
.prose :where(blockquote):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  font-weight: 500;
  font-style: italic;
  color: var(--tw-prose-quotes);
  border-inline-start-width: 0.25rem;
  border-inline-start-color: var(--tw-prose-quote-borders);
  quotes: "\201C""\201D""\2018""\2019";
  margin-top: 1.6em;
  margin-bottom: 1.6em;
  padding-inline-start: 1em;
}
.prose :where(blockquote p:first-of-type):not(:where([class~="not-prose"],[class~="not-prose"] *))::before{
  content: open-quote;
}
.prose :where(blockquote p:last-of-type):not(:where([class~="not-prose"],[class~="not-prose"] *))::after{
  content: close-quote;
}
.prose :where(h1):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-headings);
  font-weight: 800;
  font-size: 2.25em;
  margin-top: 0;
  margin-bottom: 0.8888889em;
  line-height: 1.1111111;
}
.prose :where(h1 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  font-weight: 900;
  color: inherit;
}
.prose :where(h2):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-headings);
  font-weight: 700;
  font-size: 1.5em;
  margin-top: 2em;
  margin-bottom: 1em;
  line-height: 1.3333333;
}
.prose :where(h2 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  font-weight: 800;
  color: inherit;
}
.prose :where(h3):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-headings);
  font-weight: 600;
  font-size: 1.25em;
  margin-top: 1.6em;
  margin-bottom: 0.6em;
  line-height: 1.6;
}
.prose :where(h3 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  font-weight: 700;
  color: inherit;
}
.prose :where(h4):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-headings);
  font-weight: 600;
  margin-top: 1.5em;
  margin-bottom: 0.5em;
  line-height: 1.5;
}
.prose :where(h4 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  font-weight: 700;
  color: inherit;
}
.prose :where(img):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 2em;
  margin-bottom: 2em;
}
.prose :where(picture):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  display: block;
  margin-top: 2em;
  margin-bottom: 2em;
}
.prose :where(video):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 2em;
  margin-bottom: 2em;
}
.prose :where(kbd):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  font-weight: 500;
  font-family: inherit;
  color: var(--tw-prose-kbd);
  box-shadow: 0 0 0 1px var(--tw-prose-kbd-shadows), 0 3px 0 var(--tw-prose-kbd-shadows);
  font-size: 0.875em;
  border-radius: 0.3125rem;
  padding-top: 0.1875em;
  padding-inline-end: 0.375em;
  padding-bottom: 0.1875em;
  padding-inline-start: 0.375em;
}
.prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-code);
  font-weight: 600;
  font-size: 0.875em;
}
.prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *))::before{
  content: "`";
}
.prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *))::after{
  content: "`";
}
.prose :where(a code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(h1 code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(h2 code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
  font-size: 0.875em;
}
.prose :where(h3 code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
  font-size: 0.9em;
}
.prose :where(h4 code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(blockquote code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(thead th code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: inherit;
}
.prose :where(pre):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-pre-code);
  background-color: var(--tw-prose-pre-bg);
  overflow-x: auto;
  font-weight: 400;
  font-size: 0.875em;
  line-height: 1.7142857;
  margin-top: 1.7142857em;
  margin-bottom: 1.7142857em;
  border-radius: 0.375rem;
  padding-top: 0.8571429em;
  padding-inline-end: 1.1428571em;
  padding-bottom: 0.8571429em;
  padding-inline-start: 1.1428571em;
}
.prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  background-color: transparent;
  border-width: 0;
  border-radius: 0;
  padding: 0;
  font-weight: inherit;
  color: inherit;
  font-size: inherit;
  font-family: inherit;
  line-height: inherit;
}
.prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *))::before{
  content: none;
}
.prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *))::after{
  content: none;
}
.prose :where(table):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  width: 100%;
  table-layout: auto;
  margin-top: 2em;
  margin-bottom: 2em;
  font-size: 0.875em;
  line-height: 1.7142857;
}
.prose :where(thead):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  border-bottom-width: 1px;
  border-bottom-color: var(--tw-prose-th-borders);
}
.prose :where(thead th):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-headings);
  font-weight: 600;
  vertical-align: bottom;
  padding-inline-end: 0.5714286em;
  padding-bottom: 0.5714286em;
  padding-inline-start: 0.5714286em;
}
.prose :where(tbody tr):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  border-bottom-width: 1px;
  border-bottom-color: var(--tw-prose-td-borders);
}
.prose :where(tbody tr:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  border-bottom-width: 0;
}
.prose :where(tbody td):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  vertical-align: baseline;
}
.prose :where(tfoot):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  border-top-width: 1px;
  border-top-color: var(--tw-prose-th-borders);
}
.prose :where(tfoot td):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  vertical-align: top;
}
.prose :where(th, td):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  text-align: start;
}
.prose :where(figure > *):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
  margin-bottom: 0;
}
.prose :where(figcaption):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  color: var(--tw-prose-captions);
  font-size: 0.875em;
  line-height: 1.4285714;
  margin-top: 0.8571429em;
}
.prose{
  --tw-prose-body: #374151;
  --tw-prose-headings: #111827;
  --tw-prose-lead: #4b5563;
  --tw-prose-links: #111827;
  --tw-prose-bold: #111827;
  --tw-prose-counters: #6b7280;
  --tw-prose-bullets: #d1d5db;
  --tw-prose-hr: #e5e7eb;
  --tw-prose-quotes: #111827;
  --tw-prose-quote-borders: #e5e7eb;
  --tw-prose-captions: #6b7280;
  --tw-prose-kbd: #111827;
  --tw-prose-kbd-shadows: rgb(17 24 39 / 10%);
  --tw-prose-code: #111827;
  --tw-prose-pre-code: #e5e7eb;
  --tw-prose-pre-bg: #1f2937;
  --tw-prose-th-borders: #d1d5db;
  --tw-prose-td-borders: #e5e7eb;
  --tw-prose-invert-body: #d1d5db;
  --tw-prose-invert-headings: #fff;
  --tw-prose-invert-lead: #9ca3af;
  --tw-prose-invert-links: #fff;
  --tw-prose-invert-bold: #fff;
  --tw-prose-invert-counters: #9ca3af;
  --tw-prose-invert-bullets: #4b5563;
  --tw-prose-invert-hr: #374151;
  --tw-prose-invert-quotes: #f3f4f6;
  --tw-prose-invert-quote-borders: #374151;
  --tw-prose-invert-captions: #9ca3af;
  --tw-prose-invert-kbd: #fff;
  --tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%);
  --tw-prose-invert-code: #fff;
  --tw-prose-invert-pre-code: #d1d5db;
  --tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);
  --tw-prose-invert-th-borders: #4b5563;
  --tw-prose-invert-td-borders: #374151;
  font-size: 1rem;
  line-height: 1.75;
}
.prose :where(picture > img):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
  margin-bottom: 0;
}
.prose :where(li):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}
.prose :where(ol > li):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-inline-start: 0.375em;
}
.prose :where(ul > li):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-inline-start: 0.375em;
}
.prose :where(.prose > ul > li p):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0.75em;
  margin-bottom: 0.75em;
}
.prose :where(.prose > ul > li > p:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 1.25em;
}
.prose :where(.prose > ul > li > p:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-bottom: 1.25em;
}
.prose :where(.prose > ol > li > p:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 1.25em;
}
.prose :where(.prose > ol > li > p:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-bottom: 1.25em;
}
.prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0.75em;
  margin-bottom: 0.75em;
}
.prose :where(dl):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 1.25em;
  margin-bottom: 1.25em;
}
.prose :where(dd):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0.5em;
  padding-inline-start: 1.625em;
}
.prose :where(hr + *):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
}
.prose :where(h2 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
}
.prose :where(h3 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
}
.prose :where(h4 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
}
.prose :where(thead th:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-inline-start: 0;
}
.prose :where(thead th:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-inline-end: 0;
}
.prose :where(tbody td, tfoot td):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-top: 0.5714286em;
  padding-inline-end: 0.5714286em;
  padding-bottom: 0.5714286em;
  padding-inline-start: 0.5714286em;
}
.prose :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-inline-start: 0;
}
.prose :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  padding-inline-end: 0;
}
.prose :where(figure):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 2em;
  margin-bottom: 2em;
}
.prose :where(.prose > :first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-top: 0;
}
.prose :where(.prose > :last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)){
  margin-bottom: 0;
}
a{
  color: var(--secondary-500);
}
a:hover{
  color: var(--secondary-600);
  text-decoration-line: underline;
}
b, strong{
  font-weight: 500;
}
.buttons > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
.button{
  background-color: var(--primary-500);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.button:hover{
  background-color: var(--primary-600);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  text-decoration-line: none;
}
.button:focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
  --tw-ring-color: var(--primary-600);
  --tw-ring-offset-width: 2px;
}
.button:where(.dark, .dark *){
  --tw-ring-offset-color: #334155;
}
.button.button-red{
  --tw-bg-opacity: 1;
  background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
}
.button.button-red:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.button.button-red:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(220 38 38 / var(--tw-ring-opacity, 1));
}
.button-secondary{
  color: var(--secondary-500);
}
.button-secondary:hover{
  color: var(--secondary-600);
  text-decoration-line: underline;
}
/* @apply dark:text-base-200; */
.button-secondary.button-increase-contrast{
  color: var(--secondary-700);
}
.button-secondary.button-increase-contrast:hover{
  color: var(--secondary-900);
}
.button-secondary.button-red{
  --tw-text-opacity: 1;
  color: rgb(239 68 68 / var(--tw-text-opacity, 1));
}
.button-secondary.button-red:hover{
  --tw-text-opacity: 1;
  color: rgb(220 38 38 / var(--tw-text-opacity, 1));
}
.button-secondary.button-red.button-increase-contrast{
  --tw-text-opacity: 1;
  color: rgb(185 28 28 / var(--tw-text-opacity, 1));
}
.button-secondary.button-red.button-increase-contrast:hover{
  --tw-text-opacity: 1;
  color: rgb(127 29 29 / var(--tw-text-opacity, 1));
}
.button, .button-secondary, .button-alternative{
  border-radius: 0.375rem;
  border-width: 1px;
  border-color: transparent;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.button.button-smaller, .button-secondary.button-smaller, .button-alternative.button-smaller{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  font-size: var(--text-xs);
}
.button-alternative{
  border-radius: 0.375rem;
  --tw-border-opacity: 1;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1));
  text-decoration-line: none;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.button-alternative:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1));
  text-decoration-line: none;
}
.button-alternative:where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.button-alternative:hover:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.button-color{
  background-color: var(--primary-500);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.button-color:hover{
  background-color: var(--primary-600);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  text-decoration-line: none;
}
.button-color:focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
  --tw-ring-color: var(--primary-600);
  --tw-ring-offset-width: 2px;
}
.button-color:where(.dark, .dark *){
  --tw-ring-offset-color: #334155;
}
.button-color.button-red{
  --tw-bg-opacity: 1;
  background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
}
.button-color.button-red:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.button-color.button-red:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(220 38 38 / var(--tw-ring-opacity, 1));
}
.button-color{
  border-radius: 0.375rem;
  border-width: 1px;
  border-color: transparent;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.button-color.button-smaller{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  font-size: var(--text-xs);
}
form.button_to input[type=submit].button-color{
  background-color: var(--primary-500);
}
form.button_to input[type=submit].button-color:hover{
  background-color: var(--primary-600);
}
:is(.equipment-item-actions, .os-equipment-item-actions) :is(.button-color, .os-button) {
  font-size: var(--text-sm);
}
:is(.button-color, .os-button) {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  box-shadow: none;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
}
:is(.button-color, .os-button):hover {
  color: #fff;
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
:is(.button-color, .os-button):is(.button-red, .os-button-red) {
  color: #fff;
  background: var(--red-600);
  border-color: var(--red-600);
}
:is(.button-color, .os-button):is(.button-red, .os-button-red):hover {
  color: #fff;
  background: var(--red-700);
  border-color: var(--red-700);
}
a:is(.button-color, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)), button:is(.button-color, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)) {
  background-color: var(--accent);
  border-color: var(--accent);
}
a:is(.button-color, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover, button:is(.button-color, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover {
  background-color: var(--accent-strong, var(--accent));
}
.button-color{
  border-radius: 9999px;
}
.btn-toggle input[type=checkbox], .btn-toggle input[type=radio] {
      display: none;
    }
.btn-toggle input[type=checkbox]:checked + button, .btn-toggle input[type=radio]:checked + button{
  background-color: var(--primary-500);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.btn-toggle input[type=checkbox]:checked + button:hover, .btn-toggle input[type=radio]:checked + button:hover{
  background-color: var(--primary-600);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  text-decoration-line: none;
}
.btn-toggle input[type=checkbox]:checked + button:focus, .btn-toggle input[type=radio]:checked + button:focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
  --tw-ring-color: var(--primary-600);
  --tw-ring-offset-width: 2px;
}
.btn-toggle input[type=checkbox]:checked + button:where(.dark, .dark *), .btn-toggle input[type=radio]:checked + button:where(.dark, .dark *){
  --tw-ring-offset-color: #334155;
}
.btn-toggle input[type=checkbox]:checked + button.button-red, .btn-toggle input[type=radio]:checked + button.button-red{
  --tw-bg-opacity: 1;
  background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
}
.btn-toggle input[type=checkbox]:checked + button.button-red:hover, .btn-toggle input[type=radio]:checked + button.button-red:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.btn-toggle input[type=checkbox]:checked + button.button-red:focus, .btn-toggle input[type=radio]:checked + button.button-red:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(220 38 38 / var(--tw-ring-opacity, 1));
}
.btn-toggle input[type=checkbox]:checked + button, .btn-toggle input[type=radio]:checked + button{
  border-radius: 0.375rem;
  border-width: 1px;
  border-color: transparent;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.btn-toggle input[type=checkbox]:checked + button.button-smaller, .btn-toggle input[type=radio]:checked + button.button-smaller{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  font-size: var(--text-xs);
}
form.button_to input[type=submit].btn-toggle input[type=checkbox]:checked + button,form.button_to input[type=submit] .btn-toggle input[type=radio]:checked + button{
  background-color: var(--primary-500);
}
form.button_to input[type=submit].btn-toggle input[type=checkbox]:checked + button:hover,form.button_to input[type=submit] .btn-toggle input[type=radio]:checked + button:hover{
  background-color: var(--primary-600);
}
:is(.equipment-item-actions, .os-equipment-item-actions) :is(.btn-toggle input[type=checkbox]:checked + button, .os-button),:is(.equipment-item-actions, .os-equipment-item-actions) :is( .btn-toggle input[type=radio]:checked + button, .os-button) {
  font-size: var(--text-sm);
}
:is(.btn-toggle input[type=checkbox]:checked + button, .os-button),:is( .btn-toggle input[type=radio]:checked + button, .os-button) {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  box-shadow: none;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
}
:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):hover,:is( .btn-toggle input[type=radio]:checked + button, .os-button):hover {
  color: #fff;
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):is(.button-red, .os-button-red),:is( .btn-toggle input[type=radio]:checked + button, .os-button):is(.button-red, .os-button-red) {
  color: #fff;
  background: var(--red-600);
  border-color: var(--red-600);
}
:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):is(.button-red, .os-button-red):hover,:is( .btn-toggle input[type=radio]:checked + button, .os-button):is(.button-red, .os-button-red):hover {
  color: #fff;
  background: var(--red-700);
  border-color: var(--red-700);
}
a:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)), button:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)),a:is( .btn-toggle input[type=radio]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)), button:is( .btn-toggle input[type=radio]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)) {
  background-color: var(--accent);
  border-color: var(--accent);
}
a:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover, button:is(.btn-toggle input[type=checkbox]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover,a:is( .btn-toggle input[type=radio]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover, button:is( .btn-toggle input[type=radio]:checked + button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover {
  background-color: var(--accent-strong, var(--accent));
}
.btn-toggle.btn-color-picker input[type=checkbox]:checked + button, .btn-toggle.btn-color-picker input[type=radio]:checked + button{
  border-radius: 9999px;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
  --tw-ring-offset-width: 2px;
}
.full{
  display: flex;
  width: 100%;
  justify-content: center;
}
form.\!form > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
form.form > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
form.\!form .form-wrapper > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
form.form .form-wrapper > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
form.\!form .form-wrapper[disabled] {
        opacity: 0.3 !important;
        position: relative !important;
        -webkit-user-select: none !important;
           -moz-user-select: none !important;
                user-select: none !important;
      }
form.form .form-wrapper[disabled] {
        opacity: 0.3;
        position: relative;
        -webkit-user-select: none;
           -moz-user-select: none;
                user-select: none;
      }
form.\!form .form-wrapper[disabled]:before {
          content: "" !important;
          position: absolute !important;
          background-color: transparent !important;
          top: 0 !important;
          bottom: 0 !important;
          left: 0 !important;
          right: 0 !important;
        }
form.form .form-wrapper[disabled]:before {
          content: "";
          position: absolute;
          background-color: transparent;
          top: 0;
          bottom: 0;
          left: 0;
          right: 0;
        }
/*
    This is the best way I know how to solve the problem of Tailwind's `space-y-5` creating extra space at the top
    because Rails injects hidden fields at the top of our forms. However, we don't need this on `get` forms, because
    no extra element is injected into the form.
    */
form.\!form[method="post" i], form.\!form[method="patch" i]{
  margin-top: -1.25rem;
}
form.form[method="post" i], form.form[method="patch" i]{
  margin-top: -1.25rem;
}
form.\!form[method="post" i], form.\!form[method="patch" i]{
  margin-top: -1.25rem;
}
form.\!form .buttons{
  padding-top: 0.25rem;
}
form.\!form .buttons > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
form.form .buttons{
  padding-top: 0.25rem;
}
form.form .buttons > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
.table{
  width: 100%;
}
.table > :not([hidden]) ~ :not([hidden]){
  --tw-divide-y-reverse: 0;
  border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
  border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
  border-color: rgb(15 23 42 / 0.05);
}
.table{
  text-align: left;
}
.table:where(.dark, .dark *) > :not([hidden]) ~ :not([hidden]){
  border-color: rgb(51 65 85 / 0.05);
}
.table th{
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
  font-size: var(--text-2xs);
  line-height: 0.9rem;
  letter-spacing: 1px;
  font-weight: 400;
  text-transform: uppercase;
}
.table th:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(148 163 184 / var(--tw-text-opacity, 1));
}
.table th:first-child{
  padding-left: 1.25rem;
}
.table th:last-child{
  padding-right: 1.25rem;
}
.table tbody > :not([hidden]) ~ :not([hidden]){
  --tw-divide-y-reverse: 0;
  border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
  border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
  border-color: rgb(15 23 42 / 0.05);
}
.table tbody:where(.dark, .dark *) > :not([hidden]) ~ :not([hidden]){
  border-color: rgb(51 65 85 / 0.05);
}
.table td{
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
}
.table td:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(148 163 184 / var(--tw-text-opacity, 1));
}
.table td:first-child{
  padding-left: 1.25rem;
}
.table td:last-child{
  padding-right: 1.25rem;
}
.table td.buttons{
  padding-right: 0.75rem;
}
.table td.buttons > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.5rem * var(--tw-space-x-reverse));
  margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
}
.table td.buttons{
  text-align: right;
}
/* just having a cell with buttons shouldn't expand the height of a table row. */
.table td.buttons > *{
  margin-top: -1.25rem;
  margin-bottom: -1.25rem;
}
.box-table .table th:first-child, .box-table .table td:first-child{
  padding-left: 2rem;
}
.box-table .table th:last-child, .box-table .table td:last-child{
  padding-right: 2rem;
}
.pagy{
  display: flex;
}
.pagy > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.25rem * var(--tw-space-x-reverse));
  margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
}
.pagy a:not(.gap){
  border-radius: 0.375rem;
  border-width: 1px;
  border-color: transparent;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.pagy a:not(.gap).button-smaller{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  font-size: var(--text-xs);
}
.pagy a:not(.gap){
  border-radius: 0.375rem;
  --tw-border-opacity: 1;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1));
  text-decoration-line: none;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.pagy a:not(.gap):hover{
  --tw-bg-opacity: 1;
  background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1));
  text-decoration-line: none;
}
.pagy a:not(.gap):where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.pagy a:not(.gap):hover:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
 :is(.pagy a:not(.gap), .os-button-alternative) {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  box-shadow: none;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border);
}
 :is(.pagy a:not(.gap), .os-button-alternative):hover {
  color: var(--text-primary);
  background: var(--surface-alt);
  border-color: var(--border);
}
:is(.btn-toggle, .os-btn-toggle):has(input:checked) :is(.pagy a:not(.gap), .os-button-alternative) {
  background-color: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
:is(.btn-toggle, .os-btn-toggle):has(input:checked) :is(.pagy a:not(.gap), .os-button-alternative):hover {
  background-color: var(--accent-strong, var(--accent));
}
a:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.pagy a:not(.gap), .os-button-alternative)), button:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.pagy a:not(.gap), .os-button-alternative)) {
  background-color: var(--accent);
  border-color: var(--accent);
}
a:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.pagy a:not(.gap), .os-button-alternative)):hover, button:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.pagy a:not(.gap), .os-button-alternative)):hover {
  background-color: var(--accent-strong, var(--accent));
}
.pagy a:not(.gap):not([href]) { /* disabled links (aka: the current page) */ background-color: var(--primary-500); --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity, 1)); --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
      }
.pagy a:not(.gap):not([href]):hover{
  background-color: var(--primary-600);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
  text-decoration-line: none;
}
.pagy a:not(.gap):not([href]):focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
  --tw-ring-color: var(--primary-600);
  --tw-ring-offset-width: 2px;
}
.pagy a:not(.gap):not([href]):where(.dark, .dark *){
  --tw-ring-offset-color: #334155;
}
.pagy a:not(.gap):not([href]).button-red{
  --tw-bg-opacity: 1;
  background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
}
.pagy a:not(.gap):not([href]).button-red:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.pagy a:not(.gap):not([href]).button-red:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(220 38 38 / var(--tw-ring-opacity, 1));
}
.pagy a:not(.gap):not([href]){
  border-radius: 0.375rem;
  border-width: 1px;
  border-color: transparent;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.pagy a:not(.gap):not([href]).button-smaller{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  font-size: var(--text-xs);
}
form.button_to input[type=submit].pagy a:not(.gap):not([href]){
  background-color: var(--primary-500);
}
form.button_to input[type=submit].pagy a:not(.gap):not([href]):hover{
  background-color: var(--primary-600);
}
:is(.equipment-item-actions, .os-equipment-item-actions) :is(.pagy a:not(.gap):not([href]), .os-button) {
  font-size: var(--text-sm);
}
:is(.pagy a:not(.gap):not([href]), .os-button) {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  box-shadow: none;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
}
:is(.pagy a:not(.gap):not([href]), .os-button):hover {
  color: #fff;
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
:is(.pagy a:not(.gap):not([href]), .os-button):is(.button-red, .os-button-red) {
  color: #fff;
  background: var(--red-600);
  border-color: var(--red-600);
}
:is(.pagy a:not(.gap):not([href]), .os-button):is(.button-red, .os-button-red):hover {
  color: #fff;
  background: var(--red-700);
  border-color: var(--red-700);
}
a:is(.pagy a:not(.gap):not([href]), .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)), button:is(.pagy a:not(.gap):not([href]), .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)) {
  background-color: var(--accent);
  border-color: var(--accent);
}
a:is(.pagy a:not(.gap):not([href]), .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover, button:is(.pagy a:not(.gap):not([href]), .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover {
  background-color: var(--accent-strong, var(--accent));
}
.pagy a:not(.gap):not([href]):not([aria-current]){ /* the prev link when on first page, next link when on last page */ display: none;
        }
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.pagy a:not(.gap):not([href]):not([aria-current])) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.pagy a:not(.gap):not([href]):not([aria-current]))),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.pagy a:not(.gap):not([href]):not([aria-current]))):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).pagy a:not(.gap):not([href]):not([aria-current]) { display: none; }
.os-select--native.os-select--native select:not([hidden],.pagy a:not(.gap):not([href]):not([aria-current])):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
:is(.diver-cards, .os-diver-cards).pagy a:not(.gap):not([href]):not([aria-current]) {
  display: none;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).pagy a:not(.gap):not([href]):not([aria-current]) { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].pagy a:not(.gap):not([href]):not([aria-current]) { display: none; }
/* Fix Safari issue related to <summary> / <details> arrow */
details > summary.list-none::-webkit-details-marker,
  details > summary.list-none::marker {
    display: none;
  }
.sortable-active-dropzone{
  border-style: dashed;
  --tw-border-opacity: 1;
  border-color: rgb(148 163 184 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
}
.sortable-active-dropzone:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.sortable-active-item{
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
  opacity: 1;
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.sortable-active-item > *{
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
  opacity: 1;
}
.sortable-active-item:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.sortable-active-item > *:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.sortable-drop-target{
  --tw-bg-opacity: 1;
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
  --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
  --tw-shadow-color: #6b7280;
  --tw-shadow: var(--tw-shadow-colored);
}
.sortable-drop-target > *{
  --tw-bg-opacity: 1;
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
  opacity: 0;
}
.sortable-drop-target:hover{
  --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.sortable-drop-target:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(15 23 42 / var(--tw-bg-opacity, 1));
  --tw-shadow-color: #000;
  --tw-shadow: var(--tw-shadow-colored);
}
.sortable-drop-target > *:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(15 23 42 / var(--tw-bg-opacity, 1));
}
.bulk-action-unavailable{
  display: none !important;
}
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.bulk-action-unavailable) {
  display: grid !important;
  grid-template-rows: subgrid !important;
  row-gap: 0 !important;
  margin-top: 0 !important;
  padding-top: 16px !important;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-action-unavailable)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-action-unavailable)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0 !important;
  padding-top: 0 !important;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).bulk-action-unavailable { display: none !important; }
.os-select--native.os-select--native select:not([hidden],.bulk-action-unavailable):has(+ .os-select-field) {
  position: relative !important;
  z-index: 1 !important;
  display: block !important;
  width: 0 !important;
  min-width: 100% !important;
  height: var(--os-select-h) !important;
  min-height: 0 !important;
  margin: 0 0 calc(-1 * var(--os-select-h)) !important;
  padding: 0 !important;
  border: 0 !important;
  opacity: 0 !important;
  cursor: pointer !important;
}
:is(.diver-cards, .os-diver-cards).bulk-action-unavailable {
  display: none !important;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).bulk-action-unavailable { display: none !important; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].bulk-action-unavailable { display: none !important; }
.bulk-actions-selectable-item-checkbox-wrapper{
  display: none;
}
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.bulk-actions-selectable-item-checkbox-wrapper) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions-selectable-item-checkbox-wrapper)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions-selectable-item-checkbox-wrapper)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).bulk-actions-selectable-item-checkbox-wrapper { display: none; }
.os-select--native.os-select--native select:not([hidden],.bulk-actions-selectable-item-checkbox-wrapper):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
:is(.diver-cards, .os-diver-cards).bulk-actions-selectable-item-checkbox-wrapper {
  display: none;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).bulk-actions-selectable-item-checkbox-wrapper { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].bulk-actions-selectable-item-checkbox-wrapper { display: none; }
.bulk-actions .bulk-actions-checkbox-cell{
  width: 1rem;
  padding-right: 0px;
}
.bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle{
  display: none;
}
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle { display: none; }
.os-select--native.os-select--native select:not([hidden],.bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
:is(.diver-cards, .os-diver-cards).bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle {
  display: none;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].bulk-actions:not(.selectable-available) .bulk-actions-selectable-toggle { display: none; }
.bulk-actions:not(.selectable) td:nth-child(2),.bulk-actions:not(.selectable) th:nth-child(2){
  padding-left: 1.25rem;
}
.bulk-actions:not(.selectable) .box-table td:nth-child(2),.bulk-actions:not(.selectable) th:nth-child(2){
  padding-left: 2rem;
}
.bulk-actions.selectable-available:not(.selectable) .bulk-action{
  display: none;
}
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-action) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-action)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-action)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).bulk-actions.selectable-available:not(.selectable) .bulk-action { display: none; }
.os-select--native.os-select--native select:not([hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-action):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
:is(.diver-cards, .os-diver-cards).bulk-actions.selectable-available:not(.selectable) .bulk-action {
  display: none;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).bulk-actions.selectable-available:not(.selectable) .bulk-action { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].bulk-actions.selectable-available:not(.selectable) .bulk-action { display: none; }
.bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell{
  display: none;
}
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell { display: none; }
.os-select--native.os-select--native select:not([hidden],.bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
:is(.diver-cards, .os-diver-cards).bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell {
  display: none;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].bulk-actions.selectable-available:not(.selectable) .bulk-actions-checkbox-cell { display: none; }
.bulk-actions.selectable .bulk-action-single{
  display: none;
}
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden],.bulk-actions.selectable .bulk-action-single) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions.selectable .bulk-action-single)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden],.bulk-actions.selectable .bulk-action-single)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).bulk-actions.selectable .bulk-action-single { display: none; }
.os-select--native.os-select--native select:not([hidden],.bulk-actions.selectable .bulk-action-single):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
:is(.diver-cards, .os-diver-cards).bulk-actions.selectable .bulk-action-single {
  display: none;
}
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).bulk-actions.selectable .bulk-action-single { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].bulk-actions.selectable .bulk-action-single { display: none; }
.date-input .single-daterange{
  border-radius: 0.375rem;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 300;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.date-input .single-daterange:focus{
  border-color: var(--primary-500);
  --tw-ring-color: var(--primary-500);
}
@media (min-width: 768px){
  .date-input .single-daterange{
    font-size: 0.875rem;
    line-height: 1.25rem;
  }
}
.daterangepicker .hourselect, .daterangepicker .minuteselect, .daterangepicker .ampmselect{
  border-radius: 0.375rem;
  font-weight: 300;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.daterangepicker .hourselect:focus, .daterangepicker .minuteselect:focus, .daterangepicker .ampmselect:focus{
  --tw-ring-color: var(--primary-500);
}
.daterangepicker .hourselect, .daterangepicker .minuteselect, .daterangepicker .ampmselect{
  --tw-border-opacity: 1 !important;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)) !important;
}
.daterangepicker .hourselect:focus, .daterangepicker .minuteselect:focus, .daterangepicker .ampmselect:focus{
  border-color: var(--primary-500) !important;
}
.daterangepicker .hourselect, .daterangepicker .minuteselect, .daterangepicker .ampmselect {
      -moz-text-align-last: center;
           text-align-last: center;
    }
.daterangepicker .calendar-table .active{
  background-color: var(--primary-500) !important;
}
.daterangepicker .calendar-table .\!active{
  background-color: var(--primary-500) !important;
}
.select2-container{
  width: 100%;
}
.select2-border{
  border-color: var(--primary-500) !important;
    box-shadow: inset 0 0 0 1px var(--primary-500) !important;
    outline: 0 !important;
}
.select2-selection--single,
  .select2-selection--multiple {
    height: 38px !important;
    --tw-border-opacity: 1;
    border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
    border-radius: 0.375rem !important;
    padding-top: 0px !important;
    --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05) !important;
    --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
  }
.select2-selection--single:focus, .select2-selection--multiple:focus{
  --tw-ring-color: var(--primary-500) !important;
}
.select2-selection--single.focus-visible, .select2-selection--multiple.focus-visible{
  border-color: var(--primary-500) !important;
    box-shadow: inset 0 0 0 1px var(--primary-500) !important;
    outline: 0 !important;
}
.select2-selection--single:focus, .select2-selection--multiple:focus {
      outline: 0 !important;
    }
.select2-selection--single .select2-selection__arrow, .select2-selection--multiple .select2-selection__arrow {
      height: 34px !important;
    }
.select2-selection--single .select2-selection__rendered, .select2-selection--multiple .select2-selection__rendered{
  padding-left: 0.75rem !important;
  --tw-text-opacity: 1 !important;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1)) !important;
      line-height: 35px !important;
}
.select2-selection--multiple .select2-selection__choice {
    margin-top: 6px !important;
    line-height: 22px !important;
  }
.select2-container--open .select2-selection--single, .select2-container--open .select2-selection--multiple, .select2-container--focus .select2-selection--single, .select2-container--focus .select2-selection--multiple{
  border-color: var(--primary-500) !important;
    box-shadow: inset 0 0 0 1px var(--primary-500) !important;
    outline: 0 !important;
}
.select2-container--default.select2-container--disabled .select2-selection--single,
  .select2-container--default.select2-container--disabled .select2-selection--multiple{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
.select2-container--default.select2-container--disabled .select2-selection--single:hover,
  .select2-container--default.select2-container--disabled .select2-selection--multiple:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
.select2-container--default.select2-container--disabled .select2-selection--single:where(.dark, .dark *),
  .select2-container--default.select2-container--disabled .select2-selection--multiple:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.select2-container--default.select2-container--disabled .select2-selection--single:where(.dark, .dark *):hover,
  .select2-container--default.select2-container--disabled .select2-selection--multiple:where(.dark, .dark *):hover{
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.select2-container .select2-dropdown{
  overflow: hidden !important;
  border-width: 2px !important;
  --tw-border-opacity: 1 !important;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1)) !important;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05) !important;
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
  border-color: var(--primary-500) !important;
}
.select2-container--default .select2-results__option[aria-selected=true]{
  background-color: var(--primary-500) !important;
  --tw-text-opacity: 1 !important;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1)) !important;
}
.select2-search__field{
  border-radius: 0.375rem;
  --tw-border-opacity: 1 !important;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1)) !important;
}
.select2-search__field:focus{
  border-color: var(--primary-500) !important;
  --tw-ring-color: var(--primary-500) !important;
}
.sr-only{
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
.pointer-events-none{
  pointer-events: none;
}
.\!visible{
  visibility: visible !important;
}
.visible{
  visibility: visible;
}
.invisible{
  visibility: hidden;
}
.collapse{
  visibility: collapse;
}
.static{
  position: static;
}
.\!fixed{
  position: fixed !important;
}
.fixed{
  position: fixed;
}
.absolute{
  position: absolute;
}
.relative{
  position: relative;
}
.sticky{
  position: sticky;
}
.inset-0{
  inset: 0px;
}
.inset-y-0{
  top: 0px;
  bottom: 0px;
}
.-top-0{
  top: -0px;
}
.bottom-0{
  bottom: 0px;
}
.bottom-1{
  bottom: 0.25rem;
}
.bottom-2{
  bottom: 0.5rem;
}
.bottom-4{
  bottom: 1rem;
}
.bottom-52{
  bottom: 13rem;
}
.bottom-\[-4px\]{
  bottom: -4px;
}
.bottom-full{
  bottom: 100%;
}
.left-0{
  left: 0px;
}
.left-10{
  left: 2.5rem;
}
.left-2\.5{
  left: 0.625rem;
}
.left-3{
  left: 0.75rem;
}
.left-\[5px\]{
  left: 5px;
}
.left-\[calc\(50\%\+20px\)\]{
  left: calc(50% + 20px);
}
.left-full{
  left: 100%;
}
.right-0{
  right: 0px;
}
.right-0\.5{
  right: 0.125rem;
}
.right-1{
  right: 0.25rem;
}
.right-10{
  right: 2.5rem;
}
.right-2{
  right: 0.5rem;
}
.top-0{
  top: 0px;
}
.top-1{
  top: 0.25rem;
}
.top-1\/2{
  top: 50%;
}
.top-2{
  top: 0.5rem;
}
.top-6{
  top: 1.5rem;
}
.top-full{
  top: 100%;
}
.z-0{
  z-index: 0;
}
.z-10{
  z-index: 10;
}
.z-20{
  z-index: 20;
}
.z-40{
  z-index: 40;
}
.z-50{
  z-index: 50;
}
.order-1{
  order: 1;
}
.order-2{
  order: 2;
}
.order-3{
  order: 3;
}
.col-span-1{
  grid-column: span 1 / span 1;
}
.col-span-12{
  grid-column: span 12 / span 12;
}
.col-span-2{
  grid-column: span 2 / span 2;
}
.col-span-3{
  grid-column: span 3 / span 3;
}
.col-span-4{
  grid-column: span 4 / span 4;
}
.col-span-5{
  grid-column: span 5 / span 5;
}
.col-span-7{
  grid-column: span 7 / span 7;
}
.float-right{
  float: right;
}
.-m-2{
  margin: -0.5rem;
}
.m-0{
  margin: 0px;
}
.m-2{
  margin: 0.5rem;
}
.m-4{
  margin: 1rem;
}
.m-5{
  margin: 1.25rem;
}
.m-auto{
  margin: auto;
}
.mx-1{
  margin-left: 0.25rem;
  margin-right: 0.25rem;
}
.mx-12{
  margin-left: 3rem;
  margin-right: 3rem;
}
.mx-2{
  margin-left: 0.5rem;
  margin-right: 0.5rem;
}
.mx-4{
  margin-left: 1rem;
  margin-right: 1rem;
}
.mx-auto{
  margin-left: auto;
  margin-right: auto;
}
.my-12{
  margin-top: 3rem;
  margin-bottom: 3rem;
}
.my-3{
  margin-top: 0.75rem;
  margin-bottom: 0.75rem;
}
.-mb-1{
  margin-bottom: -0.25rem;
}
.-mb-1\.5{
  margin-bottom: -0.375rem;
}
.-mb-2{
  margin-bottom: -0.5rem;
}
.-mb-5{
  margin-bottom: -1.25rem;
}
.-ml-1{
  margin-left: -0.25rem;
}
.-ml-10{
  margin-left: -2.5rem;
}
.-ml-5{
  margin-left: -1.25rem;
}
.-mr-2{
  margin-right: -0.5rem;
}
.-mt-0\.5{
  margin-top: -0.125rem;
}
.-mt-1{
  margin-top: -0.25rem;
}
.-mt-10{
  margin-top: -2.5rem;
}
.-mt-2{
  margin-top: -0.5rem;
}
.-mt-3{
  margin-top: -0.75rem;
}
.-mt-4{
  margin-top: -1rem;
}
.-mt-5{
  margin-top: -1.25rem;
}
.-mt-7{
  margin-top: -1.75rem;
}
.-mt-px{
  margin-top: -1px;
}
.mb-0{
  margin-bottom: 0px;
}
.mb-0\.5{
  margin-bottom: 0.125rem;
}
.mb-1{
  margin-bottom: 0.25rem;
}
.mb-1\.5{
  margin-bottom: 0.375rem;
}
.mb-10{
  margin-bottom: 2.5rem;
}
.mb-14{
  margin-bottom: 3.5rem;
}
.mb-2{
  margin-bottom: 0.5rem;
}
.mb-2\.5{
  margin-bottom: 0.625rem;
}
.mb-3{
  margin-bottom: 0.75rem;
}
.mb-4{
  margin-bottom: 1rem;
}
.mb-5{
  margin-bottom: 1.25rem;
}
.mb-6{
  margin-bottom: 1.5rem;
}
.mb-7{
  margin-bottom: 1.75rem;
}
.mb-8{
  margin-bottom: 2rem;
}
.ml-0{
  margin-left: 0px;
}
.ml-0\.5{
  margin-left: 0.125rem;
}
.ml-1{
  margin-left: 0.25rem;
}
.ml-1\.5{
  margin-left: 0.375rem;
}
.ml-10{
  margin-left: 2.5rem;
}
.ml-12{
  margin-left: 3rem;
}
.ml-2{
  margin-left: 0.5rem;
}
.ml-2\.5{
  margin-left: 0.625rem;
}
.ml-3{
  margin-left: 0.75rem;
}
.ml-4{
  margin-left: 1rem;
}
.ml-5{
  margin-left: 1.25rem;
}
.ml-auto{
  margin-left: auto;
}
.mr-0{
  margin-right: 0px;
}
.mr-0\.5{
  margin-right: 0.125rem;
}
.mr-1{
  margin-right: 0.25rem;
}
.mr-10{
  margin-right: 2.5rem;
}
.mr-12{
  margin-right: 3rem;
}
.mr-2{
  margin-right: 0.5rem;
}
.mr-3{
  margin-right: 0.75rem;
}
.mr-4{
  margin-right: 1rem;
}
.mr-auto{
  margin-right: auto;
}
.ms-2{
  margin-inline-start: 0.5rem;
}
.mt-0{
  margin-top: 0px;
}
.mt-0\.5{
  margin-top: 0.125rem;
}
.mt-1{
  margin-top: 0.25rem;
}
.mt-1\.5{
  margin-top: 0.375rem;
}
.mt-2{
  margin-top: 0.5rem;
}
.mt-3{
  margin-top: 0.75rem;
}
.mt-4{
  margin-top: 1rem;
}
.mt-5{
  margin-top: 1.25rem;
}
.mt-6{
  margin-top: 1.5rem;
}
.mt-7{
  margin-top: 1.75rem;
}
.mt-8{
  margin-top: 2rem;
}
.line-clamp-1{
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}
.block{
  display: block;
}
.inline-block{
  display: inline-block;
}
.inline{
  display: inline;
}
.flex{
  display: flex;
}
.inline-flex{
  display: inline-flex;
}
.table{
  display: table;
}
.grid{
  display: grid;
}
.contents{
  display: contents;
}
.hidden{
  display: none;
}
.size-1\.5{
  width: 0.375rem;
  height: 0.375rem;
}
.size-10{
  width: 2.5rem;
  height: 2.5rem;
}
.size-11{
  width: 2.75rem;
  height: 2.75rem;
}
.size-14{
  width: 3.5rem;
  height: 3.5rem;
}
.size-2\.5{
  width: 0.625rem;
  height: 0.625rem;
}
.size-24{
  width: 6rem;
  height: 6rem;
}
.size-3{
  width: 0.75rem;
  height: 0.75rem;
}
.size-3\.5{
  width: 0.875rem;
  height: 0.875rem;
}
.size-4{
  width: 1rem;
  height: 1rem;
}
.size-5{
  width: 1.25rem;
  height: 1.25rem;
}
.size-7{
  width: 1.75rem;
  height: 1.75rem;
}
.size-8{
  width: 2rem;
  height: 2rem;
}
.size-9{
  width: 2.25rem;
  height: 2.25rem;
}
.h-0\.5{
  height: 0.125rem;
}
.h-1{
  height: 0.25rem;
}
.h-1\.5{
  height: 0.375rem;
}
.h-10{
  height: 2.5rem;
}
.h-11{
  height: 2.75rem;
}
.h-12{
  height: 3rem;
}
.h-16{
  height: 4rem;
}
.h-2{
  height: 0.5rem;
}
.h-28{
  height: 7rem;
}
.h-3{
  height: 0.75rem;
}
.h-3\.5{
  height: 0.875rem;
}
.h-32{
  height: 8rem;
}
.h-4{
  height: 1rem;
}
.h-5{
  height: 1.25rem;
}
.h-6{
  height: 1.5rem;
}
.h-7{
  height: 1.75rem;
}
.h-72{
  height: 18rem;
}
.h-8{
  height: 2rem;
}
.h-9{
  height: 2.25rem;
}
.h-\[11px\]{
  height: 11px;
}
.h-auto{
  height: auto;
}
.h-full{
  height: 100%;
}
.max-h-12{
  max-height: 3rem;
}
.max-h-16{
  max-height: 4rem;
}
.max-h-20{
  max-height: 5rem;
}
.max-h-24{
  max-height: 6rem;
}
.max-h-40{
  max-height: 10rem;
}
.max-h-48{
  max-height: 12rem;
}
.max-h-64{
  max-height: 16rem;
}
.max-h-80{
  max-height: 20rem;
}
.max-h-\[100px\]{
  max-height: 100px;
}
.max-h-\[90vh\]{
  max-height: 90vh;
}
.max-h-\[calc\(100vh-200px\)\]{
  max-height: calc(100vh - 200px);
}
.max-h-full{
  max-height: 100%;
}
.min-h-11{
  min-height: 2.75rem;
}
.min-h-32{
  min-height: 8rem;
}
.min-h-9{
  min-height: 2.25rem;
}
.min-h-\[120px\]{
  min-height: 120px;
}
.min-h-\[44px\]{
  min-height: 44px;
}
.min-h-full{
  min-height: 100%;
}
.min-h-screen{
  min-height: 100vh;
}
.w-0{
  width: 0px;
}
.w-1\.5{
  width: 0.375rem;
}
.w-1\/2{
  width: 50%;
}
.w-1\/3{
  width: 33.333333%;
}
.w-1\/5{
  width: 20%;
}
.w-10{
  width: 2.5rem;
}
.w-11{
  width: 2.75rem;
}
.w-12{
  width: 3rem;
}
.w-14{
  width: 3.5rem;
}
.w-16{
  width: 4rem;
}
.w-2{
  width: 0.5rem;
}
.w-2\/3{
  width: 66.666667%;
}
.w-20{
  width: 5rem;
}
.w-24{
  width: 6rem;
}
.w-28{
  width: 7rem;
}
.w-3{
  width: 0.75rem;
}
.w-3\.5{
  width: 0.875rem;
}
.w-3\/4{
  width: 75%;
}
.w-32{
  width: 8rem;
}
.w-4{
  width: 1rem;
}
.w-4\/5{
  width: 80%;
}
.w-44{
  width: 11rem;
}
.w-48{
  width: 12rem;
}
.w-5{
  width: 1.25rem;
}
.w-56{
  width: 14rem;
}
.w-6{
  width: 1.5rem;
}
.w-60{
  width: 15rem;
}
.w-64{
  width: 16rem;
}
.w-7{
  width: 1.75rem;
}
.w-72{
  width: 18rem;
}
.w-8{
  width: 2rem;
}
.w-9{
  width: 2.25rem;
}
.w-\[110px\]{
  width: 110px;
}
.w-\[11px\]{
  width: 11px;
}
.w-\[120px\]{
  width: 120px;
}
.w-\[130px\]{
  width: 130px;
}
.w-\[140px\]{
  width: 140px;
}
.w-\[150px\]{
  width: 150px;
}
.w-\[160px\]{
  width: 160px;
}
.w-\[240px\]{
  width: 240px;
}
.w-\[570px\]{
  width: 570px;
}
.w-\[80px\]{
  width: 80px;
}
.w-\[88px\]{
  width: 88px;
}
.w-auto{
  width: auto;
}
.w-full{
  width: 100%;
}
.w-px{
  width: 1px;
}
.min-w-0{
  min-width: 0px;
}
.min-w-11{
  min-width: 2.75rem;
}
.min-w-40{
  min-width: 10rem;
}
.min-w-48{
  min-width: 12rem;
}
.min-w-72{
  min-width: 18rem;
}
.min-w-9{
  min-width: 2.25rem;
}
.min-w-\[180px\]{
  min-width: 180px;
}
.min-w-\[18px\]{
  min-width: 18px;
}
.min-w-\[240px\]{
  min-width: 240px;
}
.min-w-\[280px\]{
  min-width: 280px;
}
.min-w-\[60px\]{
  min-width: 60px;
}
.min-w-\[72px\]{
  min-width: 72px;
}
.min-w-full{
  min-width: 100%;
}
.min-w-max{
  min-width: -moz-max-content;
  min-width: max-content;
}
.max-w-2xl{
  max-width: 42rem;
}
.max-w-3xl{
  max-width: 48rem;
}
.max-w-4xl{
  max-width: 56rem;
}
.max-w-72{
  max-width: 18rem;
}
.max-w-\[1140px\]{
  max-width: 1140px;
}
.max-w-\[1280px\]{
  max-width: 1280px;
}
.max-w-\[160px\]{
  max-width: 160px;
}
.max-w-\[180px\]{
  max-width: 180px;
}
.max-w-\[200px\]{
  max-width: 200px;
}
.max-w-\[220px\]{
  max-width: 220px;
}
.max-w-\[280px\]{
  max-width: 280px;
}
.max-w-\[420px\]{
  max-width: 420px;
}
.max-w-\[860px\]{
  max-width: 860px;
}
.max-w-\[880px\]{
  max-width: 880px;
}
.max-w-\[9rem\]{
  max-width: 9rem;
}
.max-w-\[calc\(100vw-1\.5rem\)\]{
  max-width: calc(100vw - 1.5rem);
}
.max-w-full{
  max-width: 100%;
}
.max-w-lg{
  max-width: 32rem;
}
.max-w-md{
  max-width: 28rem;
}
.max-w-prose{
  max-width: 65ch;
}
.max-w-sm{
  max-width: 24rem;
}
.max-w-xl{
  max-width: 36rem;
}
.max-w-xs{
  max-width: 20rem;
}
.flex-1{
  flex: 1 1 0%;
}
.flex-auto{
  flex: 1 1 auto;
}
.flex-initial{
  flex: 0 1 auto;
}
.flex-none{
  flex: none;
}
.flex-shrink{
  flex-shrink: 1;
}
.flex-shrink-0{
  flex-shrink: 0;
}
.shrink{
  flex-shrink: 1;
}
.shrink-0{
  flex-shrink: 0;
}
.flex-grow{
  flex-grow: 1;
}
.grow{
  flex-grow: 1;
}
.basis-96{
  flex-basis: 24rem;
}
.border-collapse{
  border-collapse: collapse;
}
.-translate-x-20{
  --tw-translate-x: -5rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-x-full{
  --tw-translate-x: -100%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2{
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-0{
  --tw-translate-x: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-1{
  --tw-translate-x: 0.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-6{
  --tw-translate-x: 1.5rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-0{
  --tw-translate-y: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-1{
  --tw-translate-y: 0.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-5{
  --tw-translate-y: 1.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-90{
  --tw-rotate: 90deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-90{
  --tw-scale-x: .9;
  --tw-scale-y: .9;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-95{
  --tw-scale-x: .95;
  --tw-scale-y: .95;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform{
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform-none{
  transform: none;
}
@keyframes pulse{
  50%{
    opacity: .5;
  }
}
.animate-pulse{
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes spin{
  to{
    transform: rotate(360deg);
  }
}
.animate-spin{
  animation: spin 1s linear infinite;
}
.cursor-grab{
  cursor: grab;
}
.cursor-not-allowed{
  cursor: not-allowed;
}
.cursor-pointer{
  cursor: pointer;
}
.select-none{
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.select-all{
  -webkit-user-select: all;
     -moz-user-select: all;
          user-select: all;
}
.resize{
  resize: both;
}
.list-inside{
  list-style-position: inside;
}
.list-decimal{
  list-style-type: decimal;
}
.list-disc{
  list-style-type: disc;
}
.list-none{
  list-style-type: none;
}
.appearance-none{
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
}
.columns-\[var\(--column-width\2c _15ch\)_3\]{
  -moz-columns: var(--column-width, 15ch) 3;
       columns: var(--column-width, 15ch) 3;
}
.auto-rows-fr{
  grid-auto-rows: minmax(0, 1fr);
}
.grid-cols-1{
  grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-12{
  grid-template-columns: repeat(12, minmax(0, 1fr));
}
.grid-cols-2{
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-3{
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid-cols-4{
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid-cols-5{
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
.grid-cols-6{
  grid-template-columns: repeat(6, minmax(0, 1fr));
}
.grid-cols-7{
  grid-template-columns: repeat(7, minmax(0, 1fr));
}
.grid-cols-\[1\.2fr_1fr_1fr_auto\]{
  grid-template-columns: 1.2fr 1fr 1fr auto;
}
.grid-cols-\[100px_1fr_140px_140px\]{
  grid-template-columns: 100px 1fr 140px 140px;
}
.grid-cols-\[1fr_1fr_120px_44px\]{
  grid-template-columns: 1fr 1fr 120px 44px;
}
.grid-cols-\[1fr_1fr_120px_88px\]{
  grid-template-columns: 1fr 1fr 120px 88px;
}
.grid-cols-\[2fr_1fr_1fr_auto\]{
  grid-template-columns: 2fr 1fr 1fr auto;
}
.grid-cols-\[88px_1fr_auto_120px\]{
  grid-template-columns: 88px 1fr auto 120px;
}
.grid-cols-\[auto_1fr\]{
  grid-template-columns: auto 1fr;
}
.flex-row{
  flex-direction: row;
}
.flex-col{
  flex-direction: column;
}
.flex-col-reverse{
  flex-direction: column-reverse;
}
.flex-wrap{
  flex-wrap: wrap;
}
.place-content-center{
  place-content: center;
}
.items-start{
  align-items: flex-start;
}
.items-end{
  align-items: flex-end;
}
.items-center{
  align-items: center;
}
.items-baseline{
  align-items: baseline;
}
.items-stretch{
  align-items: stretch;
}
.justify-start{
  justify-content: flex-start;
}
.justify-end{
  justify-content: flex-end;
}
.justify-center{
  justify-content: center;
}
.justify-between{
  justify-content: space-between;
}
.gap-1{
  gap: 0.25rem;
}
.gap-1\.5{
  gap: 0.375rem;
}
.gap-2{
  gap: 0.5rem;
}
.gap-2\.5{
  gap: 0.625rem;
}
.gap-20{
  gap: 5rem;
}
.gap-3{
  gap: 0.75rem;
}
.gap-3\.5{
  gap: 0.875rem;
}
.gap-4{
  gap: 1rem;
}
.gap-5{
  gap: 1.25rem;
}
.gap-6{
  gap: 1.5rem;
}
.gap-px{
  gap: 1px;
}
.gap-x-3{
  -moz-column-gap: 0.75rem;
       column-gap: 0.75rem;
}
.gap-x-4{
  -moz-column-gap: 1rem;
       column-gap: 1rem;
}
.gap-x-6{
  -moz-column-gap: 1.5rem;
       column-gap: 1.5rem;
}
.gap-x-8{
  -moz-column-gap: 2rem;
       column-gap: 2rem;
}
.gap-y-1{
  row-gap: 0.25rem;
}
.gap-y-1\.5{
  row-gap: 0.375rem;
}
.gap-y-2{
  row-gap: 0.5rem;
}
.gap-y-3{
  row-gap: 0.75rem;
}
.space-x-1 > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.25rem * var(--tw-space-x-reverse));
  margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-x-3 > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-x-4 > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(1rem * var(--tw-space-x-reverse));
  margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-x-8 > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(2rem * var(--tw-space-x-reverse));
  margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-0\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.125rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.125rem * var(--tw-space-y-reverse));
}
.space-y-1 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
}
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
}
.space-y-2 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.625rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.625rem * var(--tw-space-y-reverse));
}
.space-y-3 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.space-y-5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
.space-y-6 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
}
.space-y-7 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.75rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.75rem * var(--tw-space-y-reverse));
}
.space-y-8 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(2rem * var(--tw-space-y-reverse));
}
.divide-x > :not([hidden]) ~ :not([hidden]){
  --tw-divide-x-reverse: 0;
  border-right-width: calc(1px * var(--tw-divide-x-reverse));
  border-left-width: calc(1px * calc(1 - var(--tw-divide-x-reverse)));
}
.divide-y > :not([hidden]) ~ :not([hidden]){
  --tw-divide-y-reverse: 0;
  border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
  border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
}
.divide-y-2 > :not([hidden]) ~ :not([hidden]){
  --tw-divide-y-reverse: 0;
  border-top-width: calc(2px * calc(1 - var(--tw-divide-y-reverse)));
  border-bottom-width: calc(2px * var(--tw-divide-y-reverse));
}
.divide-dashed > :not([hidden]) ~ :not([hidden]){
  border-style: dashed;
}
.divide-base-900\/5 > :not([hidden]) ~ :not([hidden]){
  border-color: rgb(15 23 42 / 0.05);
}
.divide-hairline > :not([hidden]) ~ :not([hidden]){
  border-color: var(--hairline, #E5E7EB);
}
.divide-hairline-2 > :not([hidden]) ~ :not([hidden]){
  border-color: var(--hairline-2, #F0F1F4);
}
.self-start{
  align-self: flex-start;
}
.self-center{
  align-self: center;
}
.justify-self-end{
  justify-self: end;
}
.overflow-auto{
  overflow: auto;
}
.overflow-hidden{
  overflow: hidden;
}
.overflow-visible{
  overflow: visible;
}
.overflow-x-auto{
  overflow-x: auto;
}
.overflow-y-auto{
  overflow-y: auto;
}
.overflow-y-scroll{
  overflow-y: scroll;
}
.truncate{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.whitespace-nowrap{
  white-space: nowrap;
}
.whitespace-pre-line{
  white-space: pre-line;
}
.whitespace-pre-wrap{
  white-space: pre-wrap;
}
.text-wrap{
  text-wrap: wrap;
}
.break-words{
  overflow-wrap: break-word;
}
.break-all{
  word-break: break-all;
}
.rounded{
  border-radius: 0.25rem;
}
.rounded-2xl{
  border-radius: 1rem;
}
.rounded-btn{
  border-radius: 6px;
}
.rounded-card{
  border-radius: 10px;
}
.rounded-full{
  border-radius: 9999px;
}
.rounded-lg{
  border-radius: 0.5rem;
}
.rounded-md{
  border-radius: 0.375rem;
}
.rounded-none{
  border-radius: 0px;
}
.rounded-sm{
  border-radius: 0.125rem;
}
.rounded-xl{
  border-radius: 0.75rem;
}
.rounded-b-lg{
  border-bottom-right-radius: 0.5rem;
  border-bottom-left-radius: 0.5rem;
}
.rounded-l-md{
  border-top-left-radius: 0.375rem;
  border-bottom-left-radius: 0.375rem;
}
.rounded-r-md{
  border-top-right-radius: 0.375rem;
  border-bottom-right-radius: 0.375rem;
}
.rounded-t-2xl{
  border-top-left-radius: 1rem;
  border-top-right-radius: 1rem;
}
.rounded-bl-lg{
  border-bottom-left-radius: 0.5rem;
}
.rounded-bl-none{
  border-bottom-left-radius: 0px;
}
.rounded-br-lg{
  border-bottom-right-radius: 0.5rem;
}
.rounded-br-none{
  border-bottom-right-radius: 0px;
}
.rounded-tl-lg{
  border-top-left-radius: 0.5rem;
}
.rounded-tr-lg{
  border-top-right-radius: 0.5rem;
}
.border{
  border-width: 1px;
}
.border-0{
  border-width: 0px;
}
.border-2{
  border-width: 2px;
}
.border-\[1\.5px\]{
  border-width: 1.5px;
}
.border-b{
  border-bottom-width: 1px;
}
.border-b-2{
  border-bottom-width: 2px;
}
.border-l{
  border-left-width: 1px;
}
.border-l-2{
  border-left-width: 2px;
}
.border-l-4{
  border-left-width: 4px;
}
.border-r{
  border-right-width: 1px;
}
.border-r-2{
  border-right-width: 2px;
}
.border-t{
  border-top-width: 1px;
}
.border-t-2{
  border-top-width: 2px;
}
.border-t-4{
  border-top-width: 4px;
}
.border-solid{
  border-style: solid;
}
.border-dashed{
  border-style: dashed;
}
.border-none{
  border-style: none;
}
.\!border-hairline{
  border-color: var(--hairline, #E5E7EB) !important;
}
.border-accent{
  border-color: var(--accent, #0369A1);
}
.border-accent-border{
  border-color: var(--accent-border, rgba(3,105,161,0.26));
}
.border-accent-strong{
  border-color: var(--accent-strong, #075985);
}
.border-amber-200{
  --tw-border-opacity: 1;
  border-color: rgb(253 230 138 / var(--tw-border-opacity, 1));
}
.border-base-200{
  --tw-border-opacity: 1;
  border-color: rgb(226 232 240 / var(--tw-border-opacity, 1));
}
.border-base-300{
  --tw-border-opacity: 1;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
}
.border-base-400{
  --tw-border-opacity: 1;
  border-color: rgb(148 163 184 / var(--tw-border-opacity, 1));
}
.border-base-900{
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
}
.border-blue-200{
  --tw-border-opacity: 1;
  border-color: rgb(191 219 254 / var(--tw-border-opacity, 1));
}
.border-blue-700{
  --tw-border-opacity: 1;
  border-color: rgb(29 78 216 / var(--tw-border-opacity, 1));
}
.border-briefing-border{
  border-color: var(--briefing-border, #FCD34D);
}
.border-cancelled-border{
  border-color: var(--cancelled-border, #FECDD3);
}
.border-confirmed-border{
  border-color: var(--confirmed-border, #BBF7D0);
}
.border-gray-200{
  --tw-border-opacity: 1;
  border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
}
.border-gray-300{
  --tw-border-opacity: 1;
  border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
}
.border-green-800{
  --tw-border-opacity: 1;
  border-color: rgb(22 101 52 / var(--tw-border-opacity, 1));
}
.border-hairline{
  border-color: var(--hairline, #E5E7EB);
}
.border-hairline-2{
  border-color: var(--hairline-2, #F0F1F4);
}
.border-hairline-strong{
  border-color: var(--hairline-strong, #D1D5DB);
}
.border-indigo-300{
  --tw-border-opacity: 1;
  border-color: rgb(165 180 252 / var(--tw-border-opacity, 1));
}
.border-muted-2{
  border-color: var(--muted-2, #9CA3AF);
}
.border-pending-border{
  border-color: var(--pending-border, #D6D3D1);
}
.border-primary-300{
  border-color: var(--primary-300);
}
.border-primary-500{
  border-color: var(--primary-500);
}
.border-primary-600{
  border-color: var(--primary-600);
}
.border-red-200{
  --tw-border-opacity: 1;
  border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));
}
.border-red-500{
  --tw-border-opacity: 1;
  border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
}
.border-slate-100{
  --tw-border-opacity: 1;
  border-color: rgb(241 245 249 / var(--tw-border-opacity, 1));
}
.border-slate-200{
  --tw-border-opacity: 1;
  border-color: rgb(226 232 240 / var(--tw-border-opacity, 1));
}
.border-slate-300{
  --tw-border-opacity: 1;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
}
.border-transparent{
  border-color: transparent;
}
.border-white{
  --tw-border-opacity: 1;
  border-color: rgb(255 255 255 / var(--tw-border-opacity, 1));
}
.border-white\/40{
  border-color: rgb(255 255 255 / 0.4);
}
.border-l-accent{
  border-left-color: var(--accent, #0369A1);
}
.border-l-briefing{
  border-left-color: var(--briefing, #92400E);
}
.border-l-cancelled{
  border-left-color: var(--cancelled, #9F1239);
}
.border-l-confirmed{
  border-left-color: var(--confirmed, #15803D);
}
.border-l-hairline-strong{
  border-left-color: var(--hairline-strong, #D1D5DB);
}
.border-l-primary-500{
  border-left-color: var(--primary-500);
}
.bg-\[color\:--code-editor-background\]{
  background-color: var(--code-editor-background);
}
.bg-\[var\(--accent-light\)\]{
  background-color: var(--accent-light);
}
.bg-accent{
  background-color: var(--accent, #0369A1);
}
.bg-accent-light{
  background-color: var(--accent-light, #E0F2FE);
}
.bg-accent-soft{
  background-color: var(--accent-soft, rgba(3,105,161,0.08));
}
.bg-accent-strong{
  background-color: var(--accent-strong, #075985);
}
.bg-amber-100{
  --tw-bg-opacity: 1;
  background-color: rgb(254 243 199 / var(--tw-bg-opacity, 1));
}
.bg-amber-300{
  --tw-bg-opacity: 1;
  background-color: rgb(252 211 77 / var(--tw-bg-opacity, 1));
}
.bg-base-100{
  --tw-bg-opacity: 1;
  background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1));
}
.bg-base-200{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
.bg-base-300{
  --tw-bg-opacity: 1;
  background-color: rgb(203 213 225 / var(--tw-bg-opacity, 1));
}
.bg-base-50{
  --tw-bg-opacity: 1;
  background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1));
}
.bg-base-800{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.bg-black\/40{
  background-color: rgb(0 0 0 / 0.4);
}
.bg-black\/50{
  background-color: rgb(0 0 0 / 0.5);
}
.bg-blue-100{
  --tw-bg-opacity: 1;
  background-color: rgb(219 234 254 / var(--tw-bg-opacity, 1));
}
.bg-blue-300{
  --tw-bg-opacity: 1;
  background-color: rgb(147 197 253 / var(--tw-bg-opacity, 1));
}
.bg-blue-400{
  --tw-bg-opacity: 1;
  background-color: rgb(96 165 250 / var(--tw-bg-opacity, 1));
}
.bg-blue-50{
  --tw-bg-opacity: 1;
  background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1));
}
.bg-blue-500{
  --tw-bg-opacity: 1;
  background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
}
.bg-blue-600{
  --tw-bg-opacity: 1;
  background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
}
.bg-blue-700{
  --tw-bg-opacity: 1;
  background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
}
.bg-briefing{
  background-color: var(--briefing, #92400E);
}
.bg-briefing-bg{
  background-color: var(--briefing-bg, #FFFBEB);
}
.bg-cancelled{
  background-color: var(--cancelled, #9F1239);
}
.bg-cancelled-bg{
  background-color: var(--cancelled-bg, #FFF1F2);
}
.bg-canvas{
  background-color: var(--canvas, #F9FAFB);
}
.bg-confirmed{
  background-color: var(--confirmed, #15803D);
}
.bg-confirmed-bg{
  background-color: var(--confirmed-bg, #F0FDF4);
}
.bg-current{
  background-color: currentColor;
}
.bg-emerald-100{
  --tw-bg-opacity: 1;
  background-color: rgb(209 250 229 / var(--tw-bg-opacity, 1));
}
.bg-gray-100{
  --tw-bg-opacity: 1;
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.bg-gray-200{
  --tw-bg-opacity: 1;
  background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
}
.bg-gray-300{
  --tw-bg-opacity: 1;
  background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));
}
.bg-gray-50{
  --tw-bg-opacity: 1;
  background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
}
.bg-green-100{
  --tw-bg-opacity: 1;
  background-color: rgb(220 252 231 / var(--tw-bg-opacity, 1));
}
.bg-green-300{
  --tw-bg-opacity: 1;
  background-color: rgb(134 239 172 / var(--tw-bg-opacity, 1));
}
.bg-green-500{
  --tw-bg-opacity: 1;
  background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
}
.bg-hairline{
  background-color: var(--hairline, #E5E7EB);
}
.bg-inwater-bg{
  background-color: var(--inwater-bg, #F0F9FF);
}
.bg-muted-2{
  background-color: var(--muted-2, #9CA3AF);
}
.bg-pending-bg{
  background-color: var(--pending-bg, #F5F5F4);
}
.bg-primary-200{
  background-color: var(--primary-200);
}
.bg-primary-400{
  background-color: var(--primary-400);
}
.bg-primary-500{
  background-color: var(--primary-500);
}
.bg-primary-600{
  background-color: var(--primary-600);
}
.bg-primary-700{
  background-color: var(--primary-700);
}
.bg-primary-900{
  background-color: var(--primary-900);
}
.bg-red-100{
  --tw-bg-opacity: 1;
  background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1));
}
.bg-red-500{
  --tw-bg-opacity: 1;
  background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
}
.bg-rose-100{
  --tw-bg-opacity: 1;
  background-color: rgb(255 228 230 / var(--tw-bg-opacity, 1));
}
.bg-rose-300{
  --tw-bg-opacity: 1;
  background-color: rgb(253 164 175 / var(--tw-bg-opacity, 1));
}
.bg-sky-300{
  --tw-bg-opacity: 1;
  background-color: rgb(125 211 252 / var(--tw-bg-opacity, 1));
}
.bg-slate-100{
  --tw-bg-opacity: 1;
  background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1));
}
.bg-slate-50{
  --tw-bg-opacity: 1;
  background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1));
}
.bg-slate-900\/60{
  background-color: rgb(15 23 42 / 0.6);
}
.bg-stone-300{
  --tw-bg-opacity: 1;
  background-color: rgb(214 211 209 / var(--tw-bg-opacity, 1));
}
.bg-surface{
  background-color: var(--surface, #FFFFFF);
}
.bg-surface-alt{
  background-color: var(--surface-alt, #F3F4F6);
}
.bg-transparent{
  background-color: transparent;
}
.bg-viz-5{
  background-color: var(--viz-5, #38BDF8);
}
.bg-white{
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
}
.bg-gradient-to-b{
  background-image: linear-gradient(to bottom, var(--tw-gradient-stops));
}
.bg-gradient-to-br{
  background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
}
.bg-gradient-to-r{
  background-image: linear-gradient(to right, var(--tw-gradient-stops));
}
.from-accent{
  --tw-gradient-from: var(--accent, #0369A1) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-primary-500{
  --tw-gradient-from: var(--primary-500) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-primary-700{
  --tw-gradient-from: var(--primary-700) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-primary-900{
  --tw-gradient-from: var(--primary-900) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-secondary-200{
  --tw-gradient-from: var(--secondary-200) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-white{
  --tw-gradient-from: #fff var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.to-accent-strong{
  --tw-gradient-to: var(--accent-strong, #075985) var(--tw-gradient-to-position);
}
.to-primary-400{
  --tw-gradient-to: var(--primary-400) var(--tw-gradient-to-position);
}
.to-primary-600{
  --tw-gradient-to: var(--primary-600) var(--tw-gradient-to-position);
}
.to-primary-800{
  --tw-gradient-to: var(--primary-800) var(--tw-gradient-to-position);
}
.fill-current{
  fill: currentColor;
}
.stroke-current{
  stroke: currentColor;
}
.object-contain{
  -o-object-fit: contain;
     object-fit: contain;
}
.object-cover{
  -o-object-fit: cover;
     object-fit: cover;
}
.p-0{
  padding: 0px;
}
.p-0\.5{
  padding: 0.125rem;
}
.p-1{
  padding: 0.25rem;
}
.p-1\.5{
  padding: 0.375rem;
}
.p-12{
  padding: 3rem;
}
.p-2{
  padding: 0.5rem;
}
.p-2\.5{
  padding: 0.625rem;
}
.p-3{
  padding: 0.75rem;
}
.p-3\.5{
  padding: 0.875rem;
}
.p-4{
  padding: 1rem;
}
.p-5{
  padding: 1.25rem;
}
.p-6{
  padding: 1.5rem;
}
.p-8{
  padding: 2rem;
}
.p-9{
  padding: 2.25rem;
}
.px-0{
  padding-left: 0px;
  padding-right: 0px;
}
.px-1{
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}
.px-1\.5{
  padding-left: 0.375rem;
  padding-right: 0.375rem;
}
.px-10{
  padding-left: 2.5rem;
  padding-right: 2.5rem;
}
.px-14{
  padding-left: 3.5rem;
  padding-right: 3.5rem;
}
.px-2{
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}
.px-2\.5{
  padding-left: 0.625rem;
  padding-right: 0.625rem;
}
.px-3{
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}
.px-3\.5{
  padding-left: 0.875rem;
  padding-right: 0.875rem;
}
.px-4{
  padding-left: 1rem;
  padding-right: 1rem;
}
.px-5{
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.px-6{
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.px-7{
  padding-left: 1.75rem;
  padding-right: 1.75rem;
}
.px-8{
  padding-left: 2rem;
  padding-right: 2rem;
}
.py-0\.5{
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
}
.py-1{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
.py-1\.5{
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
}
.py-10{
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}
.py-12{
  padding-top: 3rem;
  padding-bottom: 3rem;
}
.py-16{
  padding-top: 4rem;
  padding-bottom: 4rem;
}
.py-2{
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.py-2\.5{
  padding-top: 0.625rem;
  padding-bottom: 0.625rem;
}
.py-3{
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}
.py-3\.5{
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
}
.py-4{
  padding-top: 1rem;
  padding-bottom: 1rem;
}
.py-5{
  padding-top: 1.25rem;
  padding-bottom: 1.25rem;
}
.py-6{
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}
.py-7{
  padding-top: 1.75rem;
  padding-bottom: 1.75rem;
}
.py-8{
  padding-top: 2rem;
  padding-bottom: 2rem;
}
.pb-0\.5{
  padding-bottom: 0.125rem;
}
.pb-1{
  padding-bottom: 0.25rem;
}
.pb-10{
  padding-bottom: 2.5rem;
}
.pb-2{
  padding-bottom: 0.5rem;
}
.pb-3{
  padding-bottom: 0.75rem;
}
.pb-3\.5{
  padding-bottom: 0.875rem;
}
.pb-4{
  padding-bottom: 1rem;
}
.pb-5{
  padding-bottom: 1.25rem;
}
.pb-6{
  padding-bottom: 1.5rem;
}
.pb-7{
  padding-bottom: 1.75rem;
}
.pb-\[max\(1\.25rem\2c env\(safe-area-inset-bottom\)\)\]{
  padding-bottom: max(1.25rem, env(safe-area-inset-bottom));
}
.pb-\[max\(1rem\2c env\(safe-area-inset-bottom\)\)\]{
  padding-bottom: max(1rem, env(safe-area-inset-bottom));
}
.pl-0{
  padding-left: 0px;
}
.pl-1{
  padding-left: 0.25rem;
}
.pl-2{
  padding-left: 0.5rem;
}
.pl-3{
  padding-left: 0.75rem;
}
.pl-4{
  padding-left: 1rem;
}
.pl-5{
  padding-left: 1.25rem;
}
.pl-6{
  padding-left: 1.5rem;
}
.pl-7{
  padding-left: 1.75rem;
}
.pl-8{
  padding-left: 2rem;
}
.pl-9{
  padding-left: 2.25rem;
}
.pr-0{
  padding-right: 0px;
}
.pr-1{
  padding-right: 0.25rem;
}
.pr-10{
  padding-right: 2.5rem;
}
.pr-2{
  padding-right: 0.5rem;
}
.pr-20{
  padding-right: 5rem;
}
.pr-3{
  padding-right: 0.75rem;
}
.pr-3\.5{
  padding-right: 0.875rem;
}
.pr-4{
  padding-right: 1rem;
}
.pr-5{
  padding-right: 1.25rem;
}
.pr-8{
  padding-right: 2rem;
}
.pt-0{
  padding-top: 0px;
}
.pt-1{
  padding-top: 0.25rem;
}
.pt-1\.5{
  padding-top: 0.375rem;
}
.pt-10{
  padding-top: 2.5rem;
}
.pt-2{
  padding-top: 0.5rem;
}
.pt-3{
  padding-top: 0.75rem;
}
.pt-3\.5{
  padding-top: 0.875rem;
}
.pt-4{
  padding-top: 1rem;
}
.pt-5{
  padding-top: 1.25rem;
}
.pt-6{
  padding-top: 1.5rem;
}
.pt-7{
  padding-top: 1.75rem;
}
.pt-8{
  padding-top: 2rem;
}
.text-left{
  text-align: left;
}
.text-center{
  text-align: center;
}
.text-right{
  text-align: right;
}
.align-middle{
  vertical-align: middle;
}
.align-text-bottom{
  vertical-align: text-bottom;
}
.align-\[-2px\]{
  vertical-align: -2px;
}
.font-mono{
  font-family: 'Geist Mono', ui-monospace, monospace;
}
.font-sans{
  font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
.text-2xl{
  font-size: 1.5rem;
  line-height: 2rem;
}
.text-2xs{
  font-size: var(--text-2xs);
  line-height: 0.9rem;
  letter-spacing: 1px;
}
.text-3xl{
  font-size: var(--text-3xl);
  line-height: 2.25rem;
}
.text-6xl{
  font-size: 3.75rem;
  line-height: 1;
}
.text-\[10px\]{
  font-size: 10px;
}
.text-\[11px\]{
  font-size: 11px;
}
.text-\[12px\]{
  font-size: 12px;
}
.text-\[13\.5px\]{
  font-size: 13.5px;
}
.text-base{
  font-size: 1rem;
  line-height: 1.5rem;
}
.text-lg{
  font-size: 1.125rem;
  line-height: 1.75rem;
}
.text-sm{
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.text-xl{
  font-size: 1.25rem;
  line-height: 1.75rem;
}
.text-xs{
  font-size: var(--text-xs);
}
.font-bold{
  font-weight: 700;
}
.font-extralight{
  font-weight: 200;
}
.font-light{
  font-weight: 300;
}
.font-medium{
  font-weight: 500;
}
.font-normal{
  font-weight: 400;
}
.font-semibold{
  font-weight: 600;
}
.uppercase{
  text-transform: uppercase;
}
.lowercase{
  text-transform: lowercase;
}
.capitalize{
  text-transform: capitalize;
}
.italic{
  font-style: italic;
}
.tabular-nums{
  --tw-numeric-spacing: tabular-nums;
  font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);
}
.leading-4{
  line-height: 1rem;
}
.leading-5{
  line-height: 1.25rem;
}
.leading-6{
  line-height: 1.5rem;
}
.leading-none{
  line-height: 1;
}
.leading-normal{
  line-height: 1.5;
}
.leading-relaxed{
  line-height: 1.625;
}
.leading-snug{
  line-height: 1.375;
}
.leading-tight{
  line-height: 1.25;
}
.tracking-\[0\.08em\]{
  letter-spacing: 0.08em;
}
.tracking-tight{
  letter-spacing: -0.025em;
}
.tracking-wide{
  letter-spacing: 0.025em;
}
.tracking-wider{
  letter-spacing: 0.05em;
}
.tracking-widest{
  letter-spacing: 0.1em;
}
.text-accent{
  color: var(--accent, #0369A1);
}
.text-accent-strong{
  color: var(--accent-strong, #075985);
}
.text-amber-700{
  --tw-text-opacity: 1;
  color: rgb(180 83 9 / var(--tw-text-opacity, 1));
}
.text-amber-800{
  --tw-text-opacity: 1;
  color: rgb(146 64 14 / var(--tw-text-opacity, 1));
}
.text-base-300{
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.text-base-400{
  --tw-text-opacity: 1;
  color: rgb(148 163 184 / var(--tw-text-opacity, 1));
}
.text-base-50{
  --tw-text-opacity: 1;
  color: rgb(248 250 252 / var(--tw-text-opacity, 1));
}
.text-base-500{
  --tw-text-opacity: 1;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1));
}
.text-base-600{
  --tw-text-opacity: 1;
  color: rgb(71 85 105 / var(--tw-text-opacity, 1));
}
.text-base-700{
  --tw-text-opacity: 1;
  color: rgb(51 65 85 / var(--tw-text-opacity, 1));
}
.text-base-800{
  --tw-text-opacity: 1;
  color: rgb(30 41 59 / var(--tw-text-opacity, 1));
}
.text-black{
  --tw-text-opacity: 1;
  color: rgb(0 0 0 / var(--tw-text-opacity, 1));
}
.text-blue-400{
  --tw-text-opacity: 1;
  color: rgb(96 165 250 / var(--tw-text-opacity, 1));
}
.text-blue-600{
  --tw-text-opacity: 1;
  color: rgb(37 99 235 / var(--tw-text-opacity, 1));
}
.text-blue-700{
  --tw-text-opacity: 1;
  color: rgb(29 78 216 / var(--tw-text-opacity, 1));
}
.text-blue-800{
  --tw-text-opacity: 1;
  color: rgb(30 64 175 / var(--tw-text-opacity, 1));
}
.text-briefing{
  color: var(--briefing, #92400E);
}
.text-cancelled{
  color: var(--cancelled, #9F1239);
}
.text-confirmed{
  color: var(--confirmed, #15803D);
}
.text-emerald-700{
  --tw-text-opacity: 1;
  color: rgb(4 120 87 / var(--tw-text-opacity, 1));
}
.text-gray-300{
  --tw-text-opacity: 1;
  color: rgb(209 213 219 / var(--tw-text-opacity, 1));
}
.text-gray-400{
  --tw-text-opacity: 1;
  color: rgb(156 163 175 / var(--tw-text-opacity, 1));
}
.text-gray-500{
  --tw-text-opacity: 1;
  color: rgb(107 114 128 / var(--tw-text-opacity, 1));
}
.text-gray-600{
  --tw-text-opacity: 1;
  color: rgb(75 85 99 / var(--tw-text-opacity, 1));
}
.text-gray-700{
  --tw-text-opacity: 1;
  color: rgb(55 65 81 / var(--tw-text-opacity, 1));
}
.text-gray-800{
  --tw-text-opacity: 1;
  color: rgb(31 41 55 / var(--tw-text-opacity, 1));
}
.text-gray-900{
  --tw-text-opacity: 1;
  color: rgb(17 24 39 / var(--tw-text-opacity, 1));
}
.text-green-500{
  --tw-text-opacity: 1;
  color: rgb(34 197 94 / var(--tw-text-opacity, 1));
}
.text-green-600{
  --tw-text-opacity: 1;
  color: rgb(22 163 74 / var(--tw-text-opacity, 1));
}
.text-green-800{
  --tw-text-opacity: 1;
  color: rgb(22 101 52 / var(--tw-text-opacity, 1));
}
.text-hairline{
  color: var(--hairline, #E5E7EB);
}
.text-ink{
  color: var(--ink, #111827);
}
.text-inwater{
  color: var(--inwater, #075985);
}
.text-muted{
  color: var(--muted, #6B7280);
}
.text-muted-2{
  color: var(--muted-2, #9CA3AF);
}
.text-pending{
  color: var(--pending, #57534E);
}
.text-pink-600{
  --tw-text-opacity: 1;
  color: rgb(219 39 119 / var(--tw-text-opacity, 1));
}
.text-primary-400{
  color: var(--primary-400);
}
.text-primary-500{
  color: var(--primary-500);
}
.text-red-500{
  --tw-text-opacity: 1;
  color: rgb(239 68 68 / var(--tw-text-opacity, 1));
}
.text-red-600{
  --tw-text-opacity: 1;
  color: rgb(220 38 38 / var(--tw-text-opacity, 1));
}
.text-red-700{
  --tw-text-opacity: 1;
  color: rgb(185 28 28 / var(--tw-text-opacity, 1));
}
.text-red-900{
  --tw-text-opacity: 1;
  color: rgb(127 29 29 / var(--tw-text-opacity, 1));
}
.text-rose-700{
  --tw-text-opacity: 1;
  color: rgb(190 18 60 / var(--tw-text-opacity, 1));
}
.text-secondary-300{
  color: var(--secondary-300);
}
.text-secondary-500{
  color: var(--secondary-500);
}
.text-secondary-700{
  color: var(--secondary-700);
}
.text-slate-400{
  --tw-text-opacity: 1;
  color: rgb(148 163 184 / var(--tw-text-opacity, 1));
}
.text-slate-500{
  --tw-text-opacity: 1;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1));
}
.text-slate-600{
  --tw-text-opacity: 1;
  color: rgb(71 85 105 / var(--tw-text-opacity, 1));
}
.text-slate-700{
  --tw-text-opacity: 1;
  color: rgb(51 65 85 / var(--tw-text-opacity, 1));
}
.text-slate-900{
  --tw-text-opacity: 1;
  color: rgb(15 23 42 / var(--tw-text-opacity, 1));
}
.text-viz-ink{
  color: var(--viz-ink, #075985);
}
.text-white{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.underline{
  text-decoration-line: underline;
}
.line-through{
  text-decoration-line: line-through;
}
.no-underline{
  text-decoration-line: none;
}
.decoration-hairline{
  text-decoration-color: var(--hairline, #E5E7EB);
}
.antialiased{
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.placeholder-muted-2::-moz-placeholder{
  color: var(--muted-2, #9CA3AF);
}
.placeholder-muted-2::placeholder{
  color: var(--muted-2, #9CA3AF);
}
.placeholder-red-500::-moz-placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(239 68 68 / var(--tw-placeholder-opacity, 1));
}
.placeholder-red-500::placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(239 68 68 / var(--tw-placeholder-opacity, 1));
}
.accent-accent{
  accent-color: var(--accent, #0369A1);
}
.opacity-0{
  opacity: 0;
}
.opacity-100{
  opacity: 1;
}
.opacity-20{
  opacity: 0.2;
}
.opacity-30{
  opacity: 0.3;
}
.opacity-40{
  opacity: 0.4;
}
.opacity-50{
  opacity: 0.5;
}
.opacity-60{
  opacity: 0.6;
}
.opacity-70{
  opacity: 0.7;
}
.opacity-75{
  opacity: 0.75;
}
.shadow{
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-2xl{
  --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
  --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-card{
  --tw-shadow: 0 1px 2px rgba(17,24,39,0.04), 0 0 0 1px var(--hairline, #E5E7EB);
  --tw-shadow-colored: 0 1px 2px var(--tw-shadow-color), 0 0 0 1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-inner{
  --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-lg{
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-md{
  --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-sm{
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-xl{
  --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-base-900{
  --tw-shadow-color: #0f172a;
  --tw-shadow: var(--tw-shadow-colored);
}
.shadow-gray-500{
  --tw-shadow-color: #6b7280;
  --tw-shadow: var(--tw-shadow-colored);
}
.outline-none{
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.outline{
  outline-style: solid;
}
.outline-1{
  outline-width: 1px;
}
.-outline-offset-1{
  outline-offset: -1px;
}
.outline-gray-300{
  outline-color: #d1d5db;
}
.outline-hairline-strong{
  outline-color: var(--hairline-strong, #D1D5DB);
}
.ring{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-1{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-2{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-inset{
  --tw-ring-inset: inset;
}
.ring-accent{
  --tw-ring-color: var(--accent, #0369A1);
}
.ring-accent-border{
  --tw-ring-color: var(--accent-border, rgba(3,105,161,0.26));
}
.ring-accent-soft{
  --tw-ring-color: var(--accent-soft, rgba(3,105,161,0.08));
}
.ring-blue-600{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(37 99 235 / var(--tw-ring-opacity, 1));
}
.ring-cancelled{
  --tw-ring-color: var(--cancelled, #9F1239);
}
.ring-cancelled-border{
  --tw-ring-color: var(--cancelled-border, #FECDD3);
}
.ring-confirmed{
  --tw-ring-color: var(--confirmed, #15803D);
}
.ring-confirmed-border{
  --tw-ring-color: var(--confirmed-border, #BBF7D0);
}
.ring-hairline{
  --tw-ring-color: var(--hairline, #E5E7EB);
}
.ring-hairline-strong{
  --tw-ring-color: var(--hairline-strong, #D1D5DB);
}
.ring-primary-500{
  --tw-ring-color: var(--primary-500);
}
.ring-sky-200{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(186 230 253 / var(--tw-ring-opacity, 1));
}
.ring-white{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity, 1));
}
.ring-offset-1{
  --tw-ring-offset-width: 1px;
}
.ring-offset-2{
  --tw-ring-offset-width: 2px;
}
.blur{
  --tw-blur: blur(8px);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.grayscale{
  --tw-grayscale: grayscale(100%);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.invert{
  --tw-invert: invert(100%);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.filter{
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.backdrop-blur-sm{
  --tw-backdrop-blur: blur(4px);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.backdrop-filter{
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.transition{
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-all{
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-colors{
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-opacity{
  transition-property: opacity;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-transform{
  transition-property: transform;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.duration-1000{
  transition-duration: 1000ms;
}
.duration-150{
  transition-duration: 150ms;
}
.duration-200{
  transition-duration: 200ms;
}
.duration-300{
  transition-duration: 300ms;
}
.duration-500{
  transition-duration: 500ms;
}
.ease-in-out{
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.ease-linear{
  transition-timing-function: linear;
}
.ease-out{
  transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.background-fade-container {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 100vw;
    max-width: 100vw;
    overflow: hidden;
    z-index: -1;
  }
.background-fade:before {
      content: "";
      position: absolute;
      z-index: 1;
      background-color: var(--primary-200);
      background-image: linear-gradient(to right, var(--tw-gradient-stops));
      --tw-gradient-from: #fff var(--tw-gradient-from-position);
      --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
      --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}
.background-fade{

    position: absolute;
    top: 0px;
    transform: translate(-360px, 0px) rotate(-45deg);
    z-index: -1;
    background-color: var(--primary-400);
    background-image: linear-gradient(to right, var(--tw-gradient-stops));
    --tw-gradient-from: #fff var(--tw-gradient-from-position);
    --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
    --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.medium-fade:before {
      right: -40px;
      top: -200px;
      width: 1000px;
      height: 600px;
    }
.medium-fade{

    right: -800px;
    width: 800px;
    height: 600px;
}
.large-fade:before {
      right: -0px;
      top: -200px;
      width: 1500px;
      height: 800px;
    }
.large-fade{

    right: -700px;
    width: 1000px;
    height: 800px;
}
.pricing-table-shadow {
    box-shadow: 0 2px 30px 0 rgba(54,88,206,0.2);
  }
.pricing-page-background {
    background-image: linear-gradient(to bottom, #f8faff, #fff);
  }
.brand-title {
    color: #047bf8;
    font-size: 2.99rem;
    margin: 30px 0px;
    margin-top: 10px;
    position: relative;
    letter-spacing: -0.025em;
    line-height: 120%;
    font-weight: 700;
  }
.brand-description {
    color: #868686;
    font-size: 1.2rem;
    line-height: 1.5;
    font-weight: 200;
  }
.text-light-gradient {
    -webkit-background-clip: text;
    -webkit-box-decoration-break: clone;
    -webkit-font-smoothing: subpixel-antialiased;
    -webkit-text-fill-color: rgba(0,0,0,0);
    background-attachment: scroll;
    background-clip: text;
    background-color: rgba(0,0,0,0);
    --tw-bg-opacity: 1;
    background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
    background-image: linear-gradient(to right, var(--tw-gradient-stops));
    --tw-gradient-from: var(--primary-500) var(--tw-gradient-from-position);
    --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
    --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}
.reveal {
    transition-property: opacity, transform;
    --tw-translate-y: 1.25rem;
    transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
    opacity: 0;
    transition-timing-function: cubic-bezier(0, 0, 0.2, 1)}
.reveal-from-left{
  --tw-translate-y: 0px;
  --tw-translate-x: -5rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.reveal.in{
  transform: none;
  opacity: 1;
  transition-duration: 1000ms;
}
.space-y > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
.space-x > :not([hidden]) ~ :not([hidden]){
  --tw-space-x-reverse: 0;
  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
}
.gap-y{
  row-gap: 1.25rem;
}
.gap-x{
  -moz-column-gap: 1rem;
       column-gap: 1rem;
}
[hidden] {
    display: none !important;
  }
/**
     * Custom components
     **/
/* Color picker */
.dark .pcr-app{
  border-width: 1px;
  border-style: solid;
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.dark .pcr-app .pcr-interaction .pcr-result{
  border-width: 1px;
  border-style: solid;
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.dark .pcr-app .pcr-interaction .pcr-result:focus {
          box-shadow: 0 0 0 1px var(--primary-500), 0 0 0 3px var(--primary-500);
        }
/* Date range picker */
.dark .daterangepicker{
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.dark .daterangepicker::before {
        border-bottom-color: #0f172a;
      }
.dark .daterangepicker::after {
        border-bottom-color: #1e293b;
      }
.dark .daterangepicker .calendar-table{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
/* navigation arrows */
.dark .daterangepicker .calendar-table .available span{
  border-color: var(--primary-500);
}
/* Clear and Apply buttons wrapper */
.dark .daterangepicker .drp-buttons {
        border-top-color: #0f172a;
        --tw-text-opacity: 1;
        color: rgb(203 213 225 / var(--tw-text-opacity, 1));
      }
.dark .daterangepicker th.available:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(71 85 105 / var(--tw-bg-opacity, 1));
}
.dark .daterangepicker td.off{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.dark .daterangepicker td.available:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(71 85 105 / var(--tw-bg-opacity, 1));
}
.dark .daterangepicker .hourselect, .dark .daterangepicker .minuteselect, .dark .daterangepicker .ampmselect{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
  --tw-text-opacity: 1 !important;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1)) !important;
}
/* Phone field */
.dark .iti__country-list{
  border-width: 1px;
  border-style: solid;
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
/* Select2 */
.dark .select2-container .select2-selection__rendered{
  --tw-text-opacity: 1 !important;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1)) !important;
}
.dark .select2-container .select2-dropdown{
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.dark .select2-container .select2-search__field{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.dark .select2-container .select2-selection--multiple, .dark .select2-container .select2-selection--single{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.dark .select2-container .select2-selection--multiple:focus, .dark .select2-container .select2-selection--single:focus{
  --tw-ring-color: var(--primary-500) !important;
}
.dark .select2-container .select2-selection--multiple, .dark .select2-container .select2-selection--single{
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
/* For the selected options in the multiple select2 component */
.dark .select2-container .select2-selection__choice{
  border-color: var(--primary-500) !important;
  background-color: var(--primary-500) !important;
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.dark .select2-container .select2-selection__choice .select2-selection__choice__remove{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.dark .select2-container .select2-selection__choice .select2-selection__choice__remove:hover{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.dark .select2-container .select2-results__option{
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
/* Trix Editor */
.dark trix-editor{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.dark trix-editor:focus, .dark trix-editor:active{
  border-color: var(--primary-500) !important;
}
.dark trix-toolbar{
  opacity: 0.5 !important;
}
.dark trix-toolbar.visible{
  opacity: 1 !important;
}
.dark trix-toolbar.\!visible{
  opacity: 1 !important;
}
.dark trix-toolbar .trix-button-group, .dark trix-toolbar .trix-button{
  --tw-border-opacity: 1 !important;
  border-color: rgb(148 163 184 / var(--tw-border-opacity, 1)) !important;
}
.dark trix-toolbar .trix-button:disabled::before{
  opacity: 0.25;
}
.dark trix-toolbar .trix-dialog{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1) !important;
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
  --tw-shadow-color: #0f172a !important;
  --tw-shadow: var(--tw-shadow-colored) !important;
}
.dark trix-toolbar .trix-dialog .trix-button--dialog{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.dark trix-toolbar .trix-dialog .trix-input--dialog{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.dark trix-toolbar .trix-dialog .trix-input--dialog:focus{
  border-color: var(--primary-500);
  --tw-ring-color: var(--primary-500);
}
.dark trix-toolbar .trix-dialog .trix-input--dialog:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.dark .tribute-container ul{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.dark .trix-dialogs{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.dark .trix-content a[href^="bullettrain://"]{
  --tw-bg-opacity: 1;
  background-color: rgb(100 116 139 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
/* CKEditor */
.dark .ck {
      --ck-color-base-background: #1e293b;
      --ck-color-base-border: #0f172a;
      --ck-color-toolbar-background: #1e293b;
      --ck-color-toolbar-border: #0f172a;
      --ck-color-text: #cbd5e1;
    }
.dark .ck .ck-editor__editable:not(.ck-editor__nested-editable){
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.dark .ck .ck-editor__editable:not(.ck-editor__nested-editable).ck-focused{
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.\[--code-editor-background\:theme\(\'colors\.base\.50\'\)\]{
  --code-editor-background: #f8fafc;
}
/* 
 * Refer to the stimulus-scroll-reveal documentation for details.
 * https://www.stimulus-components.com/docs/stimulus-scroll-reveal/
 */
:root, .theme-blue {
  --primary-50: #eff6ff;
  --primary-100: #dbeafe;
  --primary-200: #bfdbfe;
  --primary-300: #93c5fd;
  --primary-400: #60a5fa;
  --primary-500: #3b82f6;
  --primary-600: #2563eb;
  --primary-700: #1d4ed8;
  --primary-800: #1e40af;
  --primary-900: #1e3a8a;

  --secondary-50: #eff6ff;
  --secondary-100: #dbeafe;
  --secondary-200: #bfdbfe;
  --secondary-300: #93c5fd;
  --secondary-400: #60a5fa;
  --secondary-500: #3b82f6;
  --secondary-600: #2563eb;
  --secondary-700: #1d4ed8;
  --secondary-800: #1e40af;
  --secondary-900: #1e3a8a;
}
.theme-slate {
  --primary-50: #f8fafc;
  --primary-100: #f1f5f9;
  --primary-200: #e2e8f0;
  --primary-300: #cbd5e1;
  --primary-400: #94a3b8;
  --primary-500: #64748b;
  --primary-600: #475569;
  --primary-700: #334155;
  --primary-800: #1e293b;
  --primary-900: #0f172a;

  --secondary-50: #f8fafc;
  --secondary-100: #f1f5f9;
  --secondary-200: #e2e8f0;
  --secondary-300: #cbd5e1;
  --secondary-400: #94a3b8;
  --secondary-500: #64748b;
  --secondary-600: #475569;
  --secondary-700: #334155;
  --secondary-800: #1e293b;
  --secondary-900: #0f172a;
}
.theme-gray {
  --primary-50: #f8fafc;
  --primary-100: #f1f5f9;
  --primary-200: #e2e8f0;
  --primary-300: #cbd5e1;
  --primary-400: #94a3b8;
  --primary-500: #64748b;
  --primary-600: #475569;
  --primary-700: #334155;
  --primary-800: #1e293b;
  --primary-900: #0f172a;

  --secondary-50: #f8fafc;
  --secondary-100: #f1f5f9;
  --secondary-200: #e2e8f0;
  --secondary-300: #cbd5e1;
  --secondary-400: #94a3b8;
  --secondary-500: #64748b;
  --secondary-600: #475569;
  --secondary-700: #334155;
  --secondary-800: #1e293b;
  --secondary-900: #0f172a;
}
.theme-zinc {
  --primary-50: #fafafa;
  --primary-100: #f4f4f5;
  --primary-200: #e4e4e7;
  --primary-300: #d4d4d8;
  --primary-400: #a1a1aa;
  --primary-500: #71717a;
  --primary-600: #52525b;
  --primary-700: #3f3f46;
  --primary-800: #27272a;
  --primary-900: #18181b;

  --secondary-50: #fafafa;
  --secondary-100: #f4f4f5;
  --secondary-200: #e4e4e7;
  --secondary-300: #d4d4d8;
  --secondary-400: #a1a1aa;
  --secondary-500: #71717a;
  --secondary-600: #52525b;
  --secondary-700: #3f3f46;
  --secondary-800: #27272a;
  --secondary-900: #18181b;
}
.theme-neutral {
  --primary-50: #fafafa;
  --primary-100: #f5f5f5;
  --primary-200: #e5e5e5;
  --primary-300: #d4d4d4;
  --primary-400: #a3a3a3;
  --primary-500: #737373;
  --primary-600: #525252;
  --primary-700: #404040;
  --primary-800: #262626;
  --primary-900: #171717;

  --secondary-50: #fafafa;
  --secondary-100: #f5f5f5;
  --secondary-200: #e5e5e5;
  --secondary-300: #d4d4d4;
  --secondary-400: #a3a3a3;
  --secondary-500: #737373;
  --secondary-600: #525252;
  --secondary-700: #404040;
  --secondary-800: #262626;
  --secondary-900: #171717;
}
.theme-stone {
  --primary-50: #fafaf9;
  --primary-100: #f5f5f4;
  --primary-200: #e7e5e4;
  --primary-300: #d6d3d1;
  --primary-400: #a8a29e;
  --primary-500: #78716c;
  --primary-600: #57534e;
  --primary-700: #44403c;
  --primary-800: #292524;
  --primary-900: #1c1917;

  --secondary-50: #fafaf9;
  --secondary-100: #f5f5f4;
  --secondary-200: #e7e5e4;
  --secondary-300: #d6d3d1;
  --secondary-400: #a8a29e;
  --secondary-500: #78716c;
  --secondary-600: #57534e;
  --secondary-700: #44403c;
  --secondary-800: #292524;
  --secondary-900: #1c1917;
}
.theme-red {
  --primary-50: #fef2f2;
  --primary-100: #fee2e2;
  --primary-200: #fecaca;
  --primary-300: #fca5a5;
  --primary-400: #f87171;
  --primary-500: #ef4444;
  --primary-600: #dc2626;
  --primary-700: #b91c1c;
  --primary-800: #991b1b;
  --primary-900: #7f1d1d;

  --secondary-50: #fef2f2;
  --secondary-100: #fee2e2;
  --secondary-200: #fecaca;
  --secondary-300: #fca5a5;
  --secondary-400: #f87171;
  --secondary-500: #ef4444;
  --secondary-600: #dc2626;
  --secondary-700: #b91c1c;
  --secondary-800: #991b1b;
  --secondary-900: #7f1d1d;
}
.theme-orange {
  --primary-50: #fff7ed;
  --primary-100: #ffedd5;
  --primary-200: #fed7aa;
  --primary-300: #fdba74;
  --primary-400: #fb923c;
  --primary-500: #f97316;
  --primary-600: #ea580c;
  --primary-700: #c2410c;
  --primary-800: #9a3412;
  --primary-900: #7c2d12;

  --secondary-50: #fff7ed;
  --secondary-100: #ffedd5;
  --secondary-200: #fed7aa;
  --secondary-300: #fdba74;
  --secondary-400: #fb923c;
  --secondary-500: #f97316;
  --secondary-600: #ea580c;
  --secondary-700: #c2410c;
  --secondary-800: #9a3412;
  --secondary-900: #7c2d12;
}
.theme-amber {
  --primary-50: #fffbeb;
  --primary-100: #fef3c7;
  --primary-200: #fde68a;
  --primary-300: #fcd34d;
  --primary-400: #fbbf24;
  --primary-500: #f59e0b;
  --primary-600: #d97706;
  --primary-700: #b45309;
  --primary-800: #92400e;
  --primary-900: #78350f;

  --secondary-50: #fffbeb;
  --secondary-100: #fef3c7;
  --secondary-200: #fde68a;
  --secondary-300: #fcd34d;
  --secondary-400: #fbbf24;
  --secondary-500: #f59e0b;
  --secondary-600: #d97706;
  --secondary-700: #b45309;
  --secondary-800: #92400e;
  --secondary-900: #78350f;
}
.theme-yellow {
  --primary-50: #fefce8;
  --primary-100: #fef9c3;
  --primary-200: #fef08a;
  --primary-300: #fde047;
  --primary-400: #facc15;
  --primary-500: #eab308;
  --primary-600: #ca8a04;
  --primary-700: #a16207;
  --primary-800: #854d0e;
  --primary-900: #713f12;

  --secondary-50: #fefce8;
  --secondary-100: #fef9c3;
  --secondary-200: #fef08a;
  --secondary-300: #fde047;
  --secondary-400: #facc15;
  --secondary-500: #eab308;
  --secondary-600: #ca8a04;
  --secondary-700: #a16207;
  --secondary-800: #854d0e;
  --secondary-900: #713f12;
}
.theme-lime {
  --primary-50: #f7fee7;
  --primary-100: #ecfccb;
  --primary-200: #d9f99d;
  --primary-300: #bef264;
  --primary-400: #a3e635;
  --primary-500: #84cc16;
  --primary-600: #65a30d;
  --primary-700: #4d7c0f;
  --primary-800: #3f6212;
  --primary-900: #365314;

  --secondary-50: #f7fee7;
  --secondary-100: #ecfccb;
  --secondary-200: #d9f99d;
  --secondary-300: #bef264;
  --secondary-400: #a3e635;
  --secondary-500: #84cc16;
  --secondary-600: #65a30d;
  --secondary-700: #4d7c0f;
  --secondary-800: #3f6212;
  --secondary-900: #365314;
}
.theme-green {
  --primary-50: #f0fdf4;
  --primary-100: #dcfce7;
  --primary-200: #bbf7d0;
  --primary-300: #86efac;
  --primary-400: #4ade80;
  --primary-500: #22c55e;
  --primary-600: #16a34a;
  --primary-700: #15803d;
  --primary-800: #166534;
  --primary-900: #14532d;

  --secondary-50: #f0fdf4;
  --secondary-100: #dcfce7;
  --secondary-200: #bbf7d0;
  --secondary-300: #86efac;
  --secondary-400: #4ade80;
  --secondary-500: #22c55e;
  --secondary-600: #16a34a;
  --secondary-700: #15803d;
  --secondary-800: #166534;
  --secondary-900: #14532d;
}
.theme-emerald {
  --primary-50: #ecfdf5;
  --primary-100: #d1fae5;
  --primary-200: #a7f3d0;
  --primary-300: #6ee7b7;
  --primary-400: #34d399;
  --primary-500: #10b981;
  --primary-600: #059669;
  --primary-700: #047857;
  --primary-800: #065f46;
  --primary-900: #064e3b;

  --secondary-50: #ecfdf5;
  --secondary-100: #d1fae5;
  --secondary-200: #a7f3d0;
  --secondary-300: #6ee7b7;
  --secondary-400: #34d399;
  --secondary-500: #10b981;
  --secondary-600: #059669;
  --secondary-700: #047857;
  --secondary-800: #065f46;
  --secondary-900: #064e3b;
}
.theme-teal {
  --primary-50: #f0fdfa;
  --primary-100: #ccfbf1;
  --primary-200: #99f6e4;
  --primary-300: #5eead4;
  --primary-400: #2dd4bf;
  --primary-500: #14b8a6;
  --primary-600: #0d9488;
  --primary-700: #0f766e;
  --primary-800: #115e59;
  --primary-900: #134e4a;

  --secondary-50: #f0fdfa;
  --secondary-100: #ccfbf1;
  --secondary-200: #99f6e4;
  --secondary-300: #5eead4;
  --secondary-400: #2dd4bf;
  --secondary-500: #14b8a6;
  --secondary-600: #0d9488;
  --secondary-700: #0f766e;
  --secondary-800: #115e59;
  --secondary-900: #134e4a;
}
.theme-cyan {
  --primary-50: #ecfeff;
  --primary-100: #cffafe;
  --primary-200: #a5f3fc;
  --primary-300: #67e8f9;
  --primary-400: #22d3ee;
  --primary-500: #06b6d4;
  --primary-600: #0891b2;
  --primary-700: #0e7490;
  --primary-800: #155e75;
  --primary-900: #164e63;

  --secondary-50: #ecfeff;
  --secondary-100: #cffafe;
  --secondary-200: #a5f3fc;
  --secondary-300: #67e8f9;
  --secondary-400: #22d3ee;
  --secondary-500: #06b6d4;
  --secondary-600: #0891b2;
  --secondary-700: #0e7490;
  --secondary-800: #155e75;
  --secondary-900: #164e63;
}
.theme-sky {
  --primary-50: #f0f9ff;
  --primary-100: #e0f2fe;
  --primary-200: #bae6fd;
  --primary-300: #7dd3fc;
  --primary-400: #38bdf8;
  --primary-500: #0ea5e9;
  --primary-600: #0284c7;
  --primary-700: #0369a1;
  --primary-800: #075985;
  --primary-900: #0c4a6e;

  --secondary-50: #f0f9ff;
  --secondary-100: #e0f2fe;
  --secondary-200: #bae6fd;
  --secondary-300: #7dd3fc;
  --secondary-400: #38bdf8;
  --secondary-500: #0ea5e9;
  --secondary-600: #0284c7;
  --secondary-700: #0369a1;
  --secondary-800: #075985;
  --secondary-900: #0c4a6e;
}
.theme-indigo {
  --primary-50: #eef2ff;
  --primary-100: #e0e7ff;
  --primary-200: #c7d2fe;
  --primary-300: #a5b4fc;
  --primary-400: #818cf8;
  --primary-500: #6366f1;
  --primary-600: #4f46e5;
  --primary-700: #4338ca;
  --primary-800: #3730a3;
  --primary-900: #312e81;

  --secondary-50: #eef2ff;
  --secondary-100: #e0e7ff;
  --secondary-200: #c7d2fe;
  --secondary-300: #a5b4fc;
  --secondary-400: #818cf8;
  --secondary-500: #6366f1;
  --secondary-600: #4f46e5;
  --secondary-700: #4338ca;
  --secondary-800: #3730a3;
  --secondary-900: #312e81;
}
.theme-violet {
  --primary-50: #f5f3ff;
  --primary-100: #ede9fe;
  --primary-200: #ddd6fe;
  --primary-300: #c4b5fd;
  --primary-400: #a78bfa;
  --primary-500: #8b5cf6;
  --primary-600: #7c3aed;
  --primary-700: #6d28d9;
  --primary-800: #5b21b6;
  --primary-900: #4c1d95;

  --secondary-50: #f5f3ff;
  --secondary-100: #ede9fe;
  --secondary-200: #ddd6fe;
  --secondary-300: #c4b5fd;
  --secondary-400: #a78bfa;
  --secondary-500: #8b5cf6;
  --secondary-600: #7c3aed;
  --secondary-700: #6d28d9;
  --secondary-800: #5b21b6;
  --secondary-900: #4c1d95;
}
.theme-purple {
  --primary-50: #faf5ff;
  --primary-100: #f3e8ff;
  --primary-200: #e9d5ff;
  --primary-300: #d8b4fe;
  --primary-400: #c084fc;
  --primary-500: #a855f7;
  --primary-600: #9333ea;
  --primary-700: #7e22ce;
  --primary-800: #6b21a8;
  --primary-900: #581c87;

  --secondary-50: #faf5ff;
  --secondary-100: #f3e8ff;
  --secondary-200: #e9d5ff;
  --secondary-300: #d8b4fe;
  --secondary-400: #c084fc;
  --secondary-500: #a855f7;
  --secondary-600: #9333ea;
  --secondary-700: #7e22ce;
  --secondary-800: #6b21a8;
  --secondary-900: #581c87;
}
.theme-fuchsia {
  --primary-50: #fdf4ff;
  --primary-100: #fae8ff;
  --primary-200: #f5d0fe;
  --primary-300: #f0abfc;
  --primary-400: #e879f9;
  --primary-500: #d946ef;
  --primary-600: #c026d3;
  --primary-700: #a21caf;
  --primary-800: #86198f;
  --primary-900: #701a75;

  --secondary-50: #fdf4ff;
  --secondary-100: #fae8ff;
  --secondary-200: #f5d0fe;
  --secondary-300: #f0abfc;
  --secondary-400: #e879f9;
  --secondary-500: #d946ef;
  --secondary-600: #c026d3;
  --secondary-700: #a21caf;
  --secondary-800: #86198f;
  --secondary-900: #701a75;
}
.theme-pink {
  --primary-50: #fdf2f8;
  --primary-100: #fce7f3;
  --primary-200: #fbcfe8;
  --primary-300: #f9a8d4;
  --primary-400: #f472b6;
  --primary-500: #ec4899;
  --primary-600: #db2777;
  --primary-700: #be185d;
  --primary-800: #9d174d;
  --primary-900: #831843;

  --secondary-50: #fdf2f8;
  --secondary-100: #fce7f3;
  --secondary-200: #fbcfe8;
  --secondary-300: #f9a8d4;
  --secondary-400: #f472b6;
  --secondary-500: #ec4899;
  --secondary-600: #db2777;
  --secondary-700: #be185d;
  --secondary-800: #9d174d;
  --secondary-900: #831843;
}
.theme-rose {
  --primary-50: #fff1f2;
  --primary-100: #ffe4e6;
  --primary-200: #fecdd3;
  --primary-300: #fda4af;
  --primary-400: #fb7185;
  --primary-500: #f43f5e;
  --primary-600: #e11d48;
  --primary-700: #be123c;
  --primary-800: #9f1239;
  --primary-900: #881337;

  --secondary-50: #fff1f2;
  --secondary-100: #ffe4e6;
  --secondary-200: #fecdd3;
  --secondary-300: #fda4af;
  --secondary-400: #fb7185;
  --secondary-500: #f43f5e;
  --secondary-600: #e11d48;
  --secondary-700: #be123c;
  --secondary-800: #9f1239;
  --secondary-900: #881337;
}
.theme-secondary-blue {
  --secondary-50: #eff6ff;
  --secondary-100: #dbeafe;
  --secondary-200: #bfdbfe;
  --secondary-300: #93c5fd;
  --secondary-400: #60a5fa;
  --secondary-500: #3b82f6;
  --secondary-600: #2563eb;
  --secondary-700: #1d4ed8;
  --secondary-800: #1e40af;
  --secondary-900: #1e3a8a;
}
.theme-secondary-slate {
  --secondary-50: #f8fafc;
  --secondary-100: #f1f5f9;
  --secondary-200: #e2e8f0;
  --secondary-300: #cbd5e1;
  --secondary-400: #94a3b8;
  --secondary-500: #64748b;
  --secondary-600: #475569;
  --secondary-700: #334155;
  --secondary-800: #1e293b;
  --secondary-900: #0f172a;
}
.theme-secondary-gray {
  --secondary-50: #f8fafc;
  --secondary-100: #f1f5f9;
  --secondary-200: #e2e8f0;
  --secondary-300: #cbd5e1;
  --secondary-400: #94a3b8;
  --secondary-500: #64748b;
  --secondary-600: #475569;
  --secondary-700: #334155;
  --secondary-800: #1e293b;
  --secondary-900: #0f172a;
}
.theme-secondary-zinc {
  --secondary-50: #fafafa;
  --secondary-100: #f4f4f5;
  --secondary-200: #e4e4e7;
  --secondary-300: #d4d4d8;
  --secondary-400: #a1a1aa;
  --secondary-500: #71717a;
  --secondary-600: #52525b;
  --secondary-700: #3f3f46;
  --secondary-800: #27272a;
  --secondary-900: #18181b;
}
.theme-secondary-neutral {
  --secondary-50: #fafafa;
  --secondary-100: #f5f5f5;
  --secondary-200: #e5e5e5;
  --secondary-300: #d4d4d4;
  --secondary-400: #a3a3a3;
  --secondary-500: #737373;
  --secondary-600: #525252;
  --secondary-700: #404040;
  --secondary-800: #262626;
  --secondary-900: #171717;
}
.theme-secondary-stone {
  --secondary-50: #fafaf9;
  --secondary-100: #f5f5f4;
  --secondary-200: #e7e5e4;
  --secondary-300: #d6d3d1;
  --secondary-400: #a8a29e;
  --secondary-500: #78716c;
  --secondary-600: #57534e;
  --secondary-700: #44403c;
  --secondary-800: #292524;
  --secondary-900: #1c1917;
}
.theme-secondary-red {
  --secondary-50: #fef2f2;
  --secondary-100: #fee2e2;
  --secondary-200: #fecaca;
  --secondary-300: #fca5a5;
  --secondary-400: #f87171;
  --secondary-500: #ef4444;
  --secondary-600: #dc2626;
  --secondary-700: #b91c1c;
  --secondary-800: #991b1b;
  --secondary-900: #7f1d1d;
}
.theme-secondary-orange {
  --secondary-50: #fff7ed;
  --secondary-100: #ffedd5;
  --secondary-200: #fed7aa;
  --secondary-300: #fdba74;
  --secondary-400: #fb923c;
  --secondary-500: #f97316;
  --secondary-600: #ea580c;
  --secondary-700: #c2410c;
  --secondary-800: #9a3412;
  --secondary-900: #7c2d12;
}
.theme-secondary-amber {
  --secondary-50: #fffbeb;
  --secondary-100: #fef3c7;
  --secondary-200: #fde68a;
  --secondary-300: #fcd34d;
  --secondary-400: #fbbf24;
  --secondary-500: #f59e0b;
  --secondary-600: #d97706;
  --secondary-700: #b45309;
  --secondary-800: #92400e;
  --secondary-900: #78350f;
}
.theme-secondary-yellow {
  --secondary-50: #fefce8;
  --secondary-100: #fef9c3;
  --secondary-200: #fef08a;
  --secondary-300: #fde047;
  --secondary-400: #facc15;
  --secondary-500: #eab308;
  --secondary-600: #ca8a04;
  --secondary-700: #a16207;
  --secondary-800: #854d0e;
  --secondary-900: #713f12;
}
.theme-secondary-lime {
  --secondary-50: #f7fee7;
  --secondary-100: #ecfccb;
  --secondary-200: #d9f99d;
  --secondary-300: #bef264;
  --secondary-400: #a3e635;
  --secondary-500: #84cc16;
  --secondary-600: #65a30d;
  --secondary-700: #4d7c0f;
  --secondary-800: #3f6212;
  --secondary-900: #365314;
}
.theme-secondary-green {
  --secondary-50: #f0fdf4;
  --secondary-100: #dcfce7;
  --secondary-200: #bbf7d0;
  --secondary-300: #86efac;
  --secondary-400: #4ade80;
  --secondary-500: #22c55e;
  --secondary-600: #16a34a;
  --secondary-700: #15803d;
  --secondary-800: #166534;
  --secondary-900: #14532d;
}
.theme-secondary-emerald {
  --secondary-50: #ecfdf5;
  --secondary-100: #d1fae5;
  --secondary-200: #a7f3d0;
  --secondary-300: #6ee7b7;
  --secondary-400: #34d399;
  --secondary-500: #10b981;
  --secondary-600: #059669;
  --secondary-700: #047857;
  --secondary-800: #065f46;
  --secondary-900: #064e3b;
}
.theme-secondary-teal {
  --secondary-50: #f0fdfa;
  --secondary-100: #ccfbf1;
  --secondary-200: #99f6e4;
  --secondary-300: #5eead4;
  --secondary-400: #2dd4bf;
  --secondary-500: #14b8a6;
  --secondary-600: #0d9488;
  --secondary-700: #0f766e;
  --secondary-800: #115e59;
  --secondary-900: #134e4a;
}
.theme-secondary-cyan {
  --secondary-50: #ecfeff;
  --secondary-100: #cffafe;
  --secondary-200: #a5f3fc;
  --secondary-300: #67e8f9;
  --secondary-400: #22d3ee;
  --secondary-500: #06b6d4;
  --secondary-600: #0891b2;
  --secondary-700: #0e7490;
  --secondary-800: #155e75;
  --secondary-900: #164e63;
}
.theme-secondary-sky {
  --secondary-50: #f0f9ff;
  --secondary-100: #e0f2fe;
  --secondary-200: #bae6fd;
  --secondary-300: #7dd3fc;
  --secondary-400: #38bdf8;
  --secondary-500: #0ea5e9;
  --secondary-600: #0284c7;
  --secondary-700: #0369a1;
  --secondary-800: #075985;
  --secondary-900: #0c4a6e;
}
.theme-secondary-indigo {
  --secondary-50: #eef2ff;
  --secondary-100: #e0e7ff;
  --secondary-200: #c7d2fe;
  --secondary-300: #a5b4fc;
  --secondary-400: #818cf8;
  --secondary-500: #6366f1;
  --secondary-600: #4f46e5;
  --secondary-700: #4338ca;
  --secondary-800: #3730a3;
  --secondary-900: #312e81;
}
.theme-secondary-violet {
  --secondary-50: #f5f3ff;
  --secondary-100: #ede9fe;
  --secondary-200: #ddd6fe;
  --secondary-300: #c4b5fd;
  --secondary-400: #a78bfa;
  --secondary-500: #8b5cf6;
  --secondary-600: #7c3aed;
  --secondary-700: #6d28d9;
  --secondary-800: #5b21b6;
  --secondary-900: #4c1d95;
}
.theme-secondary-purple {
  --secondary-50: #faf5ff;
  --secondary-100: #f3e8ff;
  --secondary-200: #e9d5ff;
  --secondary-300: #d8b4fe;
  --secondary-400: #c084fc;
  --secondary-500: #a855f7;
  --secondary-600: #9333ea;
  --secondary-700: #7e22ce;
  --secondary-800: #6b21a8;
  --secondary-900: #581c87;
}
.theme-secondary-fuchsia {
  --secondary-50: #fdf4ff;
  --secondary-100: #fae8ff;
  --secondary-200: #f5d0fe;
  --secondary-300: #f0abfc;
  --secondary-400: #e879f9;
  --secondary-500: #d946ef;
  --secondary-600: #c026d3;
  --secondary-700: #a21caf;
  --secondary-800: #86198f;
  --secondary-900: #701a75;
}
.theme-secondary-pink {
  --secondary-50: #fdf2f8;
  --secondary-100: #fce7f3;
  --secondary-200: #fbcfe8;
  --secondary-300: #f9a8d4;
  --secondary-400: #f472b6;
  --secondary-500: #ec4899;
  --secondary-600: #db2777;
  --secondary-700: #be185d;
  --secondary-800: #9d174d;
  --secondary-900: #831843;
}
.theme-secondary-rose {
  --secondary-50: #fff1f2;
  --secondary-100: #ffe4e6;
  --secondary-200: #fecdd3;
  --secondary-300: #fda4af;
  --secondary-400: #fb7185;
  --secondary-500: #f43f5e;
  --secondary-600: #e11d48;
  --secondary-700: #be123c;
  --secondary-800: #9f1239;
  --secondary-900: #881337;
}
/* Import Electron utilities shared across all Tailwind-based themes. */
/* @import "../tailwind/electron.scss"; */
.electron a, .todesktop a {
    outline-color: var(--tw-ring-color);
    /* TODO: Will --tw-ring-opacity still be available in tailwindcss v4? */
    --tw-ring-opacity: 1;
    --tw-ring-color: rgba(3, 98, 198, var(--tw-ring-opacity));
  }
.electron .electron-mobile-only, .todesktop .electron-mobile-only{
  display: block;
}
:is(.wz-adddate, .os-wz-adddate):is(.electron .electron-mobile-only, .os-block),:is(.wz-adddate, .os-wz-adddate):is( .todesktop .electron-mobile-only, .os-block) { display: block; }
:is(.wz-adddate, .os-wz-adddate):is(.electron .electron-mobile-only, .os-block) :is(.wz-adddate-btn, .os-wz-adddate-btn),:is(.wz-adddate, .os-wz-adddate):is( .todesktop .electron-mobile-only, .os-block) :is(.wz-adddate-btn, .os-wz-adddate-btn) { width: 100%; justify-content: center; height: 42px; border-radius: var(--radius-sm); font-size: var(--text-sm); }
:is(.wz-adddate, .os-wz-adddate):is(.electron .electron-mobile-only, .os-block) :is(.wz-menu, .os-wz-menu),:is(.wz-adddate, .os-wz-adddate):is( .todesktop .electron-mobile-only, .os-block) :is(.wz-menu, .os-wz-menu) { width: 100%; }
@media (min-width: 1024px){
  .electron .electron-mobile-only, .todesktop .electron-mobile-only{
    display: none;
  }
}
.electron .electron-title-bar, .todesktop .electron-title-bar {
    /* override `md:rounded-lg` */
    border-top-left-radius: 0;
  }
/* hide logo because it doesn't fit into the ui well. */
.electron .electron-title-bar img, .todesktop .electron-title-bar img { display: none; }
.electron .electron-title-bar, .todesktop .electron-title-bar{

    min-height: 36px;
}
.electron .main-container-padding, .todesktop .main-container-padding {
    padding: 0;
  }
.electron .main-container, .todesktop .main-container {
    /* override `md:rounded-lg` */
    border-top-right-radius: 0;
    border-top-left-radius: 0;
    border-bottom-right-radius: 0;
    border-bottom-left-radius: 0;

    /* override `md:h-auto` */
    height: 100vh;
  }
/* hide profiler results because they don't fit into the ui well. */
.electron .profiler-results, .todesktop .profiler-results { display: none; }
/* touch up the padding of the breadcrumbs. */
.electron ol.breadcrumb, .todesktop ol.breadcrumb { padding-top: 3px; }
/*
 * This takes care of the window's contents shifting when the
 * scrollbar appears and disappears during the turn.css animation
 */
/* Chrome, Safari and Opera */
.devise_layout::-webkit-scrollbar {
  display: none;
}
/* Firefox and Edge */
.devise_layout {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.cloudinary-field button.upload {
    margin: 0;
    border-radius: 4px;
    padding: 0;
    border: 2px solid #dde2ec;
    background: transparent;
    position: relative;
    min-height: 50px;
    min-width: 50px;
  }
.cloudinary-field button.upload:not(.present) {
      min-height: 100px;
      min-width: 100px;
    }
.cloudinary-field button.upload i {
      display: block;
      text-align: center;
      vertical-align: middle;
      position: absolute;
      line-height: 50px;
      width: 50px;
      height: 50px;
      margin-left: -25px;
      margin-top: -25px;
      top: 50%;
      left: 50%;
      font-size: 32px;
      color: #dde2ec;
    }
.cloudinary-field button.upload + button.clear {
      display: none;
      font-size: 32px;
      color: #dde2ec;
      background: transparent;
      border: 0;
      overflow: visible;
    }
.cloudinary-field button.upload + button.clear:focus i, .cloudinary-field button.upload + button.clear:active i {
          color: var(--primary-500);
        }
.cloudinary-field button.upload.present i {
        display: none;
      }
.cloudinary-field button.upload.present + button.clear {
        display: inline-block;
      }
.cloudinary-field button.upload:focus, .cloudinary-field button.upload:active {
      border-color: var(--primary-500);
    }
.cloudinary-field button.upload:focus i, .cloudinary-field button.upload:active i {
        color: var(--primary-500);
      }
input[type=tel] {
  line-height: 21px;
}
input[type=tel]::-moz-placeholder {
    color: #9ca3af;
  }
input[type=tel]::placeholder {
    color: #9ca3af;
  }
.select2-container--default .select2-selection--single,
  .select2-container--default .select2-selection--multiple{
  --tw-border-opacity: 1;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
}
.select2-selection.select2-selection--single,
.select2-selection.select2-selection--multiple {
  min-height: 37px;
}
.select2-selection.select2-selection--single .select2-selection__rendered, .select2-selection.select2-selection--multiple .select2-selection__rendered {
    padding-left: 12px;
    min-height: 34px;
    line-height: 34px;
  }
.select2-selection.select2-selection--single .select2-selection__arrow, .select2-selection.select2-selection--multiple .select2-selection__arrow {
    padding-top: 35px;
  }
.select2-container .select2-search--inline .select2-search__field {
  font-weight: 300;
  margin-top: 6px;
  font-size: 1rem;
  line-height: 1.5rem;
}
@media (min-width: 768px){
  .select2-container .select2-search--inline .select2-search__field{
    font-size: 0.875rem;
    line-height: 1.25rem;
  }
}
.select2 {
  display: block;
}
.select2 img {
    display: none;
  }
.select2-results img {
    height: 30px;
    width: 30px;
    border-radius: 15px;
    margin-right: 8px;
  }
.select2-results__option--highlighted{
  background-color: var(--primary-400) !important;
}
.trix-content .attachment-gallery > action-text-attachment,
    .trix-content .attachment-gallery > .attachment {
      flex: 1 0 33%;
      padding: 0 0.5em;
      max-width: 33%;
    }
.trix-content .attachment-gallery.attachment-gallery--2 > action-text-attachment,
      .trix-content .attachment-gallery.attachment-gallery--2 > .attachment,
      .trix-content .attachment-gallery.attachment-gallery--4 > action-text-attachment,
      .trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
        flex-basis: 50%;
        max-width: 50%;
      }
/* Override Tailwind's preflight styles */
/* https://github.com/tailwindlabs/tailwindcss/issues/989#issuecomment-506555308 */
.trix-content ul {
    list-style-type: disc;
  }
.trix-content ol {
    list-style-type: decimal;
  }
.trix-content action-text-attachment .attachment {
      padding: 0 !important;
      max-width: 100% !important;
    }
/* don't show the editor tool bar unless the user is editing the field. */
/* see https://github.com/basecamp/trix/issues/343 and `app/assets/javascripts/account/fields.js` */
trix-toolbar {
  opacity: 0.15;
}
trix-toolbar.visible {
    opacity: 1;
  }
/* Override Tailwind's preflight styles */
/* https://github.com/tailwindlabs/tailwindcss/issues/989#issuecomment-506555308 */
.trix-button:where(.dark, .dark *){
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
/* Prevent red ring on Trix Editor */
:-moz-focusring {
  outline-style: none;
}
a[href^="bullettrain://"], span.tribute-reference {
  border-radius: 4px;
  display: inline-block;
  box-sizing: border-box;
  padding: 0 4px;
  margin: -1px 0;
  color: #3E4B5B;
  line-height: 17px;
  text-decoration: none;
  background-color: #ebe2ff;
  border: 1px solid #7147d2;
}
a[href^="bullettrain://users"], a[href^="bullettrain://teams"], span.tribute-users-reference, span.tribute-teams-reference {
  background-color: #e2ebff;
  border: 1px solid #4771d2;
}
.tribute-container ul {
    border-radius: 5px;
    overflow: hidden;
    box-sizing: border-box;
    border: 2px solid var(--primary-500);
    background: white;
    list-style: none;
    padding: 0;
  }
.tribute-container ul:empty {
      display: none;
    }
.tribute-container ul li{
  display: flex;
  align-items: center;
}
.tribute-container ul li span {
        font-weight: normal;
      }
.tribute-container ul li.highlight {
        background-color: #5897fb;
        color: white;
      }
.tribute-container ul li{
      padding: 5px 10px;
}
.tribute-container ul li img {
        height: 30px;
        width: 30px;
        border-radius: 15px;
        margin-right: 5px;
      }
trix-editor [data-trix-cursor-target] {
  display: none !important;
  height: 0 !important;
  width: 0 !important;
  /* background-color: red; */
}
.trix-editor * {
    box-sizing: border-box;
  }
trix-editor {
  padding-right: 0.75rem;
  padding-left: 0.75rem;
  border-radius: 0.375rem;
  --tw-border-opacity: 1;
  border-color: rgb(203 213 225 / var(--tw-border-opacity, 1));
  font-weight: 300;
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
trix-editor:focus, trix-editor:active {
    border-color: var(--primary-500);
    box-shadow: inset 0 0 0 1px var(--primary-500);
  }
trix-editor[disabled]{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
trix-editor[disabled]:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
trix-editor[disabled]:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
trix-editor[disabled]:where(.dark, .dark *):hover{
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.trix-hide-toolbar trix-toolbar {
    display: none !important;
  }
.trix-content{
  font-size: 1rem;
  line-height: 1.5rem;
}
@media (min-width: 768px){
  .trix-content{
    font-size: 0.875rem;
    line-height: 1.25rem;
  }
}
/* The Trix Editor uses SVGs for its buttons, so we manually override them here for dark mode */
/* Icons taken from https://react-icons.github.io/react-icons/icons?name=md */
.dark .trix-button--icon-bold::before {
    background-image: url('data:image/svg+xml;utf-8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"></path></svg>') !important;
  }
.dark .trix-button--icon-italic::before {
    background-image: url('data:image/svg+xml;utf-8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"></path></svg>') !important;
  }
.dark .trix-button--icon-strike::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M6.85 7.08C6.85 4.37 9.45 3 12.24 3c1.64 0 3 .49 3.9 1.28.77.65 1.46 1.73 1.46 3.24h-3.01c0-.31-.05-.59-.15-.85-.29-.86-1.2-1.28-2.25-1.28-1.86 0-2.34 1.02-2.34 1.7 0 .48.25.88.74 1.21.38.25.77.48 1.41.7H7.39c-.21-.34-.54-.89-.54-1.92zM21 12v-2H3v2h9.62c1.15.45 1.96.75 1.96 1.97 0 1-.81 1.67-2.28 1.67-1.54 0-2.93-.54-2.93-2.51H6.4c0 .55.08 1.13.24 1.58.81 2.29 3.29 3.3 5.67 3.3 2.27 0 5.3-.89 5.3-4.05 0-.3-.01-1.16-.48-1.94H21V12z"></path></svg>') !important;
  }
.dark .trix-button--icon-link::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M8 11h8v2H8v-2zm12.1 1H22c0-2.76-2.24-5-5-5h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1zM3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM19 12h-2v3h-3v2h3v3h2v-3h3v-2h-3v-3z"></path></svg>') !important;
  }
.dark .trix-button--icon-heading-1::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M9 4v3h5v12h3V7h5V4H9zm-6 8h3v7h3v-7h3V9H3v3z"></path></svg>') !important;
  }
.dark .trix-button--icon-quote::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"></path></svg>') !important;
  }
.dark .trix-button--icon-code::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></svg>') !important;
  }
.dark .trix-button--icon-bullet-list::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"></path></svg>') !important;
  }
.dark .trix-button--icon-number-list::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"></path></svg>') !important;
  }
.dark .trix-button--icon-decrease-nesting-level::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M11 17h10v-2H11v2zm-8-5l4 4V8l-4 4zm0 9h18v-2H3v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"></path></svg>') !important;
  }
.dark .trix-button--icon-increase-nesting-level::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M3 21h18v-2H3v2zM3 8v8l4-4-4-4zm8 9h10v-2H11v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"></path></svg>') !important;
  }
.dark .trix-button--icon-attach::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5a2.5 2.5 0 015 0v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5a2.5 2.5 0 005 0V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"></path></svg>') !important;
  }
.dark .trix-button--icon-undo::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"></path></svg>') !important;
  }
.dark .trix-button--icon-redo::before {
    background-image: url('data:image/svg+xml;utf8,<svg stroke="currentColor" fill="%23FFFFFF" stroke-width="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16a8.002 8.002 0 017.6-5.5c1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"></path></svg>') !important;
  }
.code-editor .monaco-editor, .code-editor .monaco-editor .overflow-guard {
    border-radius: inherit;
  }
.code-editor .monaco-editor, .code-editor .monaco-editor-background, .code-editor .monaco-editor .margin {
    background-color: var(--code-editor-background,transparent);
  }
.required > label::after{
  display: inline-block;
  padding-left: 0.25rem;
  font-size: 1rem;
  line-height: 1.5rem;
  line-height: 1;
  --tw-text-opacity: 1;
  color: rgb(239 68 68 / var(--tw-text-opacity, 1));
  content: "*";
}
[data-turn-exit],
[data-turn-enter] {
  animation-timing-function: cubic-bezier(0.65, 0.05, 0.35, 1);
  animation-fill-mode: forwards;
}
html.turn-exit [data-turn-exit] {
  animation-name: fade-out-up;
  animation-duration: .3s;
}
html.turn-enter [data-turn-enter] {
  animation-name: fade-in-up;
  animation-duration: .6s;
}
html.turn-before-exit [data-turn-exit],
html.turn-exit [data-turn-exit] {
  will-change: transform, opacity;
}
@keyframes fade-out-up {
  0% {
   opacity: 1;
   transform: translateZ(0)
  }

  100% {
   opacity: 0;
   transform: translate3d(0, -2rem, 0)
  }
}
@keyframes fade-in-up {
  0% {
   opacity: 0;
   transform: translate3d(0, 2rem, 0)
  }

  100% {
   opacity: 1;
   transform: translateZ(0)
  }
}
/*
 * A (possibly) temporary fix for a weird interaction between Turbo and turn.js
 * https://github.com/bullet-train-co/bullet_train/issues/2214#issuecomment-3349556410
 */
.turn-view-transitions.turn-transition [data-turn-enter],
.turn-view-transitions.turn-before-transition [data-turn-enter] {
  opacity: 0;
}
/*
 * This mostly prevents sudden side-to-side jumping due to the addition of a scrollbar during transition.
 */
html.turn-advance:has(body.devise_layout){
  overflow: hidden;
}
/*
 * This disables the view transitions that turn automatically injects just by being present.
 */
@supports (view-transition-name: root) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
    opacity: 1 !important;
  }
}
#bt-docs-content h1,
#bt-docs-content h2,
#bt-docs-content h3,
#bt-docs-content h4,
#bt-docs-content h5,
#bt-docs-content h6{
  position: relative;
  margin-left: -1.2rem;
  padding-left: 1.2rem;
}
#bt-docs-content h1 a,
#bt-docs-content h2 a,
#bt-docs-content h3 a,
#bt-docs-content h4 a,
#bt-docs-content h5 a,
#bt-docs-content h6 a{
  text-decoration: none;
  display: none;
  position: absolute;
  float:left;
  margin-left:-1.2rem;
  line-height: 1;
  width: 1rem;
  height: 100%;
}
#bt-docs-content h1 a::before,
#bt-docs-content h2 a::before,
#bt-docs-content h3 a::before,
#bt-docs-content h4 a::before,
#bt-docs-content h5 a::before,
#bt-docs-content h6 a::before{
  content: "🔗";
}
#bt-docs-content h1:hover a,
#bt-docs-content h2:hover a,
#bt-docs-content h3:hover a,
#bt-docs-content h4:hover a,
#bt-docs-content h5:hover a,
#bt-docs-content h6:hover a{
  display: flex;
  justify-content: center; /* Align horizontal */
  align-items: center; /* Align vertical */
}
@media only screen and (max-width: 640px) {
  #bt-docs-content h1,
  #bt-docs-content h2,
  #bt-docs-content h3,
  #bt-docs-content h4,
  #bt-docs-content h5,
  #bt-docs-content h6{
    margin-left: -1.375rem;
    padding-left: 1.375rem;
  }
  #bt-docs-content h1 a,
  #bt-docs-content h2 a,
  #bt-docs-content h3 a,
  #bt-docs-content h4 a,
  #bt-docs-content h5 a,
  #bt-docs-content h6 a{
    margin-left:-1.375rem;
  }
  #bt-docs-content h1 a::before,
  #bt-docs-content h2 a::before,
  #bt-docs-content h3 a::before,
  #bt-docs-content h4 a::before,
  #bt-docs-content h5 a::before,
  #bt-docs-content h6 a::before{
    font-size: 1rem;
  }
}
form.button_to{
  display: inline-block;
}
form.button_to input[type=submit]{
  background-color: transparent;
}
form.button_to input[type=submit].button{
  background-color: var(--primary-500);
}
form.button_to input[type=submit].button:hover{
  background-color: var(--primary-600);
}
/* hide the first breadcrumb chevron */
ol.breadcrumb li:first-child svg { display: none; }
/* Override Turbo's progress bar color with the application's theme. */
.turbo-progress-bar {
  height: 5px;
  background-color: var(--primary-500);
}
/*
  When dragging a sortable table row, only show the first column, usually containing the element's label.
  Can be customize on a per-table basis.
*/
tr.gu-mirror > *:not(:first-child) {
  display: none;
}
/* alias used to support ejecting the file to local */
/* ✅ YOUR APPLICATION'S CSS */
/* If you need to customize your application's CSS, this is the place to do it. This helps
   avoid merge conflicts in the future when Rails or Bullet Train update their own CSS.
*/
/* tokens.css must come first — defines ramps + semantic aliases consumed
   downstream. Per docs/archive/UI-MIGRATION-PLAN.md T1 + UI-ARCHITECTURE.md §5. */
/*
 * tokens.css — DiveOS design token ENTRY (v4 — repo spec: sky-700 + Inter)
 *
 * Two-layer token architecture (split 2026-07-11, os-ds extraction step 1):
 *   - tokens/primitives.css — product-INVARIANT raw scales (ramps, spacing,
 *     type, radius, shadow, z, motion, layout). Shared byte-for-byte across
 *     DiveOS / HotelOS; never referenced by components directly.
 *   - tokens/semantic.css   — the THEME surface: role mappings (neutrals,
 *     accent, status, input, notifications, interaction states) + fonts.
 *     The ~10% a product re-brands; components consume ONLY these.
 * A consuming product re-themes by overriding tokens/semantic.css alone.
 *
 * v4 migration (2026-06-06): aligned to the diveOS-design-system repo
 * (gitlab.nsfrg.my:novas/diveOS-design-system), the locked design source of
 * truth — body font Inter, accent sky-700 #0369A1, cool-gray neutrals,
 * ramp-based status tints, dark mode removed (light-only).
 *
 * Loaded via application.css before all other stylesheets. The token @imports
 * below are inlined by postcss-import at build time into one :root cascade;
 * order is cosmetic since every var() resolves at use-time.
 */
/* Self-hosted webfonts (woff2 face declarations) — replaces the former remote
   Google Fonts imports. A consuming app tightened its CSP to `font_src :self`
   with no external stylesheet host, which blocked the remote font import and
   dropped the type. Fonts now ship in the gem (app/assets/fonts, on the engine
   asset path) and resolve via Propshaft's url() rewriting. Declared here at the
   top of the token entry so the face rules land near the top of the flattened
   bundle, ahead of any rule that uses the families. Material Symbols was dropped
   (dead — no consumer). */
/* THE @import STATEMENTS MUST STAY FIRST. CSS ignores any `@import` that
   appears after another statement, and `@font-face` counts. From v0.16.1 —
   when the fonts were self-hosted and these face rules were added ABOVE the
   imports — both token imports became invalid, so a consumer that loads THIS
   FILE (rather than the flattened bundle) silently lost the entire token
   layer: every primitive and every semantic role.

   It stayed invisible for thirteen releases because the two consumers load
   os-ds differently. arena-ops loads the flattened `os_ds.css`, where the
   builder has already inlined these imports, so it is unaffected. DiveOS
   imports the SOURCE files through postcss-import, which honoured the spec,
   dropped both, and left `--accent`, `--ink`, `--surface` and every scale
   undefined. Its Tailwind theme hardcodes fallbacks (`var(--accent, #0369A1)`)
   so utilities kept working — but os-ds components carry no fallback, so
   `.dv-btn--primary` computed a TRANSPARENT background there.

   Found by rendering the real app, not by reading CSS: the class-level diff
   between versions reported zero regressions, because tokens are not classes. */
/*
 * tokens/primitives.css — PRODUCT-INVARIANT design primitives.
 *
 * The raw scales every product shares byte-for-byte: colour ramps, the
 * spacing / type / radius / shadow scales, z-index stack, motion timings,
 * and structural layout defaults. These are the SOURCE the semantic layer
 * (tokens/semantic.css) maps into roles — components NEVER reference a
 * primitive directly, only its semantic alias.
 *
 * When the design system is extracted into the shared os-ds gem, this file
 * ships once and is identical across DiveOS / HotelOS. A product re-themes by
 * overriding tokens/semantic.css, not this file (it may ADD a brand ramp here
 * — e.g. a --teal-* scale — then point --accent at it in its semantic layer).
 *
 * Loaded via tokens.css (the entry) before tokens/semantic.css. Ordering is
 * cosmetic: all vars land in one :root cascade and var() resolves at use-time.
 */
:root {
  /* ─── Foundation ramps (semantic source + showcase swatches) ─────── */
  --gray-50:  #F9FAFB; --gray-100: #F3F4F6; --gray-200: #E5E7EB;
  --gray-300: #D1D5DB; --gray-400: #9CA3AF; --gray-500: #6B7280;
  --gray-600: #4B5563; --gray-700: #374151; --gray-800: #1F2937;
  --gray-900: #111827; --gray-950: #030712;

  --sky-50:  #F0F9FF; --sky-100: #E0F2FE; --sky-200: #BAE6FD;
  --sky-300: #7DD3FC; --sky-400: #38BDF8; --sky-500: #0EA5E9;
  --sky-600: #0284C7; --sky-700: #0369A1; --sky-800: #075985;
  --sky-900: #0C4A6E; --sky-950: #082F49;

  --amber-50:  #FFFBEB; --amber-100: #FEF3C7; --amber-200: #FDE68A;
  --amber-300: #FCD34D; --amber-400: #FBBF24; --amber-500: #F59E0B;
  --amber-600: #D97706; --amber-700: #B45309; --amber-800: #92400E;
  --amber-900: #78350F; --amber-950: #451A03;

  --green-50:  #F0FDF4; --green-100: #DCFCE7; --green-200: #BBF7D0;
  --green-300: #86EFAC; --green-400: #4ADE80; --green-500: #22C55E;
  --green-600: #16A34A; --green-700: #15803D; --green-800: #166534;
  --green-900: #14532D; --green-950: #052E16;

  --red-50:  #FEF2F2; --red-100: #FEE2E2; --red-200: #FECACA;
  --red-300: #FCA5A5; --red-400: #F87171; --red-500: #EF4444;
  --red-600: #DC2626; --red-700: #B91C1C; --red-800: #991B1B;
  --red-900: #7F1D1D; --red-950: #450A0A;

  --slate-50:  #F8FAFC; --slate-100: #F1F5F9; --slate-200: #E2E8F0;
  --slate-300: #CBD5E1; --slate-400: #94A3B8; --slate-500: #64748B;
  --slate-600: #475569; --slate-700: #334155; --slate-800: #1E293B;
  --slate-900: #0F172A; --slate-950: #020617;

  --rose-50:  #FFF1F2; --rose-100: #FFE4E6; --rose-200: #FECDD3;
  --rose-300: #FDA4AF; --rose-400: #FB7185; --rose-500: #F43F5E;
  --rose-600: #E11D48; --rose-700: #BE123C; --rose-800: #9F1239;
  --rose-900: #881337; --rose-950: #4C0519;

  --stone-50:  #FAFAF9; --stone-100: #F5F5F4; --stone-200: #E7E5E4;
  --stone-300: #D6D3D1; --stone-400: #A8A29E; --stone-500: #78716C;
  --stone-600: #57534E; --stone-700: #44403C; --stone-800: #292524;
  --stone-900: #1C1917; --stone-950: #0C0A09;

  /* ─── Spacing scale — 8-point system (4px sub-grid) ──────────────────
     One unit = 4px. Use these for all component padding / gap / margin so
     primitives stay on the grid. Half-step (--space-0-5 = 2px) is reserved
     for hairline-level nudges only (icon optical alignment), not layout. */
  --space-0-5: 2px;
  --space-1:   4px;
  --space-2:   8px;
  --space-3:   12px;
  --space-4:   16px;
  --space-5:   20px;
  --space-6:   24px;
  --space-8:   32px;
  --space-10:  40px;
  --space-12:  48px;
  --space-16:  64px;

  /* ─── Type scale — even steps on the system (no odd/half sizes) ───────
     Component font-size MUST use these tokens, never a raw px. The old
     11/12.5/13/13.5/15px values snap to the nearest step. Bigger one-off
     display/hero sizes (>28) stay raw — they're not primitives. */
  --text-2xs:  10px;   /* micro labels, table th eyebrows */
  --text-xs:   12px;   /* eyebrows, sub-lines, meta, chips (← 11/11.5/12.5) */
  --text-sm:   14px;   /* body / primary cell / card heading (← 13/13.5/15) */
  --text-md:   16px;   /* prominent body, small headings (← 15.5/17) */
  --text-lg:   18px;   /* card/section headings (← 19) */
  --text-xl:   20px;   /* large headings (← 21/22) */
  --text-2xl:  24px;   /* (← 23/25/26) */
  --text-3xl:  28px;   /* page titles (← 27/30/31/32) */

  /* ─── Line-height scale — paired 1:1 with the type scale ──────────────
     Practical UI, Ch.5 (Typography): line-height is ABSOLUTE and lands on
     the 4pt vertical grid (so text aligns to the layout rhythm), the RATIO
     DECREASES as font-size grows (headings tighter than body), and body
     text stays ≥1.5 for readability. Each --leading-* is the leading for
     the same-suffix --text-*; a text role sets font-size AND its paired
     line-height, never a raw ratio. Book anchors: H3 24/32, H4 20/28,
     Small 16/24, Tiny 14/20. */
  --leading-2xs: 14px;   /* 10px · 1.40 — micro labels (single-line) */
  --leading-xs:  18px;   /* 12px · 1.50 — meta / small print */
  --leading-sm:  22px;   /* 14px · 1.57 — default body (≥1.5) */
  --leading-md:  24px;   /* 16px · 1.50 — body / small heading (book Small) */
  --leading-lg:  28px;   /* 18px · 1.56 — roomy body / card heading */
  --leading-xl:  28px;   /* 20px · 1.40 — heading (book H4 20/28) */
  --leading-2xl: 32px;   /* 24px · 1.33 — heading (book H3 24/32) */
  --leading-3xl: 36px;   /* 28px · 1.29 — page title (book H2/H3 pattern) */
  --leading-relaxed: 1.6; /* long-form prose paragraphs (unitless, opt-in) */

  /* ─── Border radius scale — small / medium / large intent ────────────
     Practical UI uses 3 radii (small/medium/large). Ours is finer for a
     dense UI, but maps to the same intent. --radius is the default; --radius-md
     is a back-compat alias of it (they were a duplicate 8px). */
  --radius-sm:   6px;             /* small — chips, inputs, tight controls */
  --radius:      8px;             /* medium (default) — buttons, cards */
  --radius-md:   var(--radius);   /* alias of the default (dedup: was 8px twice) */
  --radius-lg:   10px;            /* large — panels, popovers */
  --radius-xl:   14px;            /* x-large — hero / sheet surfaces */
  --radius-2xl:  18px;            /* xx-large — the FAB (.os-fab) only, so far.
                                     Added for a 56px floating button: at that
                                     size --radius-xl reads as a plain square
                                     and --radius-pill as a circle, and neither
                                     is the intended "softened square". Reach
                                     for this only on a large standalone
                                     control, never on a card or panel. */
  --radius-pill: 9999px;

  /* ─── Control size scale — the height of an INTERACTIVE control ──────
     Every control in the system (button, input, select, filter pill,
     segmented option) is one of seven heights. Before this scale they were
     seven independent LITERALS, re-typed per component: .os-btn 36px,
     --sm 32px, --field 46px, --touch 48px, and forms.css / dv_select.css
     spelling those same four numbers again from memory. Nothing tied them
     together, so "the field height" was a number you had to know rather
     than a token you could read — and the numbers had already begun to
     drift (dv_select's small variant is 34px, not the 32px --sm it means).

     WHY a scale AND a resolved trio (below), rather than one token per
     component: a control's height is a property of the SURFACE it sits on,
     not of the control. A desk admin table wants 36px; a handheld used
     one-handed on a boat, in sun, wants 48px. The alternative — adding a
     `--field` twin to each component — is N patches that drift apart, which
     is exactly how we got here. Density is set ONCE on a layout wrapper
     (see tokens/density.css) and every control inside re-sizes.

     --control-h-md (40px) is NEW: the missing rung between --sm (32) and
     --field (46). It exists as a density STEP, not as a per-component
     modifier, so it cannot become the next one-off.

     Paired --control-pad-x-* / --control-fs-* keep a control's horizontal
     padding and label size proportional to its height; a 48px control with
     14px side padding reads as a slab. */
  --control-h-xs:    22px;   /* inline action beside a badge (.os-btn--xs) */
  --control-h-sm:    32px;   /* dense desktop row (.os-btn--sm) */
  --control-h-base:  36px;   /* THE default — desktop admin (.os-btn) */
  --control-h-md:    40px;   /* comfortable desktop / small tablet (new) */
  --control-h-lg:    42px;   /* prominent CTA (.os-btn--lg) */
  --control-h-field: 46px;   /* canonical form-control height (.os-field) */
  --control-h-touch: 48px;   /* 48pt minimum touch target (Fitts's Law) */
  /* .os-filter-btn's OWN height (v1.27.0). Not derived from --control-h: a
     consumer that scopes --control-h onto `form` (field height) must not grow
     every filter control inside a GET filter form. Only .os-density--touch
     moves it (density.css). */
  --filter-btn-h:    var(--control-h-sm);

  --control-pad-x-xs:    var(--space-2);   /* 8px  */
  --control-pad-x-sm:    var(--space-3);   /* 12px */
  --control-pad-x-base:  14px;             /* px-3.5 — off-grid, see NOTE */
  --control-pad-x-md:    14px;
  --control-pad-x-lg:    var(--space-4);   /* 16px */
  --control-pad-x-field: 14px;
  --control-pad-x-touch: var(--space-5);   /* 20px */
  /* NOTE: 14px is not on the 4px spacing grid. It is the shipped .os-btn
     padding (Tailwind px-3.5) and re-grid-ing it would resize every button
     in both products — a token contract cannot also be a visual redesign.
     Left as a literal so the off-grid value is visible, not laundered. */

  --control-fs-xs:    var(--text-2xs);
  --control-fs-sm:    var(--text-xs);
  --control-fs-base:  var(--text-sm);
  --control-fs-md:    var(--text-sm);
  --control-fs-lg:    var(--text-sm);
  --control-fs-field: var(--text-sm);
  --control-fs-touch: var(--text-sm);

  /* The RESOLVED trio every interactive component reads. Defaults to the
     base step; a density scope (tokens/density.css) re-points these three
     on a wrapper and the whole subtree follows. A component that must NOT
     follow density re-declares them on itself — which is precisely how the
     existing size modifiers stay pinned (see buttons.css). */
  --control-h:     var(--control-h-base);
  --control-pad-x: var(--control-pad-x-base);
  --control-fs:    var(--control-fs-base);

  /* ─── Elevation — TWO tiers (Practical UI Ch.3: ~2 elevations is enough) ──
     `raised`  = anything lifted off the page (cards, menus, popovers, dropdowns).
     `overlay` = surfaces floating above the page (drawers, modals, toasts).
     These two are the only concrete shadow values; the legacy --shadow-* names
     below all derive from them (back-compat), so a component can keep its old
     token and still get the collapsed 2-tier system. The card "ring" is a
     structural hairline border, composited on top of `raised` — not a 3rd
     elevation. (Visual-reviewed before/after 2026-07-11.) */
  --elevation-raised:  0 1px 2px rgba(17, 24, 39, 0.06), 0 2px 6px -1px rgba(17, 24, 39, 0.05);
  --elevation-overlay: 0 16px 40px -12px rgba(17, 24, 39, 0.20), 0 6px 16px -8px rgba(17, 24, 39, 0.10);

  /* Legacy shadow names → the 2 tiers (was 5 distinct values). --shadow-sm is
     the exception: it's a control WHISPER (segmented options, toggle knobs,
     small pills), NOT a real elevation, so it keeps its subtle 1-layer value —
     folding it into --elevation-raised made those inline controls read too
     heavy. --shadow-md is the actual raised tier. */
  --shadow-sm:    0 1px 2px rgba(17, 24, 39, 0.05);
  --shadow-md:    var(--elevation-raised);
  --shadow-card:  0 1px 2px rgba(17, 24, 39, 0.05), 0 0 0 1px var(--hairline);  /* raised + hairline ring */
  --shadow-hover: var(--elevation-raised), 0 0 0 1px var(--hairline);           /* card hover = raised + ring */
  --shadow-panel: var(--elevation-overlay);

  /* ─── Z-index stack ──────────────────────────────────────────────── */
  --z-toast:    60;
  --z-modal:    50;
  --z-panel:    40;
  --z-dropdown: 30;
  --z-tooltip:  20;

  /* ─── Motion ─────────────────────────────────────────────────────── */
  --ease-out-quart: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-standard:  cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast:  120ms;
  --t-med:   180ms;
  --t-slow:  240ms;

  /* "Calm & effortless" motion (docs/motion.md, v1.31.0). Arrivals SETTLE (quick
     start, long soft landing); departures leave on the EXIT curve at --motion-exit ×
     their entrance. --ease-out-quart is the drawer / sheet / page-slide curve and
     --t-slow (240) the calm state beat — both reused, not restated. */
  --ease-settle:  cubic-bezier(0.2, 0, 0, 1);  /* arrivals */
  --ease-exit:    cubic-bezier(0.4, 0, 1, 1);  /* departures */
  --t-quick:      140ms;  /* direct feedback: a count, a press, a tick */
  --t-slow-out:   168ms;  /* a calm (--t-slow) state leaving: 0.7 × 240 */
  --t-page:       200ms;  /* page-to-page cross-fade */
  --t-grow:       340ms;  /* a dropdown growing from its field */
  --t-drawer:     380ms;  /* a sheet / drawer / pushed page arriving */
  --t-drawer-out: 266ms;  /* ... and leaving: 0.7 × 380, written out (calc() lands on 265.99) */
  --motion-exit:  0.7;    /* exit duration = entrance × this */
  --motion-drift: 4px;    /* the furthest anything travels (sheets + pages excepted) */
  --motion-push-shift: -25%; /* page push: the page beneath recedes a quarter left (v1.31.1) */
  --motion-push-dim:   0.88; /* ... and dims to brightness(.88) — a hint of depth, not a scrim */

  /* ─── Layout primitives ─────────────────────────────────────────── */
  --sidebar-w: 240px;
  --panel-w:   520px;
  /* Date column beside a day's rows (.os-daterail: day · month · weekday). */
  --daterail-col: 72px;

  /* ─── Width scale — floating-surface widths (popovers, dialogs, panels) ──
     A fixed-width scale so a menu / popover / dialog / side-panel snaps to a
     named step instead of a raw px. Follows the de-facto container-width
     convention (Tailwind max-width, Chakra `sizes`) — 4rem steps; Carbon &
     Polaris drive layout from grid + spacing and ship no floating-surface
     width primitive, so this is the closest applicable reference. Component
     widths (os-pop 320, os-popover 380, side-panel ~560) snap to these. */
  --width-xs: 320px;   /* dropdowns / pickers (os-pop) */
  --width-sm: 384px;   /* small dialogs / popovers (os-popover; 380 → 384) */
  --width-md: 448px;   /* medium dialogs */
  --width-lg: 512px;   /* large dialogs / confirm */
  --width-xl: 576px;   /* side panels / sheets (~560 → 576) */

  /* Page width tiers — the content column ceiling per archetype. The shell
     (.diveos-content) defaults to --page-wide; forms/wizards opt into --narrow
     via content_for(:page_width). Below the ceiling the fluid --gutter breathes;
     past it, margin-inline:auto converts surplus to symmetric side space.

     THREE tiers since v1.11.0. It was two, on the reasoning that "reading pages
     stay wide and cap PROSE with --measure" — which holds for an article and
     fails for a DOCUMENT. A registration card, a folio, a checkout review, a
     statement: these are not prose, so --measure never engages, and they are
     not lists either, so --wide gives them a 1280px field of mostly-empty row.
     Their content is field/value pairs, a signature block, a party table —
     structures that want to sit together, not stretch. --narrow is the other
     failure: a two-column field grid plus a signature pad does not survive
     768px, so consumers were pinning their own local ~900-1000px values, which
     is how six different literals ended up in one app.

     PICK BY WHAT THE PAGE IS, not by how wide it looks right:
       --page-wide     you are scanning MANY records         (board, list, dashboard)
       --page-reading  you are reading or signing ONE record (document, review, receipt)
       --page-narrow   you are answering questions in order  (form, wizard, single column) */
  --page-wide:    1280px;   /* default: lists, kanban, calendar, dashboard, detail, settings */
  --page-reading:  960px;   /* documents: registration cards, folios, statements, reviews */
  --page-narrow:  768px;    /* forms, wizards, focused reading */
  /* Measure (max line length) SCALES DOWN as text grows — Practical UI Ch.4/5:
     optimal line length shrinks at larger sizes (~90ch small body → ~45ch
     display). Apply via .dv-measure (default) / --lg / --display; never on
     tables or cards. */
  --measure:         68ch;  /* default: 14–16px body — the reading cap */
  --measure-lg:      56ch;  /* 18–20px lead paragraphs / large body */
  --measure-display: 45ch;  /* 24px+ display / hero copy that wraps */
  --gutter:       clamp(16px, 4cqi, 64px);  /* fluid side gutter (measured on the content pane) */
  --content-max:  var(--page-narrow);       /* legacy alias the wizard CSS consumes (was undefined) */
}
/* Reduced motion: states still change, nothing travels. Drift collapses to 0 so any
   drift-based entrance degrades to opacity only; each component still owns its own
   `animation/transition: none` block (docs/motion.md → Reduced motion). */
@media (prefers-reduced-motion: reduce) {
  :root { --motion-drift: 0px; }
}
/*
 * tokens/semantic.css — the THEME surface (per-product override point).
 *
 * Maps the raw primitives (tokens/primitives.css) into named ROLES that
 * components consume: neutrals (canvas/surface/ink/…), the accent family,
 * status palette, input tokens, notification semantics, and interaction
 * states. This is the ~10% a product re-brands: swap the accent, the fonts,
 * or the status mapping here and every .dv-* component re-themes with no
 * component edits.
 *
 * In the shared os-ds gem this file ships as the DEFAULT (DiveOS: sky-700 /
 * Inter). A consuming app (HotelOS) overrides it with its own tokens/semantic.css
 * loaded after the gem's — same role names, different primitive targets.
 *
 * NOTE the dive-domain status names (briefing / inwater) live here: they are a
 * semantic/domain choice, so HotelOS replaces this block with its own statuses
 * rather than inheriting them.
 */
:root {
  /* ─── Typography — role fonts (a product may rebrand these) ────────────
     Single typeface for UI: Inter for BOTH display/headings and body
     (General Sans was dropped — headings + body are now one family).
     Geist Mono for tabular numerals, IDs, timestamps, financial figures.
     --font-display is kept as a distinct token (same value as --font-sans)
     so heading call-sites keep their semantic name and can diverge later
     without a sweep. */
  --font-display: 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-sans:    'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-mono:    'Geist Mono', ui-monospace, monospace;

  /* ─── Semantic neutrals (v4 — cool gray ramp aliases) ──────────────── */
  --canvas:           var(--gray-50);      /* page bg */
  --surface:          #FFFFFF;             /* cards, modals */
  --surface-alt:      var(--gray-100);     /* header zone, sidebar, subtle distinction */
  --hairline:         var(--gray-200);     /* default border */
  --hairline-2:       #F0F1F4;             /* inner row separator */
  --hairline-strong:  var(--gray-300);     /* active/focused border */
  --ink:              var(--gray-900);     /* body + headings */
  --muted:            var(--gray-500);     /* less prominent text */
  --muted-2:          #6A707A;             /* captions, meta — darkened from gray-400 to clear 4.5:1 (Practical UI Ch.3 contrast; was 2.5:1) */

  /* ─── Accent (v4 — sky-700, swappable per tenant) ─────────────────────
     --accent-rgb holds the accent's raw channels so the alpha-derived tokens
     (soft/softer/border here + input-border-focus/focus-ring/focus-ring-color
     below) compose from ONE source. A re-theming consumer overrides --accent
     AND --accent-rgb (two lines) and every derived surface — including focus
     rings — follows; before this, the six alphas were hardcoded to sky's
     channels, so swapping --accent alone left a half-sky UI. */
  --accent:           var(--sky-700);
  --accent-strong:    var(--sky-800);
  --accent-rgb:       3, 105, 161;             /* sky-700 channels; override when re-theming */
  --accent-soft:      rgba(var(--accent-rgb), 0.08);
  --accent-softer:    rgba(var(--accent-rgb), 0.04);
  --accent-border:    rgba(var(--accent-rgb), 0.26);
  /* Interactive colour (v1.31.0). Every clickable control — secondary/icon
     buttons, tabs, segmented options, filter pills/buttons, pager steps,
     sub-nav links — reads these AT REST, so "accent-coloured" is the one
     signifier of "you can click this". Hover goes one step darker. Selected
     state stays distinguished by its own chrome (fill, underline, weight).
     A product re-points --accent and these follow; override these only to
     split interactive colour from brand accent. */
  --interactive:              var(--accent);
  --interactive-hover:        var(--accent-strong);
  --interactive-border:       var(--accent-border);
  --interactive-border-hover: var(--accent);
  --on-accent:        #FFFFFF;                 /* text/glyphs on an accent fill (buttons, markers, pills) */

  /* ─── v1/v2 compat aliases — back-compat for existing callsites ───── */
  --bg:               var(--canvas);
  --text-primary:     var(--ink);
  --text-secondary:   var(--gray-700);
  --text-muted:       var(--muted);
  --border:           var(--hairline);
  --border-strong:    var(--hairline-strong);
  --accent-tint:      var(--accent-soft);
  --accent-light:     var(--sky-100);       /* lit accent tint for current-step */

  /* ─── Sequential data-viz ramp (NOT status colors) ─────────────────
     Monochromatic sky ramp for functional 5-step sequential data
     visualisations (e.g. pricing-zone bands). Purple/violet is banned;
     use these for any light→intense sequential encoding. Text on any
     step: --viz-ink (sky-800 stays readable on sky-50..400). */
  --viz-1:   var(--sky-50);
  --viz-2:   var(--sky-100);
  --viz-3:   var(--sky-200);
  --viz-4:   var(--sky-300);
  --viz-5:   var(--sky-400);
  --viz-ink: var(--sky-800);

  --sidebar-bg:       var(--gray-100);
  --hover-warm:       var(--gray-100);      /* legacy name; now neutral gray hover */

  /* ─── Status palette — single source (v4 ramp-based soft tints) ─────
     Both legacy names (--status-*-fg / --status-*-bg) and v2 short names
     (--<status>, --<status>-bg, --<status>-border) resolve to the SAME
     ramp values so no chip can drift between aliases.
     5 repo statuses + 2 app-derived (returning=slate, completed=gray). */
  --status-pending-fg:    var(--stone-600);
  --status-pending-bg:    var(--stone-100);
  --status-pending-border:var(--stone-300);
  --pending:              var(--status-pending-fg);
  --pending-bg:           var(--status-pending-bg);
  --pending-border:       var(--status-pending-border);

  --status-confirmed-fg:  var(--green-700);
  --status-confirmed-bg:  var(--green-50);
  --status-confirmed-border: var(--green-200);
  --confirmed:            var(--status-confirmed-fg);
  --confirmed-bg:         var(--status-confirmed-bg);
  --confirmed-border:     var(--status-confirmed-border);

  --status-briefing-fg:   var(--amber-800);
  --status-briefing-bg:   var(--amber-50);
  --status-briefing-border: var(--amber-300);
  --briefing:             var(--status-briefing-fg);
  --briefing-bg:          var(--status-briefing-bg);
  --briefing-border:      var(--status-briefing-border);

  --status-in-water-fg:   var(--sky-800);
  --status-in-water-bg:   var(--sky-50);
  --status-in-water-border: var(--sky-200);
  --inwater:              var(--status-in-water-fg);
  --inwater-bg:           var(--status-in-water-bg);
  --inwater-border:       var(--status-in-water-border);

  --status-returning-fg:  var(--slate-600);
  --status-returning-bg:  var(--slate-100);
  --status-returning-border: var(--slate-300);

  --status-completed-fg:  var(--gray-500);
  --status-completed-bg:  var(--gray-100);
  --status-completed-border: var(--gray-300);

  --status-cancelled-fg:  var(--rose-800);
  --status-cancelled-bg:  var(--rose-50);
  --status-cancelled-border: var(--rose-200);
  --cancelled:            var(--status-cancelled-fg);
  --cancelled-bg:         var(--status-cancelled-bg);
  --cancelled-border:     var(--status-cancelled-border);

  /* ─── Bar / rail tints (peripheral indicators — lighter ramp steps) ── */
  --bar-confirmed:  var(--green-300);
  --bar-briefing:   var(--amber-300);
  --bar-inwater:    var(--sky-300);
  --bar-pending:    var(--stone-300);
  --bar-cancelled:  var(--rose-300);
  --bar-returning:  var(--slate-300);

  /* ─── Input tokens (v4 repo model) ─────────────────────────────────── */
  --input-bg:           var(--gray-50);
  --input-border:       var(--gray-300);
  --input-border-hover: var(--gray-400);
  --input-border-focus: rgba(var(--accent-rgb), 0.60);
  --input-placeholder:  rgba(107, 114, 128, 0.80);  /* darkened from 0.50 to clear ~3:1 supplementary-text bar (label always present) */
  --focus-ring:         rgba(var(--accent-rgb), 0.10);
  --error:              #C13028;

  /* ─── Notification semantics (toasts / inline alerts) ───────────────
     Generic success/danger/warning/info layer, distinct from the
     booking-status palette. Resolves to existing colour ramps. */
  --success:         var(--green-700);
  --success-bg:      var(--green-50);
  --success-border:  var(--green-200);

  --danger:          var(--rose-800);
  --danger-bg:       var(--rose-50);
  --danger-border:   var(--rose-200);

  --warning:         var(--amber-700);
  --warning-bg:      var(--amber-50);
  --warning-border:  var(--amber-200);

  --info:            var(--accent);
  --info-bg:         var(--sky-50);
  --info-border:     var(--sky-200);

  /* ─── Interaction states ─────────────────────────────────────────────
     Canonical state vocabulary every interactive primitive uses:
       hover    → neutral darken overlay (or accent-strong on filled)
       active   → stronger overlay / translateY(1px) press
       focus    → --shadow-focus keyboard ring (focus-visible only)
       selected → accent-soft fill + accent text
       disabled → --disabled-opacity, no pointer events
     See /admin/design_system "Interaction states" for the recipe. */
  --state-hover:    rgba(17, 24, 39, 0.04);
  --state-active:   rgba(17, 24, 39, 0.08);
  --state-selected: var(--accent-soft);
  --focus-ring-color: rgba(var(--accent-rgb), 0.35);
  --shadow-focus:   0 0 0 3px var(--focus-ring-color);
  --disabled-opacity: 0.5;
  --transition-base: var(--t-med) var(--ease-standard);
}
/* Control-density SCOPE classes (.os-density--*). Imported last of the three
   so its scope rules land after the :root control defaults they override. */
/*
 * tokens/density.css — the CONTROL DENSITY SCOPE.
 *
 * One class, set ONCE on a layout wrapper, re-points the resolved control
 * trio (--control-h / --control-pad-x / --control-fs, defined in
 * tokens/primitives.css) for everything inside it. Every interactive
 * component in the gem reads that trio, so a handheld or kiosk surface
 * conforms to the design system by declaring its density rather than by
 * minting local classes.
 *
 *   <div class="os-density--touch">   <!-- boat handheld, one-handed, in sun -->
 *     <button class="os-btn os-btn--primary">Check in</button>   <!-- 48px -->
 *   </div>
 *
 * WHY A CLASS, not a data attribute (`[data-density="touch"]`)
 * ----------------------------------------------------------------------
 * Both work; the class wins on four counts specific to THIS gem.
 *   1. Composition. A wrapper very often already carries `class:` in the ERB
 *      helper and pattern partials; adding a token to that string needs no
 *      new helper argument and no rewrite of the tag call to pass a data hash,
 *      at the ~40 call sites that render a layout shell.
 *   2. The prefix contract. `.os-*` IS the gem's public surface (README →
 *      Versioning) and the no-legacy-prefix gate polices it. A data attribute
 *      would be a second, unpoliced public namespace with its own rules.
 *   3. Tooling. hallmark, the alias gate and the component index all read
 *      CLASSES. A density expressed as an attribute is invisible to every
 *      one of them, including the lookalike detector that would otherwise
 *      catch a consumer hand-rolling a 48px button instead of scoping it.
 *   4. Specificity honesty. Attribute and class selectors have identical
 *      specificity, so the attribute buys nothing there — but it DOES read
 *      as configuration rather than styling, which invites consumers to set
 *      it from server state. Density is a layout decision, not data.
 *
 * The counter-argument (an attribute self-documents its allowed values) is
 * answered by this file: the four steps are enumerated here, in one place.
 *
 * SCOPES NEST. The trio is inherited, so an inner scope overrides an outer
 * one — a `--touch` page may hold a `--compact` toolbar. That falls out of
 * the cascade; no extra rules.
 *
 * WHAT DENSITY DOES NOT TOUCH — the back-compat contract.
 * Every explicit size modifier (.os-btn--sm/--lg/--field/--touch/--icon/--xs,
 * .os-field--sm, .os-select--sm …) re-declares the trio ON ITSELF. A
 * declaration on the element always beats one inherited from an ancestor, so
 * a modifier renders at its documented size inside ANY density scope. This is
 * both the compatibility guarantee for pinned consumers and the right
 * semantics: "make this button small" is an instruction about that button.
 * Density only sizes controls that did not ask for a specific size.
 *
 * Loaded via tokens.css after primitives + semantic. Scope rules cannot live
 * in primitives.css: that file is a single :root block by contract.
 */
/* ── The four density steps ──────────────────────────────────────────────
   Named for the SURFACE they describe, not the pixel value, so a consumer
   picks by intent. Each step re-points all three tokens together — height
   without matching padding and label size produces a stretched control. */
/* Dense desktop — data-heavy admin tables, toolbars, filter rows. 32px. */
.os-density--compact {
  --control-h:     var(--control-h-sm);
  --control-pad-x: var(--control-pad-x-sm);
  --control-fs:    var(--control-fs-sm);
}
/* The system default — desktop admin. 36px. Exists as an explicit scope so a
   region can opt BACK OUT of an enclosing --touch/--field scope. */
.os-density--base {
  --control-h:     var(--control-h-base);
  --control-pad-x: var(--control-pad-x-base);
  --control-fs:    var(--control-fs-base);
}
/* Comfortable — small tablet, or a desktop form that wants air without going
   full field height. 40px: the rung that did not exist before v1.6.0, and the
   reason `--sm`-to-`--field` was a 14px cliff consumers papered over locally. */
.os-density--comfortable {
  --control-h:     var(--control-h-md);
  --control-pad-x: var(--control-pad-x-md);
  --control-fs:    var(--control-fs-md);
}
/* Form surfaces — controls align on the canonical 46px field baseline, so a
   button sitting inline with a select or datepicker matches it without the
   per-call-site `.os-btn--field` twin. */
.os-density--field {
  --control-h:     var(--control-h-field);
  --control-pad-x: var(--control-pad-x-field);
  --control-fs:    var(--control-fs-field);
}
/* Handheld / kiosk — 48pt minimum target. The originating case: a dive
   handheld used one-handed on a moving boat in direct sun, where a 32px
   filter button is below a safe target size and the consumer had to keep
   local classes because the gem offered no field-size variant of it. */
.os-density--touch {
  --control-h:     var(--control-h-touch);
  --control-pad-x: var(--control-pad-x-touch);
  --control-fs:    var(--control-fs-touch);
  --filter-btn-h:  calc(var(--control-h-touch) - 8px); /* 40px filter control */
}
@font-face { font-family:'Inter'; font-style:normal; font-weight:100 900; font-display:swap; src:url("/assets/inter-var-9b45d99b.woff2") format('woff2'); }
@font-face { font-family:'Geist Mono'; font-style:normal; font-weight:400; font-display:swap; src:url("/assets/GeistMono-Regular-8d81938c.woff2") format('woff2'); }
@font-face { font-family:'Geist Mono'; font-style:normal; font-weight:500; font-display:swap; src:url("/assets/GeistMono-Medium-0fcc9bdd.woff2") format('woff2'); }
@font-face { font-family:'Geist Mono'; font-style:normal; font-weight:600; font-display:swap; src:url("/assets/GeistMono-SemiBold-b24349fd.woff2") format('woff2'); }
/* patterns.css — 11 shared composition components (Section label, KPI
   strip, Open row, Ledger row, Side panel, etc.). docs/archive/UI-MIGRATION-PLAN.md
   T3. Loaded after tokens.css so semantic vars resolve. */
/*
 * Bullet Train's base CSS applies a global `a:hover { text-decoration-
 * line: underline; color: secondary-600; }` to every anchor. That
 * overrides custom hover treatments because text-decoration-line is
 * different from text-decoration (the latter doesn't reset the former).
 * Reset hover behavior for the custom link classes used in patterns +
 * shell. They handle their own hover state via background-color +
 * color changes — no underline, no link recoloring.
 */
/* Reset BT's global a:hover (text-decoration-line: underline + color
   secondary-600) for our custom link components. Also reset base a
   color (BT sets a { color: var(--secondary-500) }) so descendant text
   inherits --text-primary instead of the link blue. Both rules need
   to be on the parent anchor — the children inherit from there. */
.os-sidebar__link, .os-sidebar__owner, :is(.open-row__link, .os-open-row__link), :is(.ledger-row__link, .os-ledger-row__link), :is(.filter-pill, .os-filter-pill), :is(.segmented__option, .os-segmented__option), :is(.tabs__tab, .os-tabs__tab), :is(.settings-sub-nav__link, .os-settings-sub-nav__link), :is(.trip-row__link, .os-trip-row__link), :is(.setting-item--linked, .os-setting-item--linked), :is(.header-zone__action-button, .os-header-zone__action-button), :is(.org-outlet-row, .os-org-outlet-row), :is(.lead-card-clickable__link, .os-lead-card-clickable__link), :is(.run-reopen-row, .os-run-reopen-row) {
  color: inherit;
}
.os-sidebar__link:hover, .os-sidebar__owner:hover, :is(.open-row__link, .os-open-row__link):hover, :is(.ledger-row__link, .os-ledger-row__link):hover, :is(.filter-pill, .os-filter-pill):hover, :is(.segmented__option, .os-segmented__option):hover, :is(.tabs__tab, .os-tabs__tab):hover, :is(.settings-sub-nav__link, .os-settings-sub-nav__link):hover, :is(.trip-row__link, .os-trip-row__link):hover, :is(.setting-item--linked, .os-setting-item--linked):hover, :is(.header-zone__action-button, .os-header-zone__action-button):hover, :is(.org-outlet-row, .os-org-outlet-row):hover, :is(.lead-card-clickable__link, .os-lead-card-clickable__link):hover, :is(.run-reopen-row, .os-run-reopen-row):hover {
  text-decoration-line: none;
  color: inherit;
}
/* Hover background colors set explicitly elsewhere; preserve the
   defined hover states for backgrounds. */
.os-sidebar__link:hover { color: var(--interactive-hover); }
.os-sidebar__item--active .os-sidebar__link:hover { color: var(--accent-strong); }
:is(.filter-pill, .os-filter-pill):hover { color: var(--interactive-hover); }
:is(.filter-pill--active, .os-filter-pill--active):hover { color: var(--accent-strong); }
:is(.segmented__option, .os-segmented__option):hover { color: var(--interactive-hover); }
:is(.tabs__tab, .os-tabs__tab):hover { color: var(--interactive-hover); }
:is(.settings-sub-nav__link, .os-settings-sub-nav__link):hover { color: var(--interactive-hover); }
:is(.settings-sub-nav__item--active, .os-settings-sub-nav__item--active) :is(.settings-sub-nav__link, .os-settings-sub-nav__link):hover { color: var(--accent-strong); }
/*
 * patterns.css — DiveOS shared pattern styles
 *
 * One file per concern would be tidier but Propshaft imports flat. The
 * patterns live here in the same order as UI-ARCHITECTURE.md §4 so a
 * reader scrolling the spec finds the CSS for each pattern in sequence.
 *
 * Resolves all colors through tokens.css semantic aliases (light-only
 * since v4 — dark mode removed per the diveOS-design-system repo spec).
 *
 * Inter is the body font (loaded by tokens.css). Geist Mono is used for
 * any tabular-nums context (time anchors, KPI values, capacity ratios).
 * Apply via inline class `font-mono` or local rule.
 */
/* ─── Text roles ────────────────────────────────────────────────────────
   Named typographic roles. Use these instead of hand-speccing
   size/weight/transform/tracking/color inline (the `text-[10px] uppercase
   tracking-[0.08em] text-muted` soup that recurs in ~47 files). Each maps to a
   --text-* token, so nothing is off-scale. They carry NO layout (no margins /
   display) so they compose on any element — for a standalone eyebrow WITH
   block spacing use .section-label; for a card's header use .dv-card__title.
   Role names, not size names (body-14 etc.): a name shouldn't lie when the
   scale shifts. Each role names its px in the comment for reference. */
/* Headings — structural h1–h5 classes that apply a heading level's appearance
   to ANY element, decoupled from the semantic tag (à la Primer .h1–.h6 / Carbon
   heading tokens / Polaris headingXl–Sm). Decoupling is deliberate: pick the
   tag for document structure, the class for size — bare <h1>–<h5> stay on
   Tailwind's preflight reset so a level never forces a size. Semantic role
   aliases share each style (.dv-title === .dv-h4), so both vocabularies work
   with one definition. Display font, 600, tight tracking. */
.os-h1, .os-display  { font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 600; line-height: var(--leading-3xl); letter-spacing: -0.025em; color: var(--ink); }
/* 28/36 — page hero */
.os-h2, .os-title-lg { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 600; line-height: var(--leading-2xl); letter-spacing: -0.02em;  color: var(--ink); }
/* 24/32 — major section */
.os-h3               { font-family: var(--font-display); font-size: var(--text-xl);  font-weight: 600; line-height: var(--leading-xl);  letter-spacing: -0.015em; color: var(--ink); }
/* 20/28 — subsection */
.os-h4, .os-title    { font-family: var(--font-display); font-size: var(--text-lg);  font-weight: 600; line-height: var(--leading-lg);  letter-spacing: -0.01em;  color: var(--ink); }
/* 18/28 — card / panel heading */
.os-h5, .os-title-sm { font-family: var(--font-display); font-size: var(--text-md);  font-weight: 600; line-height: var(--leading-md);  letter-spacing: -0.01em;  color: var(--ink); }
/* 16/24 — small heading */
/* Subtitle — supporting subhead under a title. */
.os-subtitle { font-size: var(--text-md); line-height: var(--leading-md); color: var(--muted); }
/* 16/24 — muted lead-in */
/* Body. */
.os-body-lg  { font-size: var(--text-md); line-height: var(--leading-md); color: var(--ink); }
/* 16/24 — roomy body */
.os-body     { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--ink); }
/* 14/22 — default body */
.os-small    { font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--ink); }
/* 12/18 — small print */
.os-eyebrow {                         /* micro uppercase label — "STATUS", "BOAT" */
  font-size: var(--text-2xs);         /* 10px */
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.os-meta {                            /* secondary / supporting line */
  font-size: var(--text-xs);          /* 12px */
  color: var(--muted);
}
/* Mono variant — a dense monospace meta line (cabin/pax/ref codes). Geist Mono
   via --font-mono, one step smaller. Self-contained (carries the muted colour
   so it reads the same standalone or alongside .os-meta). From arena .ao-meta. */
.os-meta--mono {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);         /* 10px */
  color: var(--muted-2);
}
/* Mono numerals — tabular figures for money / IDs / counts (Geist Mono via
   --font-mono). Standalone; the gem previously had .os-mono only SCOPED inside
   header-band/popover. From arena .ao-mono. */
.os-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.os-figure {                          /* numeric — money / rate / id / count */
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
/* Tone modifiers — additive; defined AFTER the base color rule so the semantic
   tone wins the cascade over the base color:var(--ink). Signals a status zone
   on a figure (e.g. pricing floor / recommended / ceiling). Token-only. */
.os-figure--confirmed { color: var(--confirmed); }
.os-figure--cancelled { color: var(--cancelled); }
.os-figure--pending   { color: var(--pending); }
.os-figure--accent    { color: var(--accent); }
.os-figure--muted     { color: var(--muted); }
/* notional / de-emphasised figure */
.os-caption {                         /* quietest micro caption */
  font-size: var(--text-2xs);         /* 10px */
  color: var(--muted-2);
}
/* ─── Standalone primitives promoted from arena-ops (HotelOS) 2026-07-25 ──────
   The gem previously had these names only SCOPED (a toolbar divider, a
   setting-item dot, a sum-prog row). These are the general-purpose standalone
   versions. Token-only. */
/* Divider — a hairline separator. --thin stretches to fill a flex row (a
   section rule between a label and the row edge); was arena .ao-rule. */
.os-divider { border: 0; margin: 0; height: 1px; background: var(--hairline); }
.os-divider--thin { flex: 1; height: 1px; align-self: center; background: var(--hairline); }
/* Dot — a small status dot; colour via currentColor so a parent/inline colour
   drives it. --lit adds a soft ring. Was arena .ao-dot. */
.os-dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: currentColor; flex: none; }
.os-dot--lit { box-shadow: 0 0 0 3px var(--accent-soft); }
/* Row — a general list row: flex, vertically CENTRED (the scoped sum-prog row
   was baseline-aligned), hover highlight. Was arena .ao-row. */
.os-row { display: flex; align-items: center; gap: var(--space-3); transition: background var(--t-fast) var(--ease-standard); }
.os-row:hover { background: var(--canvas); }
/* ─── Section label ─────────────────────────────────────────────────── */
:is(.section-label, .os-section-label) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin: 24px 0 8px;
  line-height: 1.4;
}
/* ─── Layout primitives: Stack + Inline ─────────────────────────────────
   Name the layout instead of hand-rolling `flex flex-col gap-3` /
   `flex items-center gap-2`. Stack = vertical flow, Inline = horizontal flow,
   both with a token gap off the --space scale. (Polaris BlockStack/InlineStack,
   Primer Stack, Braid Stack/Inline.) Default gap = the common case; the size
   modifiers step the scale and apply to both. Inline centers + wraps by default;
   alignment/justify modifiers cover the rest. */
.os-stack  { display: flex; flex-direction: column; gap: var(--space-3); }
/* 12 */
.os-inline { display: flex; flex-direction: row; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
/* 8 */
/* Gap steps (both Stack + Inline). */
.os-stack--xs, .os-inline--xs { gap: var(--space-1); }
/* 4 */
.os-stack--sm, .os-inline--sm { gap: var(--space-2); }
/* 8 */
.os-stack--md, .os-inline--md { gap: var(--space-3); }
/* 12 */
.os-stack--lg, .os-inline--lg { gap: var(--space-4); }
/* 16 */
.os-stack--xl, .os-inline--xl { gap: var(--space-6); }
/* 24 */
/* Cross-axis + main-axis modifiers. */
.os-stack--center    { align-items: center; }
.os-inline--top      { align-items: flex-start; }
.os-inline--baseline { align-items: baseline; }
.os-inline--between  { justify-content: space-between; }
.os-inline--end      { justify-content: flex-end; }
.os-inline--nowrap   { flex-wrap: nowrap; }
/* ─── KPI strip ─────────────────────────────────────────────────────── */
:is(.kpi-strip, .os-kpi-strip) {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 28px 36px;
  margin: 0 0 28px;
  padding: 16px 0 0;
  border-top: 1px solid var(--border);
}
:is(.kpi-strip__stat, .os-kpi-strip__stat) {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
:is(.kpi-strip__value, .os-kpi-strip__value) {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-3xl);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  line-height: 1;
  margin: 0;
}
:is(.kpi-strip__label, .os-kpi-strip__label) {
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  color: var(--text-muted);
  margin: 0;
}
/* ─── StatBand — bordered metrics card (content-pane sibling of kpi_strip)
   2–5 cells, big tabular number over an uppercase label, inner hairlines.
   Sits on the gray canvas (NOT in the header band). Cell count via --cols.
   Spec: Design/agent-view-dive-sites-stat-card/handover/stat-band/. ──────── */
:is(.stat-band, .os-stat-band) {
  display: grid;
  grid-template-columns: repeat(var(--cols, 4), 1fr);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  margin-bottom: 20px;
}
:is(.stat-band__cell, .os-stat-band__cell) {
  padding: 18px 20px;
  border-left: 1px solid var(--hairline-2);
}
:is(.stat-band__cell, .os-stat-band__cell):first-child { border-left: 0; }
:is(.stat-band__label, .os-stat-band__label) {
  font-family: var(--font-sans);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
:is(.stat-band__value, .os-stat-band__value) {
  margin-top: 9px;
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--ink);
}
:is(.stat-band__unit, .os-stat-band__unit) { font-size: 0.6em; font-weight: 500; color: var(--muted); }
:is(.stat-band__value--display, .os-stat-band__value--display) { font-family: var(--font-display); font-variant-numeric: normal; }
:is(.stat-band__value--positive, .os-stat-band__value--positive)  { color: var(--status-confirmed-fg); }
:is(.stat-band__value--attention, .os-stat-band__value--attention) { color: var(--status-briefing-fg); }
:is(.stat-band__value--negative, .os-stat-band__value--negative)  { color: var(--status-cancelled-fg); }
:is(.stat-band__value--empty, .os-stat-band__value--empty)     { color: var(--muted-2); font-weight: 500; }
/* Vertical variant — single column, cells stacked with top hairlines.
   For a narrow rail (e.g. dive-site facts) where vertical space is ample. */
:is(.stat-band--vertical, .os-stat-band--vertical) { grid-template-columns: 1fr; }
:is(.stat-band--vertical, .os-stat-band--vertical) :is(.stat-band__cell, .os-stat-band__cell) { border-left: 0; border-top: 1px solid var(--hairline-2); }
:is(.stat-band--vertical, .os-stat-band--vertical) :is(.stat-band__cell, .os-stat-band__cell):first-child { border-top: 0; }
@media (max-width: 640px) {
  :is(.stat-band, .os-stat-band) { grid-template-columns: repeat(2, 1fr); }
  :is(.stat-band__cell, .os-stat-band__cell):nth-child(odd)   { border-left: 0; }
  :is(.stat-band__cell, .os-stat-band__cell):nth-child(n + 3) { border-top: 1px solid var(--hairline-2); }
}
/* ─── Stat card — clickable KPI/filter tile ─────────────────────────────
   A bordered tile (swatch + label, big tabular value, sub-line) that toggles
   a filter when clicked. Replaces hand-rolled utility-soup tiles (gear
   category KPIs) that drifted off the type scale and underlined on hover
   because BT's global a:hover beat the `no-underline` utility. As an <a> it
   resets its own hover underline. Sizes are tokens, not raw px. */
.os-stat-card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  text-decoration: none;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.os-stat-card:hover { border-color: var(--hairline-strong); text-decoration: none; }
.os-stat-card--active { border-color: var(--accent); background: var(--accent-softer); }
.os-stat-card--active:hover { border-color: var(--accent); }
.os-stat-card__head { display: flex; align-items: center; gap: var(--space-2); }
.os-stat-card__swatch { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.os-stat-card__label {
  font-family: var(--font-display); font-size: var(--text-sm); font-weight: 500; color: var(--ink);
}
.os-stat-card__value {
  font-family: var(--font-mono); font-size: var(--text-lg); font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--ink); line-height: 1; margin-top: 6px;
}
.os-stat-card__sub { font-size: var(--text-2xs); font-weight: 500; color: var(--muted); margin-top: 6px; }
.os-stat-card__sub--due { color: var(--briefing); }
/* ─── Header zone ───────────────────────────────────────────────────── */
:is(.header-zone, .os-header-zone) {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
}
:is(.header-zone__title, .os-header-zone__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-3xl);
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--text-primary);
  margin: 0;
}
:is(.header-zone__meta, .os-header-zone__meta) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  margin: 8px 0 0;
}
:is(.header-zone__actions, .os-header-zone__actions) {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
:is(.header-zone__action-button, .os-header-zone__action-button) {
  display: inline-flex;
  align-items: center;
  padding: 8px 14px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 150ms ease-out;
}
:is(.header-zone__action-button, .os-header-zone__action-button):hover { background: var(--surface-alt); }
:is(.header-zone__action-button, .os-header-zone__action-button):disabled { opacity: 0.5; cursor: not-allowed; }
:is(.header-zone__action-button--primary, .os-header-zone__action-button--primary) {
  background: var(--accent);
  color: #FFFFFF;
  border-color: var(--accent);
}
:is(.header-zone__action-button--primary, .os-header-zone__action-button--primary):hover { background: var(--accent-strong); border-color: var(--accent-strong); }
/* Destructive action — used for bottom-LEFT footer actions in side panels
   (Set inactive, Retire item). Ghost background + danger/red text; on hover it
   gains a soft red tint and red border so the destructive intent reads clearly
   without competing with the filled primary on the right. */
:is(.header-zone__action-button--danger, .os-header-zone__action-button--danger) {
  background: transparent;
  color: var(--cancelled);
  border-color: transparent;
}
:is(.header-zone__action-button--danger, .os-header-zone__action-button--danger):hover {
  background: var(--cancelled-bg);
  color: var(--cancelled);
  border-color: var(--cancelled-border);
}
/* ─── Dives surface specifics ──────────────────────────────────────── */
:is(.dives-view-bar, .os-dives-view-bar) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin: 8px 0 16px;
}
:is(.dives-list, .os-dives-list) {
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
}
:is(.dives-empty, .os-dives-empty) {
  padding: 64px 16px;
  text-align: center;
  color: var(--text-muted);
}
:is(.dives-empty--wide, .os-dives-empty--wide) { padding: 96px 16px 64px; }
:is(.dives-empty__line, .os-dives-empty__line) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  color: var(--text-secondary);
  margin: 0 0 8px;
}
:is(.dives-empty__hint, .os-dives-empty__hint) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
  max-width: 360px;
  margin-left: auto;
  margin-right: auto;
}
/* ─── Drawer body lists (Divers / Stops tabs) ──────────────────────── */
:is(.drawer-list, .os-drawer-list) {
  list-style: none;
  padding: 0;
  margin: 0 0 8px;
}
:is(.drawer-empty, .os-drawer-empty) {
  color: var(--text-muted);
  font-style: italic;
  font-size: var(--text-sm);
  margin: 8px 0 16px;
}
:is(.drawer-notes, .os-drawer-notes) {
  font-size: var(--text-sm);
  color: var(--text-primary);
  line-height: 1.5;
  margin: 0 0 16px;
}
:is(.drawer-notes--incident, .os-drawer-notes--incident) { color: var(--red-700); }
/* ─── Settings shell layout (T12) ──────────────────────────────────── */
:is(.settings-layout, .os-settings-layout) {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 32px;
  margin-top: 8px;
}
@media (max-width: 1023px) {
  :is(.settings-layout, .os-settings-layout) { grid-template-columns: 1fr; gap: 16px; }
}
/* ─── Settings hub (v3): nav + detail split INSIDE the .diveos-main pane ──
   Container query, not viewport: the split lives in the pane (viewport − the
   240px sidebar), so at a ~1024px window the pane is ~784px and the 200px nav
   left the detail card only ~409px — the description wrapped one word per line
   and the status chips clipped. Stack on a narrow PANE so the cards get full
   width; the nav becomes a horizontal wrapping bar on top. */
:is(.settings-grid, .os-settings-grid) {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 32px;
  margin-top: 8px;
}
:is(.settings-subnav, .os-settings-subnav) { border-right: 1px solid var(--hairline); padding-right: 16px; }
:is(.settings-subnav__items, .os-settings-subnav__items) { display: flex; flex-direction: column; gap: 2px; }
/* Card fix FIRST (pane ≤880): the row's status chips drop BELOW the title/meta
   instead of competing for row width, so the description reads on a full measure
   line rather than one word per line. This alone de-cramps the card while the
   nav stays a 2-column rail — no need to stack the nav (which would leave a
   short section as one lonely card over a tall void). */
@container (max-width: 880px) {
  :is(.setting-item, .os-setting-item) { grid-template-columns: auto 1fr; row-gap: 8px; }
  :is(.setting-item__trail, .os-setting-item__trail) {
    grid-column: 2;
    flex-wrap: wrap;
    justify-content: flex-start;
  }
}
/* Legacy settings feature-cards (integrations, developer tools, PMS): the row
   is `icon | body(flex-1) | trailing action/status`. On a narrow pane the body
   collapses to one word per line and the trailing element crowds/overlaps it.
   Wrap the row so the trailing action drops to its own full-width line under the
   body, which keeps a readable measure. */
@container (max-width: 700px) {
  .os-feature-row { flex-wrap: wrap; row-gap: 12px; }
  .os-feature-row > .os-feature-row__end {
    flex-basis: 100%;
    justify-content: flex-start;
    max-width: none;
    text-align: left;
  }
}
/* Only stack the nav to a top bar once the pane is too narrow for the 200px
   rail + a usable detail column (phones / very narrow panes). */
@container (max-width: 640px) {
  :is(.settings-grid, .os-settings-grid) { grid-template-columns: 1fr; gap: 16px; }
  :is(.settings-subnav, .os-settings-subnav) {
    border-right: 0;
    border-bottom: 1px solid var(--hairline);
    padding-right: 0;
    padding-bottom: 10px;
  }
  :is(.settings-subnav__group, .os-settings-subnav__group) { margin-bottom: 10px; }
  :is(.settings-subnav__items, .os-settings-subnav__items) { flex-direction: row; flex-wrap: wrap; gap: 4px; }
}
:is(.settings-sub-nav, .os-settings-sub-nav) {
  border-right: 1px solid var(--border);
  padding-right: 16px;
}
@media (max-width: 1023px) {
  :is(.settings-sub-nav, .os-settings-sub-nav) { border-right: none; padding-right: 0; border-bottom: 1px solid var(--border); padding-bottom: 8px; }
  :is(.settings-sub-nav__items, .os-settings-sub-nav__items) { display: flex; flex-wrap: wrap; gap: 4px; }
}
:is(.settings-sub-nav__items, .os-settings-sub-nav__items) {
  list-style: none;
  padding: 0;
  margin: 0;
}
:is(.settings-sub-nav__item, .os-settings-sub-nav__item) { position: relative; }
:is(.settings-sub-nav__link, .os-settings-sub-nav__link) {
  display: block;
  padding: 8px 12px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--interactive);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background 150ms ease-out, color 150ms ease-out;
}
:is(.settings-sub-nav__link, .os-settings-sub-nav__link):hover {
  background: var(--surface-alt);
  color: var(--interactive-hover);
}
:is(.settings-sub-nav__item--active, .os-settings-sub-nav__item--active) :is(.settings-sub-nav__link, .os-settings-sub-nav__link) {
  background: var(--accent-tint);
  color: var(--accent-strong);
}
:is(.settings-sub-nav__item--active, .os-settings-sub-nav__item--active)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--accent);
  border-radius: 0 1px 1px 0;
}
@media (max-width: 1023px) {
  :is(.settings-sub-nav__item--active, .os-settings-sub-nav__item--active)::before { display: none; }
}
:is(.settings-content, .os-settings-content) { min-width: 0; }
/* ─── Settings nav item (redesigned, icon + label) ──────────────────────
   The grouped Settings sub-nav (Shop / Operations / People / Account) — an
   icon + label row that is the active section's accent-soft chip and warms on
   hover. Promotes the per-item utility soup (the hand-rolled active/hover
   string with an arbitrary hover:bg-[var(--hover-warm)]) into a token-driven
   component, mirroring how .dv-filter-bar scopes the filter row. The group
   heading uses .dv-eyebrow (named micro-label). */
.os-settings-nav__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  transition: background 150ms ease, color 150ms ease;
}
.os-settings-nav__item:hover, .os-settings-nav__item:focus-visible { background: var(--hover-warm); text-decoration: none; color: var(--ink); }
.os-settings-nav__item svg { color: var(--muted); flex-shrink: 0; }
.os-settings-nav__item.is-active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}
.os-settings-nav__item.is-active:hover { background: var(--accent-soft); color: var(--accent); }
.os-settings-nav__item.is-active svg { color: var(--accent); }
:is(.settings-link-list, .os-settings-link-list) {
  list-style: none;
  padding: 0;
  margin: 0;
}
/* Status summary grid — each section partial renders this above the link
   list to show at-a-glance configuration state. Two columns; --ok rows
   show in green-700, --todo rows in amber-700, both via tokens.css. */
:is(.settings-status, .os-settings-status) {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 24px;
  margin: 16px 0 24px;
  padding: 0;
}
@media (max-width: 1023px) {
  :is(.settings-status, .os-settings-status) { grid-template-columns: 1fr; }
}
:is(.settings-status__row, .os-settings-status__row) {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  margin: 0;
}
:is(.settings-status__label, .os-settings-status__label) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
}
:is(.settings-status__value, .os-settings-status__value) {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-primary);
  margin: 0;
  font-variant-numeric: tabular-nums;
}
:is(.settings-status__row--ok, .os-settings-status__row--ok) :is(.settings-status__value, .os-settings-status__value) {
  color: var(--green-700);
}
:is(.settings-status__row--todo, .os-settings-status__row--todo) :is(.settings-status__value, .os-settings-status__value) {
  color: var(--amber-700);
}
:is(.settings-status__swatch, .os-settings-status__swatch) {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
}
:is(.settings-status__hint, .os-settings-status__hint) {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-left: 6px;
}
/* ─── Modern settings list (card rows) ───────────────────────────────
   v4 modernization. Replaces the .settings-status stat-strip + tight
   ledger-row with richer card rows: leading icon, title + description,
   trailing status pill + chevron. One row per editable thing; status is
   folded onto the row (no separate stat-strip), counts neutral, only true
   needs-attention / healthy state takes color. */
:is(.setting-list, .os-setting-list) {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
}
:is(.setting-list__item, .os-setting-list__item) { margin: 0; }
:is(.setting-item, .os-setting-item) {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  transition: background 150ms ease;
}
:is(.setting-list__item, .os-setting-list__item):last-child :is(.setting-item, .os-setting-item) { border-bottom: 0; }
:is(.setting-item--linked, .os-setting-item--linked) { cursor: pointer; }
:is(.setting-item--linked, .os-setting-item--linked):hover { background: var(--hover-warm); }
:is(.setting-item__icon, .os-setting-item__icon) {
  width: 36px;
  height: 36px;
  border-radius: 9px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  flex-shrink: 0;
}
:is(.setting-item__body, .os-setting-item__body) {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
:is(.setting-item__title, .os-setting-item__title) {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
:is(.setting-item__meta, .os-setting-item__meta) {
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: 1.4;
}
:is(.setting-item__trail, .os-setting-item__trail) {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
:is(.setting-item__pill, .os-setting-item__pill) {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1;
  padding: 4px 9px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
:is(.setting-item__pill--count, .os-setting-item__pill--count) { background: var(--surface-alt); color: var(--text-muted); border-color: var(--border); }
:is(.setting-item__pill--warn, .os-setting-item__pill--warn)  { background: var(--status-briefing-bg);  color: var(--amber-700); border-color: var(--status-briefing-border, var(--border)); }
:is(.setting-item__pill--ok, .os-setting-item__pill--ok)    { background: var(--status-confirmed-bg);  color: var(--green-700); border-color: var(--status-confirmed-border, var(--border)); }
:is(.setting-item__pill, .os-setting-item__pill) :is(.dot, .os-dot) { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
:is(.setting-item__chevron, .os-setting-item__chevron) { color: var(--text-muted); display: inline-flex; align-items: center; }
:is(.setting-item--linked, .os-setting-item--linked):focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (prefers-reduced-motion: reduce) { :is(.setting-item, .os-setting-item) { transition: none; } }
/* ─── Filter bar ────────────────────────────────────────────────────── */
:is(.filter-bar, .os-filter-strip) {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-bottom: 16px;
}
:is(.filter-bar, .os-filter-strip)::-webkit-scrollbar { display: none; }
/* v4: aligned to the repo .chip spec — 28px pill, hairline border on
   surface; active = accent-soft bg + accent-border + accent text. */
:is(.filter-pill, .os-filter-pill) {
  display: inline-flex;
  align-items: center;
  /* A filter pill is deliberately ONE STEP SHORTER than the primary control
     beside it — it is a scoping affordance, not an action, and a strip of
     full-height pills reads as a row of buttons. 8px is that shipped offset
     (36 base minus 28), so at base density this computes to exactly the 28px
     literal it replaces. The 28px floor stops --compact shrinking a pill to
     an unhittable 24.

     THIS IS THE COMPONENT THE AUDIT WAS ABOUT: a filter control frozen at a
     desktop size, with no field or touch variant, on a surface used one-handed
     on a boat. It reaches 40px under .os-density--touch — over the safe target
     size — with no local class and no new per-component modifier. */
  height: max(28px, calc(var(--control-h) - 8px));
  padding: 0 12px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--interactive);
  background: var(--surface);
  border: 1px solid var(--interactive-border);
  border-radius: var(--radius-pill);
  text-decoration: none;
  transition: background 150ms ease-out;
}
:is(.filter-pill, .os-filter-pill):hover { background: var(--canvas); }
:is(.filter-pill--active, .os-filter-pill--active) {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent-border);
}
/* ─── Operations bar (.dv-opbar) ─────────────────────────────────────────
   Consolidated status + actions strip at the foot of a form-detail page
   (sharing / public-access / documents). Uses the shared cool blue-gray
   summary surface (#F2F5F9 / #D5DEEA — same as .ds-sum) so it reads as a
   DISTINCT operations panel, not another white form-field info_card. Status +
   meta on the left, action buttons + a QR tile on the right. Standard for
   status/CTA sections across forms. */
.os-opbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
  background: #F2F5F9;             /* shared cool blue-gray summary surface */
  border: 1px solid #D5DEEA;
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
}
.os-opbar__main { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.os-opbar__label {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--slate-500);
}
.os-opbar__label svg { color: var(--muted-2); }
.os-opbar__facts { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.os-opbar__meta { font-size: var(--text-sm); color: var(--muted); display: inline-flex; align-items: center; gap: 5px; }
.os-opbar__meta svg { color: var(--confirmed); }
.os-opbar__dot { color: var(--hairline-strong); }
.os-opbar__files { display: flex; gap: 16px; font-size: var(--text-sm); }
.os-opbar__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.os-opbar__actions form { margin: 0; }
/* QR on demand via a <details> popover (C variant — the inline thumbnail was
   the A variant). "Show QR" is a secondary button; the QR floats below it. */
.os-opbar__qrtoggle { position: relative; }
.os-opbar__qrtoggle > summary { list-style: none; cursor: pointer; }
.os-opbar__qrtoggle > summary::-webkit-details-marker { display: none; }
.os-opbar__qrtoggle > summary::marker { content: ""; }
.os-opbar__qrpop {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-panel);
  padding: 14px; text-align: center; width: -moz-max-content; width: max-content;
}
.os-opbar__qr { width: 132px; height: 132px; display: grid; place-items: center; }
.os-opbar__qr svg { width: 100%; height: 100%; display: block; }
.os-opbar__qrcap { display: block; font-size: var(--text-xs); color: var(--muted-2); margin-top: 8px; }
/* ─── Status pill ───────────────────────────────────────────────────── */
/* The gem owns the FULL component: base, size/shape modifiers, the seven
   colour variants, the child elements, and the interactive (button) states.
   Every variant is a pure pass-through to the --status-<key>-{bg,fg,border}
   tokens in tokens/semantic.css, so the palette is defined once, here.

   A consuming app supplies only two things: the human LABEL, and the mapping
   from its own domain status to a variant key (e.g. a status-palette helper
   deciding that an unpaid invoice is `--pending`). It must NOT redefine any
   `.status-pill*` rule locally — a local copy silently overrides the gem and
   the two systems drift apart. */
:is(.status-pill, .os-status-pill) {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
/* Leading Lucide glyph inside the pill. This rule MUST live here: the gem's
   own `status_icon_svg` (helpers/os_ds/status_palette_helper.rb) emits
   `class="status-icon"`, so a gem-rendered icon would be unstyled if the rule
   sat in a consuming app. Sized in fixed px rather than a token — it tracks the
   pill's 12px optical glyph size, not the type scale. */
:is(.status-icon, .os-status-icon) { width: 12px; height: 12px; flex-shrink: 0; }
/* Size modifier (mirrors .dv-badge--sm) */
:is(.status-pill--sm, .os-status-pill--sm) { font-size: var(--text-2xs); padding: 2px 8px; }
/* Shape modifier: square uppercase tag (mirrors .dv-badge--square) */
:is(.status-pill--square, .os-status-pill--square) {
  border-radius: 5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--text-2xs);
  padding: 3px 8px;
}
:is(.status-pill__label, .os-status-pill__label) { line-height: 1; }
:is(.status-pill__dot, .os-status-pill__dot) {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
/* Legacy alias: `.status-pill-dot` (single dash) is the pre-BEM spelling of
   `.status-pill__dot` and is still used by host-app views. Kept so those
   callers keep rendering; prefer `.status-pill__dot` in new markup. */
:is(.status-pill-dot, .os-status-pill-dot) {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
/* Colour variants — pure token pass-throughs. Palette pivot 2026-05-23:
   Confirmed=green (was blue), In Water=sky (was emerald). The theme is
   light-only, so there is no dark branch here or in the tokens. */
:is(.status-pill--pending, .os-status-pill--pending)   { background: var(--status-pending-bg);   border-color: var(--status-pending-border);   color: var(--status-pending-fg); }
:is(.status-pill--confirmed, .os-status-pill--confirmed) { background: var(--status-confirmed-bg); border-color: var(--status-confirmed-border); color: var(--status-confirmed-fg); }
:is(.status-pill--briefing, .os-status-pill--briefing)  { background: var(--status-briefing-bg);  border-color: var(--status-briefing-border);  color: var(--status-briefing-fg); }
:is(.status-pill--in_water, .os-status-pill--in_water)  { background: var(--status-in-water-bg);  border-color: var(--status-in-water-border);  color: var(--status-in-water-fg); }
:is(.status-pill--returning, .os-status-pill--returning) { background: var(--status-returning-bg); border-color: var(--status-returning-border); color: var(--status-returning-fg); }
:is(.status-pill--completed, .os-status-pill--completed) { background: var(--status-completed-bg); border-color: var(--status-completed-border); color: var(--status-completed-fg); }
:is(.status-pill--cancelled, .os-status-pill--cancelled) { background: var(--status-cancelled-bg); border-color: var(--status-cancelled-border); color: var(--status-cancelled-fg); }
/* NON-STATUS variants. Everything above names a dive/stay STATE; these two name
   an EMPHASIS, for pills that are not statuses at all — a count, a label, a
   flag. Added because a consuming product had built its own tag family whose
   only genuinely missing colours were these two, while its `--alert` and
   `--warn` turned out to be exact duplicates of `--cancelled` and `--briefing`.
   Naming them here keeps a product from re-deriving a parallel pill set just to
   get "accent" and "muted". */
:is(.status-pill--accent, .os-status-pill--accent) { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent-strong); }
:is(.status-pill--muted, .os-status-pill--muted)  { background: var(--surface-alt); border-color: var(--hairline);      color: var(--muted); }
/* Editable status pill — the badge-dropdown trigger is a button.status-pill.
   It gets interaction affordances the static pill never does: a subtle hover
   and a token-driven focus-visible ring. The static .status-pill stays inert. */
button:is(.status-pill, .os-status-pill) {
  cursor: pointer;
  /* No resting shadow — the chevron + hover brightness carry the control
     affordance. (A shadow here reads as unwanted elevation on a flat chip.) */
  transition: filter 120ms ease;
}
button:is(.status-pill, .os-status-pill):hover {
  filter: brightness(0.97);
}
button:is(.status-pill, .os-status-pill):focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* ─── Open row ──────────────────────────────────────────────────────── */
:is(.open-row, .os-open-row) {
  list-style: none;
  border-bottom: 1px solid var(--border);
}
:is(.open-row__link, .os-open-row__link), :is(.open-row, .os-open-row) > *:not(:has(:is(.open-row__link, .os-open-row__link))) {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  gap: 24px;
  align-items: center;
  padding: 16px;
  text-decoration: none;
  color: inherit;
  min-height: 96px;
}
:is(.open-row__link, .os-open-row__link) { transition: background 150ms ease-out; }
:is(.open-row__link, .os-open-row__link):hover { background: var(--surface-alt); }
:is(.open-row__time-block, .os-open-row__time-block) {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
:is(.open-row__time, .os-open-row__time) {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-3xl);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  line-height: 1;
}
:is(.open-row__time-meta, .os-open-row__time-meta) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 6px;
}
:is(.open-row__body, .os-open-row__body) { min-width: 0; }
:is(.open-row__primary, .os-open-row__primary) {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 4px;
}
:is(.open-row__title, .os-open-row__title) {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--text-md);
  color: var(--text-primary);
}
:is(.open-row__meta, .os-open-row__meta) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
  line-height: 1.4;
}
:is(.open-row__right, .os-open-row__right) {
  text-align: right;
}
:is(.open-row__right-value, .os-open-row__right-value) {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-2xl);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  line-height: 1;
}
:is(.open-row__right-label, .os-open-row__right-label) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 4px;
}
/* ─── Ledger row ────────────────────────────────────────────────────── */
:is(.ledger-row, .os-ledger-row) {
  list-style: none;
  border-bottom: 1px solid var(--border);
}
:is(.ledger-row__link, .os-ledger-row__link), :is(.ledger-row, .os-ledger-row) > *:not(:has(:is(.ledger-row__link, .os-ledger-row__link))) {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 12px 16px;
  min-height: 48px;
  text-decoration: none;
  color: inherit;
}
:is(.ledger-row__link, .os-ledger-row__link) { transition: background 150ms ease-out; }
:is(.ledger-row__link, .os-ledger-row__link):hover { background: var(--surface-alt); }
:is(.ledger-row__time, .os-ledger-row__time) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  color: var(--text-muted);
  flex-shrink: 0;
  width: 60px;
}
:is(.ledger-row__title, .os-ledger-row__title) {
  font-size: var(--text-sm);
  color: var(--text-primary);
  flex: 1;
}
:is(.ledger-row__meta, .os-ledger-row__meta) {
  font-size: var(--text-sm);
  color: var(--text-muted);
}
:is(.ledger-row__value, .os-ledger-row__value) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: var(--text-sm);
  color: var(--text-primary);
  flex-shrink: 0;
}
/* ─── Side panel (drawer) ───────────────────────────────────────────── */
:is(.side-panel, .os-side-panel) {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface);
}
:is(.side-panel__header, .os-side-panel__header) {
  padding: 22px 24px 16px;
  border-bottom: 1px solid var(--border);
}
:is(.side-panel__eyebrow, .os-side-panel__eyebrow) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 8px;
}
:is(.side-panel__close, .os-side-panel__close) {
  float: right;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  transition: background 150ms ease-out, color 150ms ease-out;
}
:is(.side-panel__close, .os-side-panel__close):hover {
  background: var(--surface-alt);
  color: var(--text-primary);
}
/* --split — OPT-IN header layout for drawers that pair a wrapped title/subtitle
   block with the close on one row. The DEFAULT header stays block-flow (the
   close floats, title/subtitle stack as direct children) — do NOT flex the
   header by default: consumers that place title/subtitle as direct children
   would have them laid out horizontally. Under --split the header becomes a
   flex row and the close right-aligns via auto inline-start margin instead of
   the float (float is a no-op inside a flex container). align-items:flex-start
   keeps the close pinned to the top while the title block sets the row height. */
:is(.side-panel__header--split, .os-side-panel__header--split) {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
:is(.side-panel__header--split, .os-side-panel__header--split) :is(.side-panel__close, .os-side-panel__close) {
  float: none;
  margin-inline-start: auto;
}
:is(.side-panel__close-icon, .os-side-panel__close-icon) { width: 18px; height: 18px; stroke-width: 1.75; }
:is(.side-panel__title, .os-side-panel__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-xl);
  color: var(--text-primary);
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}
/* Title + status on one row, meta drops below (booking drawer, #113). */
:is(.side-panel__title-row, .os-side-panel__title-row) {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 8px;
}
:is(.side-panel__title--inline, .os-side-panel__title--inline) {
  margin: 0;
}
:is(.side-panel__subtitle, .os-side-panel__subtitle) {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
}
:is(.side-panel__meta, .os-side-panel__meta) {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--text-sm);
  color: var(--text-muted);
}
:is(.side-panel__tab-zone, .os-side-panel__tab-zone) {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* Tab bar shares the panel's 24px gutter (header/body) instead of sitting
   flush-left. Applies to every drawer that uses the side_panel chrome. */
:is(.side-panel__tab-zone, .os-side-panel__tab-zone) > :is(.tabs, .os-tabs) { padding-left: 24px; padding-right: 24px; }
:is(.side-panel__body, .os-side-panel__body) {
  flex: 1;
  overflow-y: auto;
  padding: 20px 24px;
  /* Positioning context so absolutely-positioned descendants (e.g. the
     `.dv-segment__input.sr-only` DIN/INT radios) are contained by the
     scroll body, not the `position: fixed` `.side-drawer` wrapper. Without
     this, focusing a visually-hidden control scroll-into-views the fixed
     wrapper and yanks the whole panel off-screen ("drawer scroll broke"). */
  position: relative;
}
:is(.side-panel__action-bar, .os-side-panel__action-bar) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
:is(.side-panel__action-bar-left, .os-side-panel__action-bar-left) { flex: 1; }
:is(.side-panel__action-bar-right, .os-side-panel__action-bar-right) {
  display: flex;
  gap: 8px;
  /* Always pin to the right edge. With a left/destructive action present the
     flex:1 left pushes us right (left|……|right); with no left action the
     margin-left:auto still drives us to the right edge so a lone primary CTA
     is bottom-right by default (not flex-start/left). */
  margin-left: auto;
}
/* Single-CTA footers (e.g. the booking quick-view "View full booking") pin
   their one action to the right edge. Now redundant since the default
   right-aligns via margin-left:auto — kept for any explicit callers. */
:is(.side-panel__action-bar--end, .os-side-panel__action-bar--end) { justify-content: flex-end; }
/* Width modifier — opt-in wider (560px) read-only summary drawer. Add
   `.side-panel--wide` to the `.side-panel` section when a surface needs the
   roomier variant. */
:is(.side-panel--wide, .os-side-panel--wide) { max-width: 560px; }
/* ─── Field grid ────────────────────────────────────────────────────── */
:is(.field-grid, .os-field-grid) {
  display: grid;
  /* v1.41.0: minmax(0, 1fr), not 1fr — a bare 1fr track's minimum is its
     content's min-content, so a select with a long option widened its column
     past a phone screen and squeezed its neighbour (dive-os Staff roles). */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
/* Cancel the stacked-field rhythm inside any field grid — the columns are
   adjacent siblings, so the `.os-field + .os-field` top-margin in forms.css
   would push every non-first cell down and break horizontal alignment across
   columns. The grid `gap` owns spacing. Shared by `.field-grid` and
   `.field-split` so the twin patterns can't drift apart. */
:is(.field-grid, .os-field-grid, .field-split, .os-field-split) .os-field + .os-field { margin-top: 0; }
:is(.field-grid__field--span-2, .os-field-grid__field--span-2) { grid-column: 1 / -1; }
/* v1.36.0 (#493): controls in one row line up even when a label wraps.
   v1.22.2 fixed the 22px STACK stagger; this fixes the LABEL stagger — a
   two-line label pushed its control below its neighbour's. Each field cell
   becomes a subgrid over a shared group of row tracks, so row 1 (label) is as
   tall as the tallest label in that row and every control starts on row 2.
   Hints/errors flow into rows 3+, so differing messages never move a control
   (alignment is on the control, not the cell bottom).
   - Every direct child spans the same 6 tracks (label, control, 2 messages,
     2 spare) so auto-placement keeps the 2-column flow. Empty tracks are 0px
     because the grid's row gap is 0 — a non-zero parent gap would open on the
     spare tracks.
   - The 16px between rows moves from `row-gap` to padding-top on every cell
     past the first row (margin-top for non-field children). Padding, not
     margin, so the v1.22.2 `.os-field + .os-field` margin reset can't eat it.
   - `.os-field__input` (the DiveOS field shell's control wrapper) is pinned to
     row 2 so a visually-hidden (sr-only, out-of-flow) label still leaves the
     control on the control line. */
:is(.field-grid, .os-field-grid) { row-gap: 0; }
:is(.field-grid, .os-field-grid) > * { grid-row: span 6; margin-top: 16px; }
:is(.field-grid, .os-field-grid) > :is(.field-grid__field, .os-field-grid__field, .os-field):not([hidden], .hidden) {
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  margin-top: 0;
  padding-top: 16px;
}
:is(.field-grid, .os-field-grid) > * > .os-field__input { grid-row: 2; }
/* v1.41.0: a cell is a grid (the subgrid above), so its control is a grid item
   with min-width: auto — a date/time input's intrinsic width (~156px) beat a
   phone column and overran the cell. Controls directly in a cell (or in the
   field shell's .os-field__input) may shrink to the column; nested controls
   (the time picker's HH/MM boxes) keep their own sizing. */
:is(.field-grid, .os-field-grid) > * > :is(input, select, textarea),
:is(.field-grid, .os-field-grid) > * > .os-field__input > :is(input, select, textarea) { min-width: 0; }
/* The first row has no gap above it. "First" skips hidden inputs/templates; the
   second cell joins row 1 unless either of the first two spans both columns. */
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden], .hidden)),
:is(.field-grid, .os-field-grid) > :nth-child(1 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2)
  ~ :nth-child(2 of :not(input[type="hidden"], template, [hidden], .hidden)):not(.field-grid__field--span-2, .os-field-grid__field--span-2) {
  margin-top: 0;
  padding-top: 0;
}
/* v1.41.0: phones (≤640) — one column. Two fields side by side left each
   ~140px. With one column the 2nd cell is off row 1, so it gets the row gap
   back. !important + :not(#_) because consuming apps whose build marks the
   row-1 reset !important (Bullet Train's light theme rewrites selectors that
   name `.hidden`) would otherwise keep it at 0. */
@media (max-width: 640px) {
  :is(.field-grid, .os-field-grid) { grid-template-columns: minmax(0, 1fr); }
  :is(.field-grid, .os-field-grid) > :nth-child(n+2 of :not(input[type="hidden"], template, [hidden])):is(.field-grid__field, .os-field-grid__field, .os-field):not(#_) { padding-top: 16px !important; }
  :is(.field-grid, .os-field-grid) > :nth-child(n+2 of :not(input[type="hidden"], template, [hidden])):not(.field-grid__field, .os-field-grid__field, .os-field, #_) { margin-top: 16px !important; }
}
:is(.field-grid__label, .os-field-grid__label) {
  display: block;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-bottom: 4px;
}
:is(.field-grid__value, .os-field-grid__value) {
  font-size: var(--text-sm);
  color: var(--text-primary);
}
/* ─── Segmented control ─────────────────────────────────────────────── */
:is(.segmented, .os-segmented) {
  display: inline-flex;
  background: var(--surface-alt);
  border-radius: var(--radius-md);
  padding: 4px;
  gap: 4px;
}
:is(.segmented__option, .os-segmented__option) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Button chrome reset. This component was authored for `<a>` (hence the
     `text-decoration: none` below) and never reset the UA's button styles — so
     rendered as a `<button>`, which is the CORRECT element for a control that
     toggles rather than navigates, the browser's `border: 2px outset` and
     `background: buttonface` showed through and the group read as two
     mismatched boxes instead of one segmented control. Reported by the product
     owner as "the entire page is off"; the measured computed values were
     `border: 2px rgb(0,0,0)` and `background: rgb(239,239,239)`.
     `.os-btn` has always carried this reset; this component simply never did. */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 0;
  background: none;
  font-family: inherit;
  line-height: inherit;
  cursor: pointer;
  /* Density is applied to the VERTICAL PADDING, not to a height. A segmented
     option has never declared a height — it is sized by its label's line box
     (~20px) plus 6px of padding, and introducing a min-height here would set
     a floor this component has never had, which could grow an option whose
     label is smaller than the default. Scaling the padding instead leaves the
     natural sizing intact and moves nothing at base density:
     (36 − 24) / 2 = 6px, the exact literal it replaces. The 6px floor holds
     --compact at today's size rather than crushing the option.

     Horizontal padding stays a 12px literal: this control ships 12px, not the
     button's 14px --control-pad-x, and a token contract may not resize it. */
  padding: max(6px, calc((var(--control-h) - 24px) / 2)) 12px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--interactive);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background 150ms ease-out, color 150ms ease-out;
}
:is(.segmented__option, .os-segmented__option):hover { color: var(--interactive-hover); }
:is(.segmented__option, .os-segmented__option):focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
:is(.segmented__option--active, .os-segmented__option--active) {
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}
:is(.segmented__option--active, .os-segmented__option--active):focus-visible {
  box-shadow: var(--shadow-sm), var(--shadow-focus);
}
/* Form-field variant — full-width equal segments, backed by a native radio
   group; the checked segment lifts to white with accent text (A5 difficulty
   picker). Native radios + :has, no JS. */
:is(.segmented--field, .os-segmented--field) { display: flex; width: 100%; }
:is(.segmented--field, .os-segmented--field) :is(.segmented__option, .os-segmented__option) {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
:is(.segmented__radio, .os-segmented__radio) { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
:is(.segmented--field, .os-segmented--field) :is(.segmented__option, .os-segmented__option):has(:is(.segmented__radio, .os-segmented__radio):checked) {
  background: var(--surface);
  color: var(--accent);
  font-weight: 600;
  box-shadow: var(--shadow-sm);
}
:is(.segmented--field, .os-segmented--field) :is(.segmented__option, .os-segmented__option):has(:is(.segmented__radio, .os-segmented__radio):focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* v1.36.0 (#493): on phones the equal segments wrap onto a second row instead
   of overflowing (five difficulty labels bled 21-105px off a 370px screen).
   Each segment stays a full tap target and still flexes equally per row.
   Desktop and tablet keep one row. */
@media (max-width: 640px) {
  :is(.segmented--field, .os-segmented--field) { flex-wrap: wrap; }
}
/* Count pill inside a segment (e.g. Arrivals 12 / Departures 3). Mono, tints to
   the accent on the active segment. --seg-count-size overrides the glyph size. */
.os-segmented__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  margin-left: 6px;
  border-radius: 9999px;
  background: var(--surface-alt);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: var(--seg-count-size, 11px);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
:is(.os-segmented__option--active, .os-segmented__option:has(.os-segmented__radio:checked)) .os-segmented__count {
  background: var(--accent-soft);
  color: var(--accent-strong);
}
/* ─── Toggle switch (form-bound) ────────────────────────────────────────
   A styled boolean control backed by a native checkbox that submits with the
   form (unlike the fetch-based .toggle_switch component). Native checkbox +
   :has(), no JS. */
:is(.toggle-switch, .os-toggle-switch) {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
:is(.toggle-switch__input, .os-toggle-switch__input) {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
:is(.toggle-switch__track, .os-toggle-switch__track) {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 24px;
  background: var(--hairline-strong);
  border-radius: var(--radius-pill);
  transition: background 150ms ease-out;
}
:is(.toggle-switch__knob, .os-toggle-switch__knob) {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  background: var(--surface);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  transition: transform 150ms ease-out;
}
:is(.toggle-switch__input, .os-toggle-switch__input):checked ~ :is(.toggle-switch__track, .os-toggle-switch__track), :is(.toggle-switch, .os-toggle-switch):has(:is(.toggle-switch__input, .os-toggle-switch__input):checked) :is(.toggle-switch__track, .os-toggle-switch__track) {
  background: var(--accent);
}
:is(.toggle-switch__input, .os-toggle-switch__input):checked ~ :is(.toggle-switch__track, .os-toggle-switch__track) :is(.toggle-switch__knob, .os-toggle-switch__knob), :is(.toggle-switch, .os-toggle-switch):has(:is(.toggle-switch__input, .os-toggle-switch__input):checked) :is(.toggle-switch__knob, .os-toggle-switch__knob) {
  transform: translateX(16px);
}
:is(.toggle-switch__input, .os-toggle-switch__input):focus-visible ~ :is(.toggle-switch__track, .os-toggle-switch__track) {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* ─── Tabs ──────────────────────────────────────────────────────────── */
:is(.tabs, .os-tabs) {
  display: flex;
  gap: 24px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
:is(.tabs__tab, .os-tabs__tab) {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 12px 0;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--interactive);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 150ms ease-out, border-color 150ms ease-out;
}
:is(.tabs__tab, .os-tabs__tab):hover { color: var(--interactive-hover); }
:is(.tabs__tab, .os-tabs__tab):focus-visible {
  outline: none;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-focus);
}
:is(.tabs__tab--active, .os-tabs__tab--active) {
  color: var(--text-primary);
  border-bottom-color: var(--accent);
  font-weight: 600;
}
:is(.tabs__count, .os-tabs__count) {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
:is(.tabs__tab--active, .os-tabs__tab--active) :is(.tabs__count, .os-tabs__count) { color: var(--text-secondary); }
/* ─── Equipment lifecycle action bar (P4-1 T4) ────────────────────────
   State-aware action zone on the EquipmentItem show page. Status pill
   + context-appropriate transition buttons. Calm-surface: button row
   reads as one composition with the status, not as 4 separate widgets. */
:is(.equipment-item-status, .os-equipment-item-status) {
  margin-bottom: 12px;
}
:is(.equipment-item-actions, .os-equipment-item-actions) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 24px;
}
:is(.equipment-item-actions, .os-equipment-item-actions) form { margin: 0; }
:is(.equipment-item-actions, .os-equipment-item-actions) :is(.button, .os-button) {
  font-size: var(--text-sm);
}
/* ─── Participant form (P4-2) ────────────────────────────────────────
   Collapsible sections via <details>. Per design 1C: tracked + free-form
   gear default collapsed when empty, auto-expand when assigned. */
:is(.participant-form__section, .os-participant-form__section) {
  margin: 16px 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
:is(.participant-form__section-summary, .os-participant-form__section-summary) {
  cursor: pointer;
  padding: 12px 16px;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-sm);
  color: var(--text-primary);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  list-style: none;
}
:is(.participant-form__section-summary, .os-participant-form__section-summary)::-webkit-details-marker { display: none; }
:is(.participant-form__section-summary, .os-participant-form__section-summary)::before {
  content: "▸";
  display: inline-block;
  margin-right: 8px;
  font-size: var(--text-2xs);
  color: var(--text-muted);
  transition: transform 150ms ease-out;
}
:is(.participant-form__section, .os-participant-form__section)[open] > :is(.participant-form__section-summary, .os-participant-form__section-summary)::before {
  transform: rotate(90deg);
}
:is(.participant-form__section-hint, .os-participant-form__section-hint) {
  margin-left: 8px;
  font-weight: 400;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
:is(.participant-form__section-body, .os-participant-form__section-body) {
  padding: 8px 16px 16px;
  border-top: 1px solid var(--border);
}
:is(.participant-form__empty-hint, .os-participant-form__empty-hint) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 8px 0;
}
:is(.participant-form__tracked-items, .os-participant-form__tracked-items) {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
:is(.participant-form__tracked-item, .os-participant-form__tracked-item) {
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  transition: background 100ms ease-out;
}
:is(.participant-form__tracked-item, .os-participant-form__tracked-item):hover { background: var(--surface-alt); }
:is(.participant-form__tracked-label, .os-participant-form__tracked-label) {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  min-height: 44px;  /* WCAG AA touch target per design 6C */
}
:is(.participant-form__tracked-input, .os-participant-form__tracked-input) { margin: 0; }
:is(.participant-form__tracked-identifier, .os-participant-form__tracked-identifier) {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
:is(.participant-form__tracked-meta, .os-participant-form__tracked-meta) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  flex: 1;
}
/* ── Phase 6 Pattern Library Additions (R3-R14 + D1-D11) ─────────────────
   form_section, wizard_layout, hero_show, empty_state, loading_state.
   See plan §3 + DESIGN.md tokens for the visual grammar driving these. */
/* ── form_section ───────────────────────────────────────────────────── */
/* Section card — A5 forms spec: surface card, soft shadow, fixed padding.
   Sections stack with an 18px gap in the centered .form-page column. */
:is(.form-section, .os-form-section) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  /* v1.36.0 (#493 D1): ONE card frame. A form section renders on the .os-card
     frame — same border + radius, NO resting shadow (was --shadow-sm), and the
     card's content inset: --space-6 on every side (== .os-card__head /
     __body / __foot since v1.30.0) at EVERY breakpoint. */
  box-shadow: none;
  padding: var(--space-6);
  margin-bottom: 18px;
}
/* The arena theme styles `form.form` (post/patch) with BT's `-mt-5 space-y-5`
   rhythm: a -1.25rem (-20px) top margin plus 20px between children. The
   NEGATIVE margin collapses with the .form-page's 2rem band gap (32 + -20 =
   12px), eating most of it — that's why forms looked like they lost the 2rem.
   The space-y also overrides our 18px section stack. We use form_section
   cards + the band's 2rem, not BT's form rhythm, so neutralize both. The
   selectors mirror the gem's so they tie on specificity and win on source
   order (patterns.css loads after the theme). */
form:is(.form, .os-form)[method="post" i], form:is(.form, .os-form)[method="patch" i] { margin-top: 0; }
/* space-y-5 sets BOTH margins on later children (a Rails hidden CSRF input is
   the first child, so the first section counts as "later"): margin-top 20px
   AND margin-bottom: calc(1.25rem * --tw-space-y-reverse) = 0, which zeroes
   our 18px section stack. Restore both — flush top (band owns the 2rem gap),
   18px between/after sections. */
form:is(.form, .os-form) > :is(.form-section, .os-form-section):not([hidden]) { margin-top: 0; margin-bottom: 18px; }
:is(.form-section__header, .os-form-section__header) {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Muted icon — a quiet marker that keeps the section stack calm (A5 forms
   spec). The heading carries the weight in ink; the icon is NOT accent. */
:is(.form-section__icon, .os-form-section__icon) {
  color: var(--muted);
}
/* Title-case heading — General Sans, the DS CardTitle treatment chosen over
   the uppercase SectionLabel because each header carries a description. */
:is(.form-section__title, .os-form-section__title) {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
/* Description — muted, at the card's left edge (under the icon), not indented
   under the title. */
:is(.form-section__subtitle, .os-form-section__subtitle) {
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--muted);
  margin: 6px 0 0;
}
/* Header→field gap. The card-title-with-description variant breathes at 32px
   between the title/description and the first field; tighter without one. */
:is(.form-section__body, .os-form-section__body) { margin-top: 20px; }
:is(.form-section, .os-form-section):has(:is(.form-section__subtitle, .os-form-section__subtitle)) :is(.form-section__body, .os-form-section__body) { margin-top: 32px; }
/* (v1.36.0: the ≤640px `padding: 18px 16px 20px` override is gone — .os-card
   keeps its 24px inset on phones, so the form section does too.) */
/* ── wizard_layout ──────────────────────────────────────────────────── */
:is(.wizard-layout, .os-wizard-layout) {
  max-width: 860px;
  margin: 0 auto;
  padding: 28px 40px;
}
:is(.wizard-layout__header, .os-wizard-layout__header) { margin-bottom: 24px; }
:is(.wizard-layout__title, .os-wizard-layout__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-2xl);
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin: 0;
}
:is(.wizard-layout__subtitle, .os-wizard-layout__subtitle) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 4px 0 0;
}
:is(.wizard-layout__stepper, .os-wizard-layout__stepper) {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
  margin-bottom: 20px;
}
:is(.wizard-layout__step, .os-wizard-layout__step) {
  margin-bottom: 20px;
}
:is(.wizard-layout__actions, .os-wizard-layout__actions) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
:is(.wizard-layout__actions-right, .os-wizard-layout__actions-right) {
  display: flex;
  align-items: center;
  gap: 12px;
}
:is(.wizard-layout__cancel, .os-wizard-layout__cancel), :is(.wizard-layout__back, .os-wizard-layout__back), :is(.wizard-layout__next, .os-wizard-layout__next) {
  display: inline-flex;
  align-items: center;
  height: 44px;  /* WCAG AAA touch target */
  padding: 0 18px;
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
}
:is(.wizard-layout__cancel, .os-wizard-layout__cancel) {
  color: var(--text-muted);
}
:is(.wizard-layout__cancel, .os-wizard-layout__cancel):hover { color: var(--text-primary); }
:is(.wizard-layout__back, .os-wizard-layout__back) {
  color: var(--text-primary);
  background: var(--surface);
  border-color: var(--border);
}
:is(.wizard-layout__back, .os-wizard-layout__back):hover { background: var(--surface-alt); }
:is(.wizard-layout__next, .os-wizard-layout__next) {
  color: white;
  background: var(--accent);
  border-color: var(--accent);
}
:is(.wizard-layout__next, .os-wizard-layout__next):hover { background: var(--accent-strong); border-color: var(--accent-strong); }
@media (max-width: 640px) {
  :is(.wizard-layout, .os-wizard-layout) { padding: 20px 16px; }
  :is(.wizard-layout__stepper, .os-wizard-layout__stepper) { padding: 14px; }
  /* Stack action bar vertically + full width on mobile. */
  :is(.wizard-layout__actions, .os-wizard-layout__actions) {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  :is(.wizard-layout__actions-right, .os-wizard-layout__actions-right) {
    flex-direction: column;
    align-items: stretch;
  }
  :is(.wizard-layout__cancel, .os-wizard-layout__cancel), :is(.wizard-layout__back, .os-wizard-layout__back), :is(.wizard-layout__next, .os-wizard-layout__next) {
    justify-content: center;
  }
}
/* ── hero_show ──────────────────────────────────────────────────────── */
/* Fills the diveos-content shell (1280 column + 48px gutters) so the
   header band can bleed full-width, like every other account page. */
:is(.hero-show, .os-hero-show) {
  display: block;
}
/* White header band — reuses .dv-page-band (full-bleed white + bleed math).
   This adds only the vertical rhythm: pull up to negate diveos-content's
   top padding (40px), breathe before the body. */
:is(.hero-show__band, .os-hero-show__band) {
  margin-top: calc(-1 * var(--shell-pad-top, 40px));
  margin-bottom: 2rem;
  padding-top: 26px;
  padding-bottom: 22px;
}
/* Page header band — form/settings/list header (reuses .dv-page-band +
   the .hero-show__breadcrumb/__crumb* classes for the crumb row). */
:is(.page-header, .os-page-header) { margin-top: calc(-1 * var(--shell-pad-top, 40px)); padding-top: var(--space-8); padding-bottom: var(--space-6); }
:is(.page-header, .os-page-header) :is(.hero-show__breadcrumb, .os-hero-show__breadcrumb) { margin-bottom: 16px; }
:is(.page-header__row, .os-page-header__row) {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}
:is(.page-header__actions, .os-page-header__actions) { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
@media (max-width: 640px) { :is(.page-header, .os-page-header) { margin-top: -56px; } }
/* Form column under a page_header — centered, 640px (A5 forms spec): a
   field-led single column of section cards. Top gap from the global
   band→body rule below. */
:is(.form-page, .os-form-page) { max-width: 640px; margin-inline: auto; }
/* Content-sized field rows — small numerics/codes group in a wrapping row at
   their natural width instead of stretching the column (A5 field-sizing). */
:is(.field-row, .os-field-row) { display: flex; flex-wrap: wrap; gap: 16px 20px; align-items: flex-start; }
:is(.field-w-116, .os-field-w-116) { width: 116px; }
:is(.field-w-168, .os-field-w-168) { width: 168px; }
:is(.field-w-116, .os-field-w-116) :where(.os-input, input[type], select), :is(.field-w-168, .os-field-w-168) :where(.os-input, input[type], select) { width: 100%; }
/* 50/50 split — equal columns for text PAIRS (names), not numerics. Field
   widths are contextual: compact for numbers/codes, split/full for text. */
:is(.field-split, .os-field-split) { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 20px; align-items: start; }
/* Stacked-field rhythm neutralized by the shared field-grid/field-split reset
   in the Field grid section above. */
/* Inline unit suffix (e.g. % on a commission rate) — sits in the input, not
   as a hint below. */
:is(.field-pct, .os-field-pct) .os-field__input { position: relative; }
:is(.field-pct, .os-field-pct) .os-field__input::after {
  content: "%"; position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  font-size: var(--text-sm); color: var(--muted); pointer-events: none;
}
:is(.field-pct, .os-field-pct) .os-input { padding-right: 26px; }
/* DS Trix toolbar — make the rich-text controls read as part of the system:
   hairline-bordered button groups on surface, muted glyphs, accent-tint
   active, DS-radius. Kept consistently visible (no opacity dimming). */
trix-toolbar { opacity: 1; }
trix-toolbar :is(.trix-button-row, .os-trix-button-row) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
trix-toolbar :is(.trix-button-group, .os-trix-button-group) {
  display: inline-flex;
  margin: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--surface);
  overflow: hidden;
}
trix-toolbar :is(.trix-button, .os-trix-button) {
  width: 32px;
  height: 30px;
  margin: 0;
  padding: 0;
  border: 0;
  border-left: 1px solid var(--hairline-2);
  border-radius: 0;
  background: var(--surface);
  color: var(--muted);
  font-size: 0;
}
trix-toolbar :is(.trix-button-group, .os-trix-button-group) :is(.trix-button, .os-trix-button):first-child { border-left: 0; }
trix-toolbar :is(.trix-button, .os-trix-button)::before { opacity: 0.65; }
trix-toolbar :is(.trix-button, .os-trix-button):not(:disabled):hover { background: var(--surface-alt); }
trix-toolbar :is(.trix-button, .os-trix-button):not(:disabled):hover::before { opacity: 0.9; }
trix-toolbar :is(.trix-button, .os-trix-button):is(.trix-active, .os-trix-active) {
  background: var(--accent-soft);
}
trix-toolbar :is(.trix-button, .os-trix-button):is(.trix-active, .os-trix-active)::before { opacity: 1; }
trix-toolbar :is(.trix-button, .os-trix-button):disabled::before { opacity: 0.25; }
:is(.hero-show__back-row, .os-hero-show__back-row) { margin-bottom: 18px; }
:is(.hero-show__back-link, .os-hero-show__back-link) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  text-decoration: none;
}
:is(.hero-show__back-link, .os-hero-show__back-link):hover { text-decoration: underline; }
/* Name-led header inside the white band — title + status, meta line,
   actions. The band (.dv-page-band) owns the bottom hairline + bg. */
:is(.hero-show__header, .os-hero-show__header) {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}
:is(.hero-show__identity, .os-hero-show__identity) {
  flex: 1;
  min-width: 0;
}
:is(.hero-show__title-row, .os-hero-show__title-row) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 8px;
}
:is(.hero-show__title, .os-hero-show__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-3xl);
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 0;
}
/* Meta line — middot-separated id + facts. Mirrors booking's
   .bk-contact-line so entity headers read identically. */
:is(.hero-show__meta, .os-hero-show__meta) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: var(--text-sm);
  color: var(--muted);
}
:is(.hero-show__meta-id, .os-hero-show__meta-id) {
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}
:is(.hero-show__meta-dot, .os-hero-show__meta-dot) { font-size: var(--text-xl); line-height: 0; color: var(--muted-2); }
:is(.hero-show__meta-item, .os-hero-show__meta-item) { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); }
:is(.hero-show__meta-item, .os-hero-show__meta-item) i, :is(.hero-show__meta-item, .os-hero-show__meta-item) svg { color: var(--muted-2); flex-shrink: 0; }
:is(.hero-show__actions, .os-hero-show__actions) {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
:is(.hero-show__action, .os-hero-show__action) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  text-decoration: none;
  border: 1px solid transparent;
}
:is(.hero-show__action--primary, .os-hero-show__action--primary) {
  color: white;
  background: var(--accent);
  border-color: var(--accent);
}
:is(.hero-show__action--primary, .os-hero-show__action--primary):hover { background: var(--accent-strong); border-color: var(--accent-strong); }
:is(.hero-show__action--secondary, .os-hero-show__action--secondary) {
  color: var(--text-primary);
  background: var(--surface);
  border-color: var(--border);
}
:is(.hero-show__action--secondary, .os-hero-show__action--secondary):hover { background: var(--surface-alt); }
:is(.hero-show__action--danger, .os-hero-show__action--danger) {
  color: var(--cancelled);
  background: var(--surface);
  border-color: var(--hairline);
}
:is(.hero-show__action--danger, .os-hero-show__action--danger):hover { background: var(--cancelled-bg); border-color: var(--cancelled-border); }
/* button_to wraps each action in a form; keep it inline so the flex row
   doesn't break. */
:is(.hero-show__action-form, .os-hero-show__action-form) { display: inline-flex; margin: 0; }
/* Breadcrumb row — replaces the back link on catalog-detail headers. */
:is(.hero-show__breadcrumb, .os-hero-show__breadcrumb) {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 22px;
  font-size: var(--text-sm);
}
:is(.hero-show__crumb, .os-hero-show__crumb) { color: var(--muted); text-decoration: none; }
:is(.hero-show__crumb, .os-hero-show__crumb):hover { color: var(--ink); }
:is(.hero-show__crumb--current, .os-hero-show__crumb--current) { color: var(--ink); font-weight: 600; }
:is(.hero-show__crumb-sep, .os-hero-show__crumb-sep) { display: inline-flex; color: var(--muted-2); }
/* Eyebrow pill — category/type marker above the title. */
:is(.hero-show__eyebrow, .os-hero-show__eyebrow) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
:is(.hero-show__eyebrow, .os-hero-show__eyebrow) svg { color: var(--muted-2); }
/* Subtitle helper line under the title. */
:is(.hero-show__subtitle, .os-hero-show__subtitle) {
  margin: 8px 0 0;
  font-size: var(--text-sm);
  color: var(--muted);
}
/* Rail fact card — stacked label/value rows with hairline separators. */
:is(.hero-rail-card, .os-hero-rail-card) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: 2px 20px;
}
:is(.hero-rail-stat, .os-hero-rail-stat) {
  padding: 16px 0;
  border-bottom: 1px solid var(--hairline-2);
}
:is(.hero-rail-stat, .os-hero-rail-stat):last-child { border-bottom: 0; }
:is(.hero-rail-stat__lbl, .os-hero-rail-stat__lbl) {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
:is(.hero-rail-stat__val, .os-hero-rail-stat__val) {
  margin-top: 6px;
  font-size: var(--text-xl);
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink);
}
:is(.hero-rail-stat__unit, .os-hero-rail-stat__unit) { font-size: var(--text-sm); font-weight: 500; color: var(--muted); margin-left: 2px; }
/* Content card — body section with an icon + title head. */
:is(.hero-content-card, .os-hero-content-card) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: 24px;
  margin-bottom: 20px;
}
:is(.hero-content-card__head, .os-hero-content-card__head) {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
:is(.hero-content-card__title, .os-hero-content-card__title) {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
:is(.hero-content-card__body, .os-hero-content-card__body) {
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--ink);
}
:is(.hero-show__body--one-col, .os-hero-show__body--one-col) :is(.hero-show__main, .os-hero-show__main) { width: 100%; }
:is(.hero-show__body--two-col, .os-hero-show__body--two-col) {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 20px;
}
:is(.hero-show__rail, .os-hero-show__rail) {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
@media (max-width: 1024px) {
  :is(.hero-show__body--two-col, .os-hero-show__body--two-col) {
    grid-template-columns: 1fr;
  }
}
/* Narrow PANE (container, not viewport — accounts for the 240px sidebar): the
   actions are flex-shrink:0, so beside a long title in a ~784px pane they crowd
   it. Wrap the actions under the identity block. The ≤640 viewport block below
   still owns the full mobile column treatment. */
@container (max-width: 760px) {
  :is(.hero-show__header, .os-hero-show__header) { flex-wrap: wrap; }
  :is(.hero-show__identity, .os-hero-show__identity) { flex: 1 1 100%; }
  :is(.hero-show__actions, .os-hero-show__actions) { flex-wrap: wrap; }
}
@media (max-width: 640px) {
  :is(.hero-show__band, .os-hero-show__band) { margin-top: -56px; }
  :is(.hero-show__header, .os-hero-show__header) {
    flex-direction: column;
    gap: 16px;
  }
  :is(.hero-show__actions, .os-hero-show__actions) {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
  }
  :is(.hero-show__action, .os-hero-show__action) { justify-content: center; }
}
/* ── empty_state ────────────────────────────────────────────────────── */
:is(.empty-state, .os-empty-state) {
  text-align: center;
  padding: 40px 16px;
}
/* Composed onto a card. `.os-card` sets `padding: 0` because it expects a
   `__body` child to own the inset — so `class="os-card os-empty-state"` on ONE
   element loses this pattern's padding entirely: both are single-class
   selectors and card.css is bundled after patterns.css, so the zero wins.
   Callers reach for that combination constantly (an empty state IS the whole
   card when a list is empty), and the failure is silent — the text simply runs
   to the card's edge. Two classes out-specify one, so this restores the inset
   regardless of bundle order. Found in arena-ops at 30 callsites across 26
   files: every settings index, most guest-portal empty states, and both
   portal gate pages. */
:is(.empty-state, .os-empty-state):is(.card, .os-card) {
  padding: 40px 16px;
}
:is(.empty-state__icon, .os-empty-state__icon) {
  color: var(--text-muted);
  margin: 0 auto 12px;
  display: block;
}
:is(.empty-state__message, .os-empty-state__message) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
}
/* When a description is present, the message reads as an emphasized title
   above the muted supporting line. Single-message callers are unaffected. */
:is(.empty-state, .os-empty-state):has(:is(.empty-state__description, .os-empty-state__description)) :is(.empty-state__message, .os-empty-state__message) {
  font-size: var(--text-md);
  font-weight: 500;
  color: var(--ink);
}
:is(.empty-state__description, .os-empty-state__description) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 4px 0 0;
}
:is(.empty-state__actions, .os-empty-state__actions) {
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
:is(.empty-state__action, .os-empty-state__action) {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 16px;
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  text-decoration: none;
  border: 1px solid transparent;
}
:is(.empty-state__action--primary, .os-empty-state__action--primary) {
  color: var(--accent);
  background: transparent;
  /* Inline link form when single action (matches conforming surfaces);
     becomes proper button when paired with a secondary (handled by
     `.empty-state__actions:has(.empty-state__action--secondary)`). */
}
:is(.empty-state__action--primary, .os-empty-state__action--primary):hover { text-decoration: underline; }
:is(.empty-state__actions, .os-empty-state__actions):has(:is(.empty-state__action--secondary, .os-empty-state__action--secondary)) :is(.empty-state__action--primary, .os-empty-state__action--primary) {
  color: white;
  background: var(--accent);
  border-color: var(--accent);
}
:is(.empty-state__actions, .os-empty-state__actions):has(:is(.empty-state__action--secondary, .os-empty-state__action--secondary)) :is(.empty-state__action--primary, .os-empty-state__action--primary):hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  text-decoration: none;
}
:is(.empty-state__action--secondary, .os-empty-state__action--secondary) {
  color: var(--text-primary);
  background: var(--surface);
  border-color: var(--border);
}
:is(.empty-state__action--secondary, .os-empty-state__action--secondary):hover { background: var(--surface-alt); }
/* ── loading_state ──────────────────────────────────────────────────── */
:is(.loading-state, .os-loading-state) {
  padding: 12px 0;
}
:is(.loading-state__row, .os-loading-state__row) {
  height: 48px;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  margin-bottom: 8px;
  animation: loading-state-pulse 1.6s ease-in-out infinite;
}
@keyframes loading-state-pulse {
  0% { opacity: 0.6; }
  50% { opacity: 1; }
  100% { opacity: 0.6; }
}
@media (prefers-reduced-motion: reduce) {
  :is(.loading-state__row, .os-loading-state__row) { animation: none; opacity: 0.8; }
}
/* ── stepper ──────────────────────────────────────────────────────────────
   Vertical progress rail: a dot+connector spine with a label/meta body per
   step. States — --done (confirmed dot + tinted line), --active (accent dot
   with focus-style ring), --last (drops the trailing line). Distinct from the
   wizard-layout chrome (that is page layout); this is the reusable progress
   primitive. Promoted from arena-ops (HotelOS `hos-vstep`) 2026-07-25.
   Token-only. */
.os-stepper { display: flex; gap: 12px; align-items: flex-start; }
.os-stepper__rail { display: flex; flex-direction: column; align-items: center; flex: none; }
.os-stepper__dot {
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-alt);
  color: var(--muted-2);
}
.os-stepper__line { width: 2px; height: 20px; background: var(--hairline); }
.os-stepper__body { padding-top: 3px; padding-bottom: 8px; min-width: 0; }
.os-stepper__label { font-size: var(--text-sm); color: var(--muted); }
.os-stepper__meta { font-size: var(--text-xs); color: var(--muted-2); margin-top: 2px; }
.os-stepper__meta--mono { font-family: var(--font-mono); }
.os-stepper--done .os-stepper__dot  { background: var(--confirmed-bg); color: var(--confirmed); }
.os-stepper--done .os-stepper__line { background: var(--confirmed); opacity: 0.35; }
.os-stepper--done .os-stepper__label { color: var(--ink); }
.os-stepper--active .os-stepper__dot { background: var(--accent-soft); color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.os-stepper--active .os-stepper__label { color: var(--ink); font-weight: 600; }
.os-stepper--active .os-stepper__meta { color: var(--accent); }
.os-stepper--last .os-stepper__body { padding-bottom: 0; }
.os-stepper--last .os-stepper__line { display: none; }
/* ── timeline ─────────────────────────────────────────────────────────────
   Numbered node/line/content timeline: a marker column (numbered circle +
   connector) beside a content block, one per node. --board recolours the
   marker as context (not a logged item); --last drops the trailing pad. An
   optional __link makes the content a focusable row. Promoted from dive-os
   (account `dv-timeline`) 2026-07-25. Token-only. */
.os-timeline { list-style: none; margin: 0; padding: 0 16px; }
.os-timeline__node { display: flex; gap: 12px; align-items: flex-start; min-height: 48px; }
.os-timeline__marker-col { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; width: 24px; padding-top: 2px; }
.os-timeline__number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1.5px solid var(--accent-border);
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: 600;
  flex-shrink: 0;
}
.os-timeline__number--board { background: var(--surface-alt); border-color: var(--hairline-strong); color: var(--muted); }
.os-timeline__line { width: 1.5px; flex: 1; min-height: 16px; background: var(--hairline); margin-top: 4px; }
.os-timeline__content { flex: 1; min-width: 0; padding-bottom: 20px; }
.os-timeline__node--last .os-timeline__content { padding-bottom: 8px; }
.os-timeline__link { display: flex; flex-direction: column; gap: 2px; text-decoration: none; color: inherit; }
.os-timeline__link:hover .os-timeline__title { color: var(--accent); }
.os-timeline__link:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; border-radius: var(--radius-sm); }
.os-timeline__title { font-size: var(--text-sm); font-weight: 500; color: var(--ink); line-height: 1.4; transition: color 0.12s; }
.os-timeline__meta { font-size: var(--text-xs); color: var(--muted); }
/* toggle_switch — aria-checked state for the instant-save (button) variant of
   os-ds .os-toggle-switch (#570). Must load after patterns.css. */
/* toggle_switch — instant-save switch (shared/components/_toggle_switch).

   Reuses the os-ds .os-toggle-switch track + knob (os_ds/patterns.css), but on
   a <button role="switch"> instead of a native checkbox: the toggle PATCHes on
   click via toggle_switch_controller, so there is no form to submit. os-ds keys
   its on-state off `input:checked`; this file adds the same on-state keyed off
   `aria-checked`, which the controller flips. One attribute owns the state, so
   the a11y tree and the pixels cannot disagree.

   #570: the previous hand-rolled utility version used `rounded-pill`, which
   never existed as a Tailwind class, so the track rendered as a square box. */
button.os-toggle-switch {
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--radius-pill);
}
.os-toggle-switch[aria-checked="true"] .os-toggle-switch__track {
  background: var(--accent);
}
.os-toggle-switch[aria-checked="true"] .os-toggle-switch__knob {
  transform: translateX(16px);
}
button.os-toggle-switch:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}
button.os-toggle-switch:disabled {
  cursor: not-allowed;
  opacity: var(--disabled-opacity);
}
@media (prefers-reduced-motion: reduce) {
  .os-toggle-switch__track,
  .os-toggle-switch__knob {
    transition-duration: 1ms;
  }
}
/* toggle-row — shared/fields/toggle_row (#609 R1): a form-bound yes/no as one
   row, label left and the native-checkbox .os-toggle-switch right, on the 48px
   touch height. Replaces the Apply/Skip button pairs on the business entity
   form, which overflowed at 370px. */
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--control-h-touch);
}
.toggle-row .toggle-row__label { margin-bottom: 0; cursor: pointer; }
.os-hint.toggle-row__hint { margin-top: var(--space-1); }
/* diveos_shell.css — layout shell + sidebar + side_drawer styles.
   docs/archive/UI-MIGRATION-PLAN.md T6. Loaded after patterns so .section-label
   inherited-then-overridden inside .diveos-sidebar wins via specificity. */
/*
 * diveos_shell.css — layout shell + sidebar + side drawer styles
 *
 * Loaded by application.css after tokens + patterns. Lives separately from
 * patterns.css because the shell is a singular structural component, not
 * a reusable pattern.
 *
 * Per docs/archive/UI-MIGRATION-PLAN.md T6 + UI-ARCHITECTURE.md §1 sidebar IA spec.
 */
/* ─── Body + shell ─────────────────────────────────────────────────── */
/* Element-anchored on purpose. `.os-body` is ALSO the gem's typography
   utility (14/22 body text), so a bare `:is(.diveos-body, .os-body)` selector
   leaked this whole structural block — `min-height: 100vh`, margin, background,
   font — onto every `<p class="os-body">`, stretching paragraphs to a full
   viewport tall (the "massive spacing"). Anchoring to `body` means only the
   real page body can ever match; typography `.os-body` on a <p>/<div> stays
   pure type. (arena-ops sidesteps this entirely with a dedicated
   `.hos-shell-body` name.) Guarded by test/lint/os_body_shell_scope_test.rb. */
body:is(.diveos-body, .os-body) {
  margin: 0;
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--font-sans);
  /* Inter OpenType features per the repo spec (cv11 single-storey a,
     ss01/ss03 alternates). Harmless on General Sans / Geist Mono. */
  font-feature-settings: "cv11", "ss01", "ss03";
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
:is(.diveos-shell, .os-shell) {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}
/* ─── Mobile hamburger ─────────────────────────────────────────────── */
:is(.diveos-hamburger, .os-hamburger) {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 30;
  display: none;
  align-items: center;
  justify-content: center;
  /* 44px minimum touch target per DESIGN.md a11y section. */
  width: 44px;
  height: 44px;
  background: var(--surface);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
:is(.diveos-hamburger, .os-hamburger):hover { background: var(--surface-alt); }
/* ─── Sidebar ──────────────────────────────────────────────────────── */
:is(.diveos-sidebar, .os-sidebar) {
  display: flex;
  flex-direction: column;
  /* v4: gray-100 sidebar per the repo spec (was white --surface). */
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  height: 100vh;
  position: sticky;
  top: 0;
  padding: 24px 16px 16px;
}
:is(.diveos-sidebar__brand, .os-sidebar__brand) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 16px;
}
/* Primary CTA — clean .dv-btn--lg component (not utility soup). Layout-only
   here: full width + the gap before the nav. */
:is(.diveos-sidebar__cta, .os-sidebar__cta) {
  display: flex;
  width: 100%;
  justify-content: center;
  margin-bottom: 32px;
}
/* Brand mark links to Today (logo-links-home). Quiet hover — tint the
   product mark, no background block in the brand zone. */
:is(.diveos-sidebar__brand-link, .os-sidebar__brand-link) { color: inherit; }
:is(.diveos-sidebar__brand-link, .os-sidebar__brand-link):hover :is(.diveos-sidebar__product, .os-sidebar__product) { color: var(--accent-strong); }
:is(.diveos-sidebar__product, .os-sidebar__product) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--text-primary);
  margin: 0;
  letter-spacing: -0.02em;
}
:is(.diveos-sidebar__tenant, .os-sidebar__tenant) {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: var(--leading-2xs); /* #456 — was inheriting body 22px (2.2x) */
  color: var(--text-muted);
  margin: 0;
}
:is(.diveos-sidebar__nav, .os-sidebar__nav) {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}
/* Section labels inside the sidebar get tighter top margins than the
   global .section-label utility (which is tuned for in-content use). */
:is(.diveos-sidebar__nav, .os-sidebar__nav) :is(.section-label, .os-section-label) {
  margin: 18px 10px 6px;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted-2);
}
:is(.diveos-sidebar__nav, .os-sidebar__nav) :is(.section-label, .os-section-label):first-child { margin-top: 0; }
:is(.diveos-sidebar__items, .os-sidebar__items) {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
:is(.diveos-sidebar__item, .os-sidebar__item) {
  position: relative;
}
:is(.diveos-sidebar__link, .os-sidebar__link) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 10px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background 120ms ease, color 120ms ease;
}
:is(.diveos-sidebar__link, .os-sidebar__link):hover {
  background: rgba(0, 0, 0, 0.04);
  color: var(--text-primary);
}
:is(.diveos-sidebar__item--active, .os-sidebar__item--active) :is(.diveos-sidebar__link, .os-sidebar__link) {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}
/* Active state is the accent-soft fill + accent text (our treatment); no
   left-edge bar. ::before neutralized — kept out so it can't mis-position. */
:is(.diveos-sidebar__item--active, .os-sidebar__item--active)::before { content: none; }
:is(.diveos-sidebar__label, .os-sidebar__label) { line-height: 1.2; }
:is(.diveos-sidebar__badge, .os-sidebar__badge) {
  display: inline-block;
  padding: 1px 6px;
  font-size: var(--text-2xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  line-height: 1.4;
}
/* ─── Owner footer ─────────────────────────────────────────────────── */
:is(.diveos-sidebar__owner-trigger, .os-sidebar__owner-trigger) { position: relative; }
:is(.diveos-sidebar__owner, .os-sidebar__owner) {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 16px;
  border: 0;
  border-top: 1px solid var(--border);
  background: transparent;
  color: var(--text-primary);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 150ms ease-out;
}
:is(.diveos-sidebar__owner, .os-sidebar__owner):hover { background: var(--surface-alt); }
:is(.diveos-sidebar__avatar, .os-sidebar__avatar) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
:is(.diveos-sidebar__owner-text, .os-sidebar__owner-text) { min-width: 0; flex: 1; }
:is(.diveos-sidebar__owner-label, .os-sidebar__owner-label) {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
:is(.diveos-sidebar__owner-name, .os-sidebar__owner-name) {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-primary);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
:is(.diveos-sidebar__owner-role, .os-sidebar__owner-role) {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin: 0;
  text-transform: capitalize;
}
/* Upward-opening account menu (footer sits at bottom of sidebar) */
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu) {
  position: absolute;
  bottom: 100%;
  left: 8px;
  right: 8px;
  min-width: 200px;
  margin-bottom: 6px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  z-index: 20;
}
:is(.diveos-sidebar__owner-menu, .os-sidebar__owner-menu).hidden { display: none; }
:is(.diveos-sidebar__owner-menu-item, .os-sidebar__owner-menu-item) {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-primary);
  font-size: var(--text-sm);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 150ms ease-out;
}
:is(.diveos-sidebar__owner-menu-item, .os-sidebar__owner-menu-item):hover { background: var(--bg); }
:is(.diveos-sidebar__owner-menu-item--divided, .os-sidebar__owner-menu-item--divided) {
  margin-top: 4px;
  border-top: 1px solid var(--border);
}
/* ─── Main pane ────────────────────────────────────────────────────── */
:is(.diveos-main, .os-shell-main) {
  background: var(--bg);
  outline: none;
  min-height: 100vh;
  /* Grid items default to min-width:auto, so a wide unwrappable child (mono
     trip title + action buttons) inflates the shell column past the viewport
     and forces horizontal scroll on phones. 0 lets the pane shrink-to-fit. */
  min-width: 0;
  /* Container context so the content gutter (clamp(…, 4cqi, …)) measures the
     PANE width (viewport minus sidebar), not the whole window. */
  container-type: inline-size;
}
:is(.diveos-content, .os-content) {
  /* Width tier — defaults to wide; pattern partials narrow it via a modifier. */
  --page-max: var(--page-wide);
  max-width: var(--page-max);
  margin-inline: auto;   /* centre the content column within the main pane */
  /* --shell-pad-top is the single source of truth for the pane's top padding.
     Full-bleed headers (.dv-page-head / .dv-page-tools / .page-header /
     .hero-show__band) pull up by EXACTLY this via calc() so the band sits flush
     at the pane top on every breakpoint — no hardcoded -40px to drift out of
     sync (it previously left a 16px gap on mobile where the pad is 56px).
     Horizontal padding is the fluid --gutter; self-banding headers bleed to the
     content-box edge with margin-inline: calc(var(--gutter) * -1). */
  --shell-pad-top: 40px;
  padding: var(--shell-pad-top) var(--gutter) 64px;
  /* Full-bleed band helpers (used by .dv-page-band / .dv-full-bleed / kanban):
     the band background spans the whole pane (100cqw, measured on .diveos-main),
     while its INNER content re-pads to the tier column so it lines up with the
     body. cqw excludes the scrollbar (unlike vw) → no horizontal overflow. */
  --bleed-w:  100cqw;
  --bleed-mx: calc(50% - 50cqw);
  --bleed-pad: max(var(--gutter), calc(50cqw - var(--page-max) / 2 + var(--gutter)));
}
:is(.diveos-content--narrow, .os-content--narrow)  { --page-max: var(--page-narrow); }
/* Prose cap — apply to paragraph/description runs so line length stays readable
   even on a wide page. Structured content (tables, cards, KV grids) never uses it. */
:is(.dv-measure, .os-measure) { max-width: var(--measure); }
/* Tighter caps for larger text — line length shrinks as size grows (Practical UI). */
:is(.dv-measure--lg, .os-measure--lg)      { max-width: var(--measure-lg); }
:is(.dv-measure--display, .os-measure--display) { max-width: var(--measure-display); }
/* Full-bleed pages (content_for :full_bleed) — e.g. the POS booking wizard:
   the page owns the whole content pane as a fixed-height app-shell region
   (its own header/stepper, an internally-scrolling body, and a footer pinned
   to the viewport bottom) instead of the default padded, page-scrolling column. */
:is(.diveos-main--bleed, .os-shell-main--bleed) {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}
:is(.diveos-content--bleed, .os-content--bleed) {
  flex: 1;
  min-height: 0;
  max-width: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* ─── Side drawer (the layout-level Turbo Frame) ───────────────────── */
:is(.side-drawer, .os-side-drawer) {
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0;
  right: 0;
  width: 560px;
  max-width: 90vw;
  height: 100vh;
  background: var(--surface);
  border-left: 1px solid var(--border);
  /* No shadow while parked off-canvas (#360) — it would bleed onto the
     viewport's right edge. The open rule below adds it back. */
  box-shadow: none;
  transform: translateX(100%);
  transition: transform 280ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 280ms cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 40;
  overflow: hidden;
  pointer-events: none;
}
:is(.side-drawer, .os-side-drawer) > * { min-height: 0; height: 100%; width: 100%; }
:is(.side-drawer, .os-side-drawer):is(.side-drawer--open, .os-side-drawer--open) {
  box-shadow: -8px 0 24px rgba(15, 23, 42, 0.12);
  transform: translateX(0);
  pointer-events: auto;
}
:is(.side-drawer, .os-side-drawer)::-webkit-scrollbar { width: 8px; }
:is(.side-drawer, .os-side-drawer)::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
/* ─── Side-drawer scrim ─────────────────────────────────────────────── */
/* Dims the page behind ANY open side panel (Trip / Diver / Fleet / Gear /
   Team / Fast-create), matching the Bookings slideover's `.slideover-backdrop`
   look. Sits just below the drawer (z-index 40 vs the drawer's 40 — declared
   first so the later drawer paints above) and fades in/out. The side_panel
   controller toggles `.side-drawer-scrim--visible` in lock-step with the
   drawer's open class; clicking it closes the drawer via the controller's
   outside-click handler. */
:is(.side-drawer-scrim, .os-side-drawer-scrim) {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: rgba(15, 27, 45, 0.30);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms ease;
}
:is(.side-drawer-scrim--visible, .os-side-drawer-scrim--visible) {
  opacity: 1;
  pointer-events: auto;
}
/* ─── Mobile drawer scrim ──────────────────────────────────────────── */
/* Desktop never shows it; below 1024px it sits between the page and the
   open drawer so a tap outside dismisses instead of dead-ending. */
:is(.diveos-scrim, .os-scrim) { display: none; }
/* ─── Responsive: mobile (< 1024px) ────────────────────────────────── */
@media (max-width: 1023px) {
  :is(.diveos-shell, .os-shell) { grid-template-columns: 1fr; }
  :is(.diveos-hamburger, .os-hamburger) { display: inline-flex; }
  :is(.diveos-sidebar, .os-sidebar) {
    position: fixed;
    top: 0;
    left: 0;
    width: var(--sidebar-w);
    transform: translateX(-100%);
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
    z-index: 50;
    height: 100vh;
  }
  :is(.diveos-shell--menu-open, .os-shell--menu-open) :is(.diveos-sidebar, .os-sidebar) { transform: translateX(0); }
  :is(.diveos-shell--menu-open, .os-shell--menu-open) :is(.diveos-scrim, .os-scrim) {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(15, 23, 32, 0.45);
  }
  :is(.diveos-content, .os-content) { --shell-pad-top: 56px; padding: var(--shell-pad-top) 16px 32px; }
}
/* ─── Responsive: phones (< 640px) ─────────────────────────────────── */
/* The info strip's N-up grid has a min-content width (~345px for the trip
   strip) that propagates up and forces horizontal page scroll on phones.
   Stack the cells; side dividers become bottom dividers. */
@media (max-width: 639px) {
  :is(.info-strip, .os-info-strip) { grid-template-columns: 1fr; }
  :is(.info-strip__cell, .os-info-strip__cell) { border-right: 0; }
  :is(.info-strip__cell, .os-info-strip__cell):not(:last-child) { border-bottom: 1px solid var(--border); }
  /* Full-screen drawer on phones only. Tablet (640–1023) keeps the desktop
     560px overlay + scrim so the background shows and it's easy to tap off. */
  :is(.side-drawer, .os-side-drawer) { width: 100vw; max-width: 100vw; }
}
/* ── Sidebar collapse (rail ⇄ 64px icon strip) ───────────────────────────
   Relocated here from components/package_builder.css: this is general shell/
   sidebar behaviour (the brand chevron toggle + collapsed rail), not package-
   builder-specific. Lives with the shell so the package-builder CSS can ship
   as its own PR without the sidebar depending on it. */
/* ─── 3. Sidebar collapse (extends the real .diveos-sidebar) ───────── */
/* The shell grid resolves the rail width from --sidebar-w. Collapse swaps
   that var on the shell so the grid column tracks the 64px rail. The width
   transition lives on the sidebar; the grid column follows because it reads
   the same var. */
:is(.diveos-sidebar, .os-sidebar) {
  /* add the animated width so collapse glides (the shell sets the column) */
  transition: width var(--t-slow) var(--ease-out-quart);
  overflow: hidden;
}
/* Animate the GRID TRACK so the rail glides. The column drives the sidebar
   width, so the transition must live on grid-template-columns — a transition
   on the sidebar's own width is clipped instantly by the resized track. */
:is(.diveos-shell, .os-shell) {
  transition: grid-template-columns var(--t-slow) var(--ease-out-quart);
}
/* Rail-collapse is a DESKTOP-only affordance. Below 1024px the sidebar is a
   full slide-in DRAWER, so a remembered collapse (localStorage) must NOT apply:
   it would reserve a 64px grid column that squeezes the page, and shrink the
   opened drawer to an icon rail. Every `.is-rail-collapsed` rule is therefore
   scoped to ≥1024px; on mobile the menu is always expanded. */
@media (min-width: 1024px) {
  :is(.diveos-shell, .os-shell).is-rail-collapsed {
    grid-template-columns: var(--space-16) 1fr;
  }
}
/* collapse toggle — ghost button styled like a quiet nav affordance.
   Lives in the brand header; the markup adds it next to the brand block. */
:is(.diveos-sidebar__collapse, .os-sidebar__collapse) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  margin-left: auto;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted-2);
  cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.diveos-sidebar__collapse, .os-sidebar__collapse):hover { background: var(--surface-alt); color: var(--ink); }
/* ── collapsed state (desktop only — see the note on the grid rule above) ── */
@media (min-width: 1024px) {
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar, .os-sidebar) { width: var(--space-16); padding: 24px 0 16px; }

/* brand: hide the text block, center the logo, drop the toggle below it */
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__brand, .os-sidebar__brand) {
  padding: 0 0 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__brand-link, .os-sidebar__brand-link) { justify-content: center; }
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__brand-link, .os-sidebar__brand-link) > div { display: none; }
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__collapse, .os-sidebar__collapse) { margin-left: 0; }

/* CTA → icon-only 40px accent square */
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__cta, .os-sidebar__cta) {
  width: 40px;
  height: 40px;
  margin: 0 auto 24px;
  padding: 0;
}
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__cta, .os-sidebar__cta) i, :is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__cta, .os-sidebar__cta) svg { margin: 0; }
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__cta, .os-sidebar__cta) :is(.pkb-cta-label, .os-pkb-cta-label) { display: none; }

/* nav: section labels → a hairline divider; items → icon-only */
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__nav, .os-sidebar__nav) { padding: 0 10px; }
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__nav, .os-sidebar__nav) :is(.section-label, .os-section-label) {
  height: 1px;
  margin: 14px 8px 8px;
  padding: 0;
  background: var(--hairline);
  overflow: hidden;
  text-indent: -9999px;
}
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__link, .os-sidebar__link) {
  justify-content: center;
  padding: 9px 0;
}
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__label, .os-sidebar__label), :is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__badge, .os-sidebar__badge) { display: none; }
/* active item: just the accent icon on accent-soft (no left bar in collapsed) */
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__item--active, .os-sidebar__item--active) :is(.diveos-sidebar__link, .os-sidebar__link) {
  background: var(--accent-soft);
}

/* owner footer → avatar only */
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__owner, .os-sidebar__owner) {
  justify-content: center;
  padding: 8px 0;
}
:is(.diveos-shell, .os-shell).is-rail-collapsed :is(.diveos-sidebar__owner-text, .os-sidebar__owner-text) { display: none; }
}
/* respect reduced-motion for the width glide */
@media (prefers-reduced-motion: reduce) {
  :is(.diveos-sidebar, .os-sidebar) { transition: none; }
}
/* Form field substrate (.diveos-input, .diveos-label, .diveos-button, etc.).
   Consumed by the FormBuilder (T5) and the ejected shared/fields/* partials
   (T6). The COMPONENT is the gem's; diveos_forms.css now carries only the
   DiveOS variants os-ds lacks and MUST load after it.

   NOTE: DiveOS imports gem files individually rather than the bundled
   os_ds.css, so a gem component that is not listed here simply never loads.
   forms.css was in the package but unimported — deleting the local copy
   without adding this line left the form components undefined. */
/* forms.css — the shared FORM substrate, promoted into the gem (was
   `diveos_forms.css`, duplicated BYTE-FOR-BYTE in arena-ops and dive-os).
   Third promotion after header_band: label/input/select/textarea/hint/error,
   field + form-actions, check/radio, and the legacy .diveos-button family.

   Class names are kept AS-IS (`.diveos-*`) so the promotion is a pure move —
   every form callsite in both consumers keeps working. A `.dv-*` alias pass is
   a separate, later step; renaming here would break two apps at once.

   Consumers: delete your local `diveos_forms.css` and drop its
   `stylesheet_link_tag` once you are on this version. */
/* DiveOS form substrate — utility classes the ejected shared/fields/*
   partials (T6) and DiveosFormBuilder (T5) apply so 75+ forms inherit
   consistent styling without per-call class lists.
   Per docs/archive/UI-MIGRATION-PLAN.md PR1 task T4 + design-review D2 (error state)
   + D9 (focus rings + touch targets). */
/* Vertical rhythm between stacked fields — without this they collapse to
   margin:0 and read as a cramped wall (legacy-redesign QA finding). The
   label→input gap stays tight (6px); the field→field gap breathes (22px). */
:is(.form-section__body, .os-form-section__body) > * + * { margin-top: 22px; }
.os-field + .os-field { margin-top: 22px; }
.os-label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.os-label--required::after {
  content: " *";
  color: var(--error);
}
/* v4 input model per the repo spec: gray-50 bg, gray-300 border with a
   gray-400 hover step, accent-derived focus border + 10% focus ring. */
.os-input, .os-field-select, .os-textarea {
  display: block;
  width: 100%;
  /* Height is PINNED to the button scale so an input and the button beside it
     line up (a control row is the common case: "Record… [Save]", search +
     submit, a filter + apply). Before this, an input was implicitly ~40px from
     padding while .os-btn is a fixed 36px, so every inline pairing sat a few
     px off — visible app-wide. --sm matches .os-btn--sm. box-sizing keeps the
     border inside the declared height.

     Since v1.6.0 that pinning is literal: the input reads the SAME
     --control-h token .os-btn does, so the two cannot drift apart again and
     both follow an .os-density--* scope together. Padding stays a literal
     pair — an input's 12px inset is tighter than a button's 14px by design
     (the caret needs less shoulder than a centred label), so it is not the
     same value and must not be tokenised as if it were. */
  box-sizing: border-box;
  min-height: var(--control-h);   /* 36px at base density — .os-btn */
  padding: 10px 12px;
  font-family: var(--font-sans);
  font-size: var(--control-fs);
  color: var(--text-primary);
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  transition: border-color 100ms ease, box-shadow 100ms ease;
}
/* Small control row — pairs with .os-btn--sm (32px). */
.os-input--sm, .os-field-select--sm {
  --control-h:  var(--control-h-sm);    /* 32px — .os-btn--sm */
  --control-fs: var(--control-fs-sm);   /* 12px */
  padding: 6px 10px;
}
/* (A textarea is multi-line — its own min-height: 96px below overrides the
   control height set above.) */
.os-input:hover, .os-field-select:hover, .os-textarea:hover {
  border-color: var(--input-border-hover);
}
.os-input:focus, .os-field-select:focus, .os-textarea:focus {
  outline: none;
  border-color: var(--input-border-focus);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.os-input:disabled, .os-field-select:disabled, .os-textarea:disabled {
  background: var(--surface-alt);
  color: var(--text-muted);
  cursor: not-allowed;
}
.os-input::-moz-placeholder, .os-textarea::-moz-placeholder {
  color: var(--input-placeholder);
}
.os-input::placeholder, .os-textarea::placeholder {
  color: var(--input-placeholder);
}
.os-textarea {
  min-height: 96px;
  resize: vertical;
}
/* Error state — applied by ejected field partials (T6) when the field
   has validation errors. Design-review D2: red border + inline message
   below. The message itself uses .diveos-error. */
/* ══════════════════════════════════════════════════════════════
   DATE / TIME INPUTS — painted by DEFAULT (v1.13.0)
   ══════════════════════════════════════════════════════════════
   Same reasoning as the checkbox in v1.10.0: the default has to be the one you
   want. `<input type="date" class="os-input">` inherited the PLATFORM's calendar
   affordance — on Chrome a small grey glyph in the UA's own weight and colour,
   on Safari a different one — sitting inside a field drawn from our tokens. Two
   vocabularies in one control, and every product hit it because typing the
   obvious thing is what produced it.

   The glyph is now a MASK tinted with `--muted-2`, so it takes the theme's
   colour (and the accent on hover), matches the 1.75 stroke weight the icon set
   uses, and carries no hard-coded colour of its own — the mask is geometry, the
   colour is a token. The native picker still opens on click: this restyles the
   indicator, it does not replace the control.

   Firefox exposes no such pseudo-element and renders no indicator, so it
   degrades to a plain field — the same as before this rule.

   NO MARKUP CHANGE anywhere; every existing date input is repainted as-is. */
.os-input[type="date"],
.os-input[type="time"],
.os-input[type="datetime-local"],
.os-input[type="month"],
.os-input[type="week"] {
  /* iOS refuses to fill the field and centres the value instead unless the UA
     appearance is reset — the value then sits mid-field while the placeholder
     of the input beside it sits at the top. */
  -webkit-appearance: none;
  -moz-appearance: none;
       appearance: none;
}
.os-input[type="date"]::-webkit-calendar-picker-indicator,
.os-input[type="time"]::-webkit-calendar-picker-indicator,
.os-input[type="datetime-local"]::-webkit-calendar-picker-indicator,
.os-input[type="month"]::-webkit-calendar-picker-indicator,
.os-input[type="week"]::-webkit-calendar-picker-indicator {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  padding: 0;
  cursor: pointer;
  opacity: 1;
  background-color: var(--muted-2);
  -webkit-mask: var(--os-cal-glyph) center / 18px 18px no-repeat;
  mask: var(--os-cal-glyph) center / 18px 18px no-repeat;
  -webkit-transition: background-color 120ms var(--ease-standard);
  transition: background-color 120ms var(--ease-standard);
}
.os-input:hover::-webkit-calendar-picker-indicator { background-color: var(--muted); }
.os-input:focus::-webkit-calendar-picker-indicator { background-color: var(--accent); }
/* The calendar geometry, as a mask. `black` is the mask's alpha channel, not a
   colour the user ever sees — the visible colour is the `background-color`
   token above. Declared as a custom property so the five type selectors above
   share one copy of the payload. */
:root {
  --os-cal-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E");
}
/* ══════════════════════════════════════════════════════════════
   SELECT — painted with NO JavaScript (v1.17.0)
   ══════════════════════════════════════════════════════════════
   `.os-field-select` used to leave `appearance: auto`, so the painted select
   existed ONLY behind the `os-select` Stimulus controller. Every bundler-less
   consumer — and every deliberately no-JS surface, like a guest portal that
   runs on plain form posts — got the platform's chevron sitting inside a field
   drawn entirely from our tokens. Same defect the checkbox had in v1.10.0 and
   the date input in v1.13.0, and the same fix: the DEFAULT has to be ours.

   This is the closed state only. `appearance: none` does not touch how the
   option list opens, so mobile still gets the native picker it should have —
   there is no need to gate this by pointer type, and doing so would leave
   touch-capable laptops on the UA chevron.

   THE TINT IS BAKED, and that is a real limitation, not an oversight: a
   `background-image` data-URI cannot read a custom property, and `currentColor`
   does not resolve inside one. The calendar indicator escapes this by being a
   pseudo-element we can `mask` (so it takes `--muted-2`); a `<select>` has no
   such pseudo-element to hang a mask on without masking its text too. The whole
   URL is therefore exposed as `--os-select-chevron` so a product can replace
   the glyph wholesale — geometry and tint together — rather than being stuck
   with ours. The default is `--slate-500` / `--gray-500`, the value `--muted-2`
   resolves to in both shipped themes.

   A consumer that DOES run the `os-select` controller is unaffected: it wraps
   the native select and paints its own trigger, which sits above this. */
:root {
  --os-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.os-field-select {
  -webkit-appearance: none;
  -moz-appearance: none;
       appearance: none;
  background-image: var(--os-select-chevron);
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  background-size: 16px 16px;
  /* Room for the glyph plus its gutter: 12 (inset) + 16 (glyph) + 10 (gap).
     Without it a long option value runs under the chevron — which is exactly
     how this shipped before, with the UA arrow jammed against the text. */
  padding-right: 38px;
}
/* Multiple/size selects render a list box, not a closed control — a chevron on
   a list box is a lie. */
.os-field-select[multiple], .os-field-select[size]:not([size="1"]) {
  background-image: none;
  padding-right: 12px;
}
.os-input.is-invalid, .os-field-select.is-invalid, .os-textarea.is-invalid {
  border-color: var(--error);
}
.os-input.is-invalid:focus, .os-field-select.is-invalid:focus, .os-textarea.is-invalid:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 10%, transparent);
}
.os-hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 6px;
}
.os-field-error {
  font-size: var(--text-xs);
  color: var(--error);
  margin-top: 6px;
}
/* ── Affixed field — a currency symbol or unit INSIDE the control ─────
   WHY THIS EXISTS. Every money input in the system had the same problem: the
   dollar sign was rendered as a separate label beside the box, so the pair
   read as two things and the number lost its meaning the moment the eye left
   the label. DiveOS solved it locally in its booking wizard by hand-building
   a bordered flex box with the symbol inside it; arena-ops, porting that POS
   flow, needed the same thing at every charge line and had nothing to reach
   for. The affix belongs INSIDE the control's border, before the value — it
   is part of the control, not an adornment next to it.

   This EXTENDS the field anatomy rather than replacing it. Label, hint and
   error are unchanged; only the control itself is wrapped.

     div.os-field
       label.os-label
       div.os-field--affix          the control box — owns border and height
         span.os-field__affix       the symbol
         input.os-input             the value
       p.os-hint

   TRAILING AFFIXES fall out of DOM order for free: put .os-field__affix
   AFTER the input and it renders as a unit suffix — kg, %, /night. Nothing
   below is position-specific except the divider rules, which key off
   adjacency rather than a modifier, so both sides work without a variant.

   ONE GOTCHA, worth stating because the failure is silent. The control box
   carries .os-field--affix ALONE, never `os-field os-field--affix`. The base
   class participates in the 22px field-stacking rule above, so pairing them
   would put inter-field margin inside a single field. The modifier is
   therefore self-contained: it redeclares the box styling instead of
   inheriting it. */
.os-field--affix {
  display: flex;
  align-items: stretch;
  box-sizing: border-box;
  width: 100%;
  /* The affix box takes over the border, background and height the input
     normally draws, so the two read as one control. Values are the input's,
     token for token, and the height comes from the SAME --control-h an
     .os-input reads — an affixed field and a plain one in the same row line
     up, and both follow an .os-density--* scope together. */
  min-height: var(--control-h);
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  transition: border-color 100ms ease, box-shadow 100ms ease;
  /* Keeps the affix's tint off the rounded corners. */
  overflow: hidden;
}
.os-field--affix:hover {
  border-color: var(--input-border-hover);
}
/* The ring moves to the WHOLE box: the input inside has no visible edge left
   to ring, and ringing an invisible child would draw a rectangle floating
   inside the control. Not :focus-visible — a text field rings on any focus,
   which is what .os-input already does. */
.os-field--affix:focus-within {
  border-color: var(--input-border-focus);
  box-shadow: var(--shadow-focus);
}
.os-field--affix.is-invalid {
  border-color: var(--error);
}
.os-field--affix.is-invalid:focus-within {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 10%, transparent);
}
/* The symbol. Monospace and muted so it stays subordinate to the number it
   qualifies, and non-selectable so dragging across the value to copy it does
   not carry a stray dollar sign into the clipboard. */
.os-field__affix {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding-inline: 12px;
  font-family: var(--font-mono);
  font-size: var(--control-fs);
  color: var(--text-muted);
  background: var(--surface-alt);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  white-space: nowrap;
}
/* A hairline where the affix meets the value, on whichever side it sits.
   Adjacency, not a modifier — see the trailing note above. */
.os-field__affix + * { border-inline-start: 1px solid var(--input-border); }
* + .os-field__affix  { border-inline-start: 1px solid var(--input-border); }
/* A quieter affix for the money case, where a boxed, ruled `$` is heavier
   than the symbol deserves: no fill, no divider, just the glyph tucked
   against the number. This is the DiveOS price-field reading. */
.os-field--affix-flush .os-field__affix {
  background: transparent;
  padding-inline-end: 0;
  border: 0;
}
.os-field--affix-flush .os-field__affix + * { border-inline-start: 0; }
.os-field--affix-flush * + .os-field__affix { border-inline-start: 0; }
.os-field--affix-flush .os-field__affix + .os-input { padding-inline-start: 4px; }
/* The input surrenders its own chrome to the box around it. Descendant
   selector rather than a required extra class: the wrapper is what makes it
   affixed, so the consumer should not have to say so twice. */
.os-field--affix .os-input, .os-field--affix .os-field-select {
  min-height: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  flex: 1 1 auto;
  min-width: 0;
}
.os-field--affix .os-input:hover, .os-field--affix .os-field-select:hover {
  border-color: transparent;
}
.os-field--affix .os-input:focus, .os-field--affix .os-field-select:focus {
  outline: none;
  border-color: transparent;
  box-shadow: none;
}
/* A money value reads right-aligned and tabular so decimal points stack down
   a column of charges. Opt-in — an affixed field is not always money. */
.os-field--affix-numeric .os-input {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.os-field--affix-numeric .os-input::-webkit-outer-spin-button,
.os-field--affix-numeric .os-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.os-field--affix-numeric .os-input[type="number"] {
  -webkit-appearance: textfield;
          appearance: textfield;
  -moz-appearance: textfield;
}
/* Size modifiers redeclare the trio on themselves, pinning them against an
   enclosing density scope — the v1.6.0 back-compat rule. */
.os-field--affix-sm {
  --control-h:  var(--control-h-sm);
  --control-fs: var(--control-fs-sm);
}
.os-field--affix-sm .os-input { padding: 6px 10px; }
/* Intrinsic width, for an affixed field sitting inline in a line-item row
   rather than filling a form column. */
.os-field--affix-inline {
  display: inline-flex;
  width: auto;
}
/* ══════════════════════════════════════════════════════════════
   CHECKBOX / RADIO — painted by DEFAULT (v1.10.0)
   ══════════════════════════════════════════════════════════════
   WHAT CHANGED AND WHY. `.os-checkbox` used to be the NATIVE control with
   `accent-color` set — deliberately, "no custom-painted control". In practice
   that made the default the wrong one. A product that writes the obvious thing,
   `<input type="checkbox" class="os-checkbox">`, got the PLATFORM's checkbox:
   macOS renders a rounded-square with its own tick weight, Windows a hard
   square, and neither matches the 1.5px hairline + `--radius-sm` vocabulary
   every other control in the library is drawn with. The painted component
   existed (`.os-field-check`), but it needs a two-element structure —
   `__input` + a sibling `__box` — so nobody reached for it on a bare input,
   and both products shipped surfaces with platform checkboxes sitting inside
   DS tiles. The default has to be the one you want.

   So `.os-checkbox` / `.os-radio` now paint THEMSELVES, single-element: the
   input is its own box, the tick is a `::after` pseudo-element. **No markup
   change anywhere** — every existing call-site is repainted as-is, which is
   why this is a minor bump and not a major.

   THE ESCAPE HATCH is `--native`: add it to hand a control back to the
   platform (an OS-integrated form, a print sheet, a surface where the user
   expects their own widget). That is the modifier the old default became.

   `.os-field-check` is unchanged and still correct when the box must sit
   beside multi-line label text with its own alignment — it owns the
   composition; these own the control. */
.os-checkbox, .os-radio {
  -moz-appearance: none;
       appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 18px;
  height: 18px;
  margin-top: 3px; /* optical alignment to label cap-height when parent is flex-start */
  padding: 0;
  flex-shrink: 0;
  cursor: pointer;
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  transition: background-color 120ms var(--ease-standard),
              border-color 120ms var(--ease-standard);
}
.os-checkbox { border-radius: var(--radius-sm); }
.os-radio    { border-radius: var(--radius-pill); }
.os-checkbox:hover:not(:disabled), .os-radio:hover:not(:disabled) {
  border-color: var(--accent);
}
.os-checkbox:checked, .os-radio:checked,
.os-checkbox:indeterminate {
  background: var(--accent);
  border-color: var(--accent);
}
/* The tick is DRAWN, not an image: a rotated corner of a 2-sided box. That
   keeps it token-free (no data-URI carrying a hard-coded stroke colour, which
   is also what the compliance scanner would flag) and lets it inherit the
   sizing above if the control is scaled. */
.os-checkbox::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: 4px;
  height: 8px;
  border: solid var(--surface);
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -50%) rotate(45deg) scale(0.6);
  opacity: 0;
  transition: opacity 120ms var(--ease-standard), transform 120ms var(--ease-standard);
}
.os-checkbox:checked::after {
  opacity: 1;
  transform: translate(-50%, -50%) rotate(45deg) scale(1);
}
/* Indeterminate is a BAR, not a tick — "some of the children", which a
   half-drawn check cannot say. It replaces the tick rather than joining it. */
.os-checkbox:indeterminate::after {
  opacity: 1;
  width: 9px;
  height: 0;
  border-width: 0 0 2px 0;
  transform: translate(-50%, -50%);
}
.os-radio::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 120ms var(--ease-standard), transform 120ms var(--ease-standard);
}
.os-radio:checked::after { opacity: 1; transform: scale(1); }
.os-checkbox:focus-visible, .os-radio:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-focus);
}
.os-checkbox:disabled, .os-radio:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
/* ── Opt back out to the platform control ─────────────────────────────────
   This is exactly what `.os-checkbox` was before v1.10.0. Everything the
   painted version declares is reset here, so the modifier is complete on its
   own and does not depend on declaration order. */
.os-checkbox--native, .os-radio--native {
  -moz-appearance: auto;
       appearance: auto;
  -webkit-appearance: auto;
  border: 0;
  background: none;
  border-radius: 0;
  accent-color: var(--accent);
}
.os-checkbox--native::after, .os-radio--native::after { content: none; }
.os-checkbox-label, .os-radio-label {
  display: inline-flex;
  align-items: flex-start;
  gap: 8px;
  font-size: var(--text-sm);
  color: var(--text-primary);
  cursor: pointer;
  min-height: 44px;
}
/* ══════════════════════════════════════════════════════════════
   CANONICAL CHECKBOX COMPONENT  (.diveos-check)
   Painted square box + Lucide check icon. Native input visually
   hidden but fully accessible (focus, keyboard, screen readers).
   Aligns the box to the label's first line.
   ══════════════════════════════════════════════════════════════ */
.os-field-check {
  display: inline-flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--text-primary);
  line-height: 1.45;
}
.os-field-check__input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}
.os-field-check__box {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.os-field-check__box svg {
  width: 12px;
  height: 12px;
  opacity: 0;
  transform: scale(.6);
  transition: opacity 120ms ease, transform 120ms ease;
}
.os-field-check__input:checked + .os-field-check__box {
  background: var(--accent);
  border-color: var(--accent);
}
.os-field-check__input:checked + .os-field-check__box svg {
  opacity: 1;
  transform: scale(1);
}
.os-field-check__input:indeterminate + .os-field-check__box {
  background: var(--accent);
  border-color: var(--accent);
}
.os-field-check__input:indeterminate + .os-field-check__box::after {
  content: "";
  width: 9px;
  height: 1.5px;
  background: #fff;
  border-radius: 1px;
}
.os-field-check__input:focus-visible + .os-field-check__box {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}
.os-field-check:hover .os-field-check__input:not(:checked) + .os-field-check__box {
  border-color: var(--accent);
}
.os-field-check__input:disabled + .os-field-check__box {
  background: var(--surface-alt);
  border-color: var(--border);
}
.os-field-check__input:disabled ~ .os-field-check__text {
  color: var(--text-muted);
}
.os-field-check:has(.os-field-check__input:disabled) {
  cursor: not-allowed;
}
.os-field-check__text {
  display: block;
}
.os-field-check__text :is(.t, .os-t) {
  font-weight: 500;
  color: var(--text-primary);
}
.os-field-check__text :is(.d, .os-d) {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
  font-weight: 400;
}
/* Buttons — primary/secondary/ghost/destructive. Used by the FormBuilder
   submit helper + everywhere a form needs an action.
   Matches the inline patterns the conforming surfaces ship today. */
.os-field-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--control-h);   /* 36px at base density — tracks .os-btn */
  padding: 0 16px;            /* literal: this family ships 16px, not the button's 14px */
  font-family: var(--font-sans);
  font-size: var(--control-fs);
  font-weight: 500;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
}
.os-field-button:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}
.os-field-button:disabled, .os-field-button[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}
.os-field-button--primary {
  color: white;
  background: var(--accent);
  border-color: var(--accent);
}
.os-field-button--primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
.os-field-button--secondary {
  color: var(--text-primary);
  background: var(--surface);
  border-color: var(--border);
}
.os-field-button--secondary:hover {
  background: var(--surface-alt);
}
.os-field-button--ghost {
  color: var(--text-muted);
  background: transparent;
}
.os-field-button--ghost:hover {
  color: var(--text-primary);
}
/* Destructive — used for "Remove diver" etc. NOT for plain Cancel
   (Cancel uses ghost). Red text on neutral background; full-red bg
   reserved for confirmation modals. */
.os-field-button--destructive {
  color: #991B1B;
  background: var(--surface);
  border-color: var(--border);
}
.os-field-button--destructive:hover {
  background: #FEF2F2;
  border-color: #FECACA;
}
/* Size modifiers re-declare the trio on themselves, which pins them against
   any enclosing .os-density--* scope (tokens/density.css). NOTE --lg here is
   44px, NOT the 42px of .os-btn--lg — an existing divergence between the two
   button families. Left as-is on purpose: unifying them would resize shipped
   buttons, which a token contract must not do. Logged for a future minor. */
.os-field-button--sm { --control-h: var(--control-h-sm); padding: 0 12px; font-size: var(--text-sm); }
.os-field-button--lg { height: 44px; padding: 0 20px; font-size: var(--text-sm); }
/* Action bar that sits below the last form-section. Right-aligned by
   default — primary button trails so the eye lands there last. Stacks
   full-width on narrow screens so taps stay reachable. */
.os-form-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 24px;
}
.os-form-actions__leading {
  margin-right: auto;
}
@media (max-width: 640px) {
  .os-form-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }
  .os-form-actions .os-field-button { width: 100%; }
  .os-form-actions__leading { margin-right: 0; }
}
/* Touch targets on mobile per DESIGN.md a11y section. Bump small
   buttons + inputs to 44px so they hit the WCAG AAA threshold without
   requiring callers to remember per-screen overrides. */
@media (max-width: 640px) {
  .os-field-button { min-height: 44px; height: auto; padding: 11px 18px; }
  .os-input, .os-field-select, .os-textarea {
    min-height: 44px;
    padding: 12px 14px;
  }
}
/* v1.36.0 (#493): ONE field height. A single-line control inside a form field
   is exactly --control-h-field (46px) at every breakpoint, the same token
   .os-btn--field reads, so a field + field-button row lines up. Before, the
   height fell out of padding + line-height: 46px for a text input, 43px for a
   tel input (shorter line box), and 50px at <=640px (12px padding), which put
   inputs 4px taller than .os-btn--field on phones. Fixed height + zero block
   padding (the browser centres an input's text); still >= the 44px touch
   floor above. Scoped to field shells and field grids, so a bare .os-input in a toolbar keeps
   the --control-h contract. Not the --sm variants, not a textarea, not an
   input inside an affix box (the box draws the frame and takes the height). */
:is(.os-field, .field-grid__field, .os-field-grid__field, .field-grid, .os-field-grid) :is(input.os-input, .os-field-select):not(.os-input--sm, .os-field-select--sm, .os-field--affix *),
:is(.os-field, .field-grid__field, .os-field-grid__field, .field-grid, .os-field-grid) .os-field--affix:not(.os-field--affix-sm) {
  height: var(--control-h-field);
  min-height: 0;
}
:is(.os-field, .field-grid__field, .os-field-grid__field, .field-grid, .os-field-grid) :is(input.os-input, .os-field-select):not(.os-input--sm, .os-field-select--sm, .os-field--affix *) {
  padding-top: 0;
  padding-bottom: 0;
}
@media (prefers-reduced-motion: reduce) {
  .os-input, .os-field-select, .os-textarea, .os-field-button {
    transition: none;
  }
}
/* Phase 8 PR5 T7 — fitting-room size pill picker. Sits above each
   slot dropdown in the fitting drawer. Tapping a pill calls the
   fitting-size-filter Stimulus controller to filter the dropdown to
   items in that size. --active styles the currently selected pill. */
:is(.fitting-size-pill, .os-fitting-size-pill) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  /* v1.36.0 (#493 D3): on the control scale. Was an off-scale 28px; now
     --control-h-sm (32px, .os-btn--sm) on desktop, --control-h-base (36px) on
     phones (below). */
  min-height: var(--control-h-sm);
  padding: 2px 10px;
  font: 500 12px/1 var(--font-sans, system-ui);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 100ms ease, color 100ms ease, border-color 100ms ease;
}
:is(.fitting-size-pill, .os-fitting-size-pill):hover {
  background: var(--canvas);
}
:is(.fitting-size-pill, .os-fitting-size-pill):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
:is(.fitting-size-pill--active, .os-fitting-size-pill--active) {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
/* Tablet hit-target compliance: bump pill height to 36px on small
   viewports so the fitting room is usable on a 10" tablet without
   stylus-precision taps. */
@media (max-width: 640px) {
  :is(.fitting-size-pill, .os-fitting-size-pill) { min-height: var(--control-h-base); padding: 4px 14px; font-size: var(--text-sm); }
}
/* ── select2 (super_select) → DiveOS field substrate ──────────────────────
   Bullet Train's theme super_select.css styles select2's chrome with the BT
   palette (base-300 border, primary-500 accent). select2 hides the native
   <select> and renders its OWN box, so .diveos-select on the hidden element
   never shows — the BT-looking box IS this chrome. Restyle it ONCE here to
   match .diveos-input; every super_select field (27 views) inherits. Loaded
   after the theme; !important beats super_select's !important rules. */
:is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--single, .os-select2-selection--single), :is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--multiple, .os-select2-selection--multiple) {
  min-height: 40px !important;
  padding: 0 !important;
  background: var(--input-bg) !important;
  border: 1px solid var(--input-border) !important;
  border-radius: var(--radius-sm) !important;
  box-shadow: none !important;
  transition: border-color 100ms ease, box-shadow 100ms ease !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--single, .os-select2-selection--single):hover, :is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--multiple, .os-select2-selection--multiple):hover {
  border-color: var(--input-border-hover) !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--single, .os-select2-selection--single) :is(.select2-selection__rendered, .os-select2-selection__rendered) {
  padding: 0 12px !important;
  line-height: 38px !important;
  color: var(--text-primary) !important;
  font-size: var(--text-sm) !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--single, .os-select2-selection--single) :is(.select2-selection__arrow, .os-select2-selection__arrow) {
  height: 38px !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-selection__placeholder, .os-select2-selection__placeholder) {
  color: var(--input-placeholder) !important;
}
:is(.select2-container--default, .os-select2-container--default):is(.select2-container--open, .os-select2-container--open) :is(.select2-selection--single, .os-select2-selection--single), :is(.select2-container--default, .os-select2-container--default):is(.select2-container--open, .os-select2-container--open) :is(.select2-selection--multiple, .os-select2-selection--multiple), :is(.select2-container--default, .os-select2-container--default):is(.select2-container--focus, .os-select2-container--focus) :is(.select2-selection--single, .os-select2-selection--single), :is(.select2-container--default, .os-select2-container--default):is(.select2-container--focus, .os-select2-container--focus) :is(.select2-selection--multiple, .os-select2-selection--multiple) {
  border-color: var(--input-border-focus) !important;
  box-shadow: 0 0 0 3px var(--focus-ring) !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-dropdown, .os-select2-dropdown) {
  background: var(--surface) !important;
  border: 1px solid var(--input-border) !important;
  border-radius: var(--radius-md) !important;
  box-shadow: var(--shadow-md) !important;
  overflow: hidden !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-results__option, .os-select2-results__option) {
  color: var(--text-primary) !important;
  font-size: var(--text-sm) !important;
  padding: 8px 12px !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-results__option--highlighted, .os-select2-results__option--highlighted), :is(.select2-container--default, .os-select2-container--default) :is(.select2-results__option--highlighted, .os-select2-results__option--highlighted)[aria-selected] {
  background: var(--accent) !important;
  color: #fff !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-results__option, .os-select2-results__option)[aria-selected="true"] {
  background: var(--accent-soft, var(--surface-alt)) !important;
  color: var(--text-primary) !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-search--dropdown, .os-select2-search--dropdown) :is(.select2-search__field, .os-select2-search__field) {
  border: 1px solid var(--input-border) !important;
  border-radius: var(--radius-sm) !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-search--dropdown, .os-select2-search--dropdown) :is(.select2-search__field, .os-select2-search__field):focus {
  border-color: var(--input-border-focus) !important;
  box-shadow: 0 0 0 3px var(--focus-ring) !important;
  outline: none !important;
}
:is(.select2-container--default, .os-select2-container--default) :is(.select2-selection--multiple, .os-select2-selection--multiple) :is(.select2-selection__choice, .os-select2-selection__choice) {
  background: var(--accent-soft, var(--surface-alt)) !important;
  border: 1px solid var(--hairline) !important;
  border-radius: var(--radius-sm) !important;
  color: var(--text-primary) !important;
  margin-top: 7px !important;
}
/* ── Bullet Train .button family → DiveOS buttons ─────────────────────────
   The arena theme's .button / .button-secondary / .button-alternative /
   .button-red classes (BT palette: primary-500, base-300/500) back the file-
   upload buttons (active_storage "Upload New Image"), the buttons-toggle
   field, and any BT-rendered action control. Restyle the family ONCE here so
   every instance matches .diveos-button, no per-view edits. Loaded after the
   theme; ties on specificity, wins on source order. */
:is(.button, .os-button), :is(.button-secondary, .os-button-secondary), :is(.button-alternative, .os-button-alternative) {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  box-shadow: none;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
}
/* primary */
:is(.button, .os-button) {
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
}
:is(.button, .os-button):hover {
  color: #fff;
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
/* secondary / alternative (outlined) — the file-upload button look */
:is(.button-secondary, .os-button-secondary), :is(.button-alternative, .os-button-alternative) {
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border);
}
:is(.button-secondary, .os-button-secondary):hover, :is(.button-alternative, .os-button-alternative):hover {
  color: var(--text-primary);
  background: var(--surface-alt);
  border-color: var(--border);
}
/* danger */
:is(.button, .os-button):is(.button-red, .os-button-red), :is(.button-red, .os-button-red) {
  color: #fff;
  background: var(--red-600);
  border-color: var(--red-600);
}
:is(.button, .os-button):is(.button-red, .os-button-red):hover, :is(.button-red, .os-button-red):hover {
  color: #fff;
  background: var(--red-700);
  border-color: var(--red-700);
}
/* color-swatch buttons (color picker `.button-color`). Neutral DS shell
   matching the .button-alternative look; the swatch fill comes from the
   inline background-color style. Selected state (the BT `ring-2`) reads
   through --accent so the active swatch picks up the DS accent ring. */
:is(.button-color, .os-button-color) {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: none;
}
:is(.button-color, .os-button-color):is(.ring-2, .os-ring-2), :is(.button-color, .os-button-color):focus-visible {
  --tw-ring-color: var(--accent);
  outline: none;
}
/* ── File-upload widget chrome (file_field + active_storage_image) ─────────
   The ejected upload partials render a progress bar (`bg-primary-500`) and a
   thumbnail/progress panel (`bg-base-100`) straight from the BT palette.
   Retoken both centrally — the partials keep their markup, these win on
   source order. */
:is(.file-field, .os-file-field) [data-fields--file-field-target="progressBar"] {
  background: var(--accent);
}
:is(.file-field, .os-file-field) :is(.bg-base-100, .os-bg-base-100) {
  background: var(--surface);
}
/* ─────────────────────────────────────────────────────────────────────
   DiveOS form substrate — integration layer.

   The form COMPONENTS (.diveos-input, .diveos-select, .diveos-textarea,
   .diveos-label, .diveos-field, .diveos-check*, .diveos-button,
   .diveos-form-actions, .diveos-error, .diveos-hint, and the select2
   re-skin) now come from os-ds `patterns.css`, already imported in
   application.css. This sheet holds only what the gem does not own.

   De-vendored 2026-07-21. A media-query-aware rule diff found 82 of the
   previous 92 local rules byte-identical to the gem with ZERO drift —
   independently reproducing arena's "82 rules, 0 differences" result on
   the same file lineage. Those 82 were deleted; the 10 below remain.

   THESE 10 ARE UPSTREAM CANDIDATES. Per CLAUDE.md ("if a variant is
   missing, add it to the component — don't hand-roll a one-off"), most
   of what follows is a missing os-ds variant rather than genuinely
   DiveOS-specific styling. They are kept local only so the de-vendoring
   is not blocked on a gem release. Contribute them to os-ds, then delete
   this file.
   ───────────────────────────────────────────────────────────────────── */
/* The gem's adjacent-sibling rhythm (.diveos-field + .diveos-field) is for
   STACKED fields only. Inside a grid the container `gap` handles spacing, and
   that margin fires on DOM order regardless of layout — pushing every non-first
   cell down 22px and breaking horizontal alignment across columns (First Name
   vs Last Name sat 22px apart). Neutralize it for grid-laid fields.
   Form-alignment audit 2026-07; `.field-grid` added 2026-08 (the os-ds two-col
   form grid — e.g. Run pre-departure headcount + override — was missing here,
   so its 2nd column sat 22px low). */
:is(.grid, .os-grid, .field-grid) > :is(.diveos-field, .os-field), [class*="grid-cols"] > :is(.diveos-field, .os-field) {
  margin-top: 0;
}
/* Compact field that lines up with a .dv-btn (2.25rem / 36px) — for the
   input+button rows in headers/toolbars where the default 42px field sits
   taller than the buttons beside it. */
:is(.diveos-input--sm, .os-input--sm) { height: 2.25rem; padding-top: 0; padding-bottom: 0; }
/* Field-height controls (46px) for filter / search rows — the standalone
   counterparts to `.dv-btn--field` and `.dv-input-group--field` (both 46px), so
   a LABELLED horizontal bar of selects + inputs + buttons (the landing search
   bar) lines up at one height without wrapping every control in an input-group.
   Same 46px scale the header `.dv-filter-bar` already uses. */
:is(.diveos-input--field, .os-input--field), :is(.diveos-select--field, .os-field-select--field) { height: 46px; padding-top: 0; padding-bottom: 0; }
/* Square icon button at field height — the search-bar +/- stepper (`.dv-btn--icon`
   is a 36px square; `--field` lifts it to 46px tall, this squares the width). */
:is(.dv-btn--field, .os-btn--field):is(.dv-btn--icon, .os-btn--icon) { width: 46px; }
/* A .diveos-input used as an inline ROW (leading icon + text) — e.g. a <details>
   summary acting as a field. The base .diveos-input sets `display:block`, and
   this stylesheet loads AFTER Tailwind, so a `flex` utility on the element loses
   to it and the icon stacks above the text. Express the row here so it wins. */
:is(.diveos-input--row, .os-input--row) { display: flex; align-items: center; gap: 0.5rem; }
/* Suppress the native number-input spinner where a control supplies its OWN
   +/- stepper (the landing search bar's Divers field), so the browser arrows
   don't double the buttons. Scoped modifier — other number fields keep theirs. */
:is(.diveos-input--no-spinner, .os-input--no-spinner) { -moz-appearance: textfield; -webkit-appearance: textfield; appearance: textfield; }
:is(.diveos-input--no-spinner, .os-input--no-spinner)::-webkit-outer-spin-button, :is(.diveos-input--no-spinner, .os-input--no-spinner)::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* ── Input group — input + button(s) on one row, at one height ──────────────
   The default .diveos-input is padding-derived (~42px), sized for roomy stacked
   forms; .dv-btn is a fixed 36px, sized for tight action clusters. When the two
   share a horizontal row (a header action cluster, a filter/apply bar) they must
   be normalized to ONE height or they look misaligned. `.dv-input-group` is that
   row: it owns the shared height so the controls can't drift apart. Default =
   36px (matches .dv-btn); `.dv-input-group--field` = 46px (matches .dv-btn--field
   filter bars). Whenever a .diveos-input sits beside a .dv-btn, wrap them here —
   enforced by hallmark (dv_input_group signature). */
:is(.dv-input-group, .os-input-group) {
  display: flex;
  align-items: center;
  gap: 8px;
}
:is(.dv-input-group, .os-input-group) > :is(.diveos-input, .os-input), :is(.dv-input-group, .os-input-group) > :is(.diveos-select, .os-field-select) {
  width: auto;
  height: 36px;
  min-height: 0;
  padding-top: 0;
  padding-bottom: 0;
}
:is(.dv-input-group--field, .os-input-group--field) > :is(.diveos-input, .os-input), :is(.dv-input-group--field, .os-input-group--field) > :is(.diveos-select, .os-field-select), :is(.dv-input-group--field, .os-input-group--field) > :is(.dv-btn, .os-btn) {
  height: 46px;
}
/* #512 design pass — os-ds paints its calendar mask on every native date AND
   time picker indicator, so a flight-time field showed a calendar. A time field
   gets Lucide's clock instead (same mask technique, colour stays the token).
   Upstream to os-ds forms.css, then drop this. */
.os-input[type="time"]::-webkit-calendar-picker-indicator {
  -webkit-mask-image: var(--os-clock-glyph);
  mask-image: var(--os-clock-glyph);
}
:root {
  --os-clock-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/svg%3E");
}
/* Time field (themes/light/fields/_time_field → os-ds .os-time). The os-ds
   control sizes to max-content (HH:MM segment + AM/PM toggle, ~204px); in a
   2-up field grid at 370px that pushed the page sideways (#609 R1). Let the
   AM/PM toggle wrap under the time when the cell is narrower. */
.os-time-field .os-time { flex-wrap: wrap; max-width: 100%; row-gap: var(--space-2); }
/* The field itself must not outgrow its cell, or the wrap above never fires —
   the trip stop form (a flex row, field at flex 0 0 auto) pushed AM/PM 6px past
   a 375px screen. */
.os-time-field { max-width: 100%; }
/* #635 — the os-ds picker is 38px tall beside 46px text fields; match them on
   tablet/desktop, and on phone lift it to the 48px touch target.
   Upstream to os-ds, then drop this. */
.os-time-field :is(.os-seg, .os-ampm) { height: 46px; }
.os-time-field .os-seg input { width: var(--control-h-base); min-width: var(--control-h-base); }
@media (max-width: 640px) {
  .os-time-field :is(.os-seg, .os-ampm) { height: var(--space-12); }
  .os-time-field .os-seg input { width: var(--space-10); min-width: var(--space-10); font-size: var(--text-lg); }
  .os-time-field .os-ampm button { padding: 0 var(--space-5, 20px); }
}
/* Kanban board — the os-ds component (#354), then the app's full-bleed
   placement of its scroll shell (kanban.css), which must load after it. */
/* ─────────────────────────────────────────────────────────────────────
   .os-kanban — status board (columns of draggable cards) + .os-kanban-card.

   Promoted from dive-os (#354), where the leads and bookings boards each
   hand-built the same board out of utility soup (`flex-shrink-0 w-[300px]
   rounded-lg p-3 bg-canvas border …`) around app-local `.kanban-*` hooks.
   This sheet owns the whole board chrome; the consuming app owns only the
   behaviour (a Stimulus controller binding `data-*-target`s, never these
   class names) and, if it wants one, a full-bleed placement of the shell.

   Anatomy
     .os-kanban                 scroll shell: own x-scroller with edge fades
       .os-kanban__track        the flex row of columns (fixed board height)
         .os-kanban__column     one lane (300px, canvas, hairline, radius)
           .os-kanban__head     title + count row
             .os-kanban__title  the lane label (usually a .status-pill)
             .os-kanban__count  "7" or "10 of 12" (mono, tabular)
           .os-kanban__cards    the list; scrolls vertically; drop zone
             .is-drop-target    while a card is dragged over it
             .os-kanban-card …  the cards
             .os-kanban__empty  quiet one-line "No leads" when the lane is empty
             .os-kanban__more   "View all" footer on a capped lane

     .os-kanban-card            draggable card (surface, hairline, grab cursor)
       .os-kanban-card__main    avatar + body row
         .os-kanban-card__body  the text stack (min-width 0 so text truncates)
           .os-kanban-card__title  the card's headline (a link or text)
           .os-kanban-card__sub    one muted secondary line (email / phone)
       .os-kanban-card__meta    row of small facts (wraps)
         .os-kanban-card__chip  one fact: icon + text   (--mono: tabular figures)
       .os-kanban-card__foot    hairline-topped status + actions row
     States:    .is-dragging (source card mid-drag), .is-clickable (the whole
                card is the click target — hover tint; pair with a stretched link)
     Modifier:  .os-kanban-card--compact (tighter padding + rhythm)

   Phones keep the horizontal scroll: lanes stay 300px and the shell scrolls.
   Token-only (var(--token)); no raw hex, no raw Tailwind palette.
   ───────────────────────────────────────────────────────────────────── */
/* ── Scroll shell ─────────────────────────────────────────────────────
   Scroll-shadow (pure CSS, Lea Verou technique): the two `local` "cover"
   gradients move WITH the content and mask the pinned `scroll` shadow
   gradients — so a soft edge fade appears only when there's more to scroll
   in that direction, signalling "scroll for more" rather than a hard cut. */
.os-kanban {
  overflow-x: auto;
  overflow-y: hidden;
  background:
    linear-gradient(to right, var(--canvas), transparent 28px) 0 0 / 28px 100% no-repeat local,
    linear-gradient(to left,  var(--canvas), transparent 28px) 100% 0 / 28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,   color-mix(in srgb, var(--ink) 8%, transparent), transparent) 0 0 / 16px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--ink) 8%, transparent), transparent) 100% 0 / 16px 100% no-repeat scroll;
}
/* ── Track: the row of lanes ──────────────────────────────────────────── */
.os-kanban__track {
  display: flex;
  gap: var(--space-3);
  width: -moz-max-content;
  width: max-content;
  height: 78vh;
  padding-bottom: var(--space-6);
  overflow: hidden;
}
/* ── Column (lane) ────────────────────────────────────────────────────── */
.os-kanban__column {
  flex: 0 0 auto;
  width: 300px;
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
  overflow: hidden;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}
.os-kanban__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-inline: var(--space-1);
  margin-bottom: var(--space-3);
}
.os-kanban__title {
  display: inline-flex;
  align-items: center;
  min-width: 0;
}
.os-kanban__count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
}
/* ── Card list (drop zone) ────────────────────────────────────────────── */
.os-kanban__cards {
  flex: 1 1 0%;
  min-height: 0;                     /* let the list scroll inside the lane */
  overflow-y: auto;
  padding: 0 var(--space-1) var(--space-2);
}
.os-kanban__cards > * + * { margin-top: var(--space-2); }
.os-kanban__cards.is-drop-target {
  background-color: var(--accent-light);
  border: 2px dashed var(--accent);
  border-radius: var(--radius);
}
/* Quiet empty lane — one muted line, not the full empty-state card. */
.os-kanban__empty {
  padding: var(--space-4) var(--space-2);
  text-align: center;
  font-size: var(--text-xs);
  color: var(--muted-2);
}
/* "View all" footer on a capped lane. */
.os-kanban__more {
  padding-top: var(--space-2);
  border-top: 1px solid var(--hairline-2);
  text-align: center;
}
/* ── Card ─────────────────────────────────────────────────────────────── */
.os-kanban-card {
  display: block;
  padding: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  cursor: grab;
  transition: color var(--t-fast) ease, background-color var(--t-fast) ease, border-color var(--t-fast) ease;
}
.os-kanban-card:hover { border-color: var(--hairline-strong); }
.os-kanban-card:active { cursor: grabbing; }
.os-kanban-card:focus { outline: none; box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.3); }
/* The source card keeps the normal card look while dragged — the browser
   paints the translucent ghost that follows the cursor, so the source needs
   no fade/lift/tilt (0.5 opacity read as disabled). A stable hook only. */
.os-kanban-card.is-dragging { opacity: 1; }
/* Whole card is the click target (pair with a stretched link on the title). */
.os-kanban-card.is-clickable { position: relative; }
.os-kanban-card.is-clickable:hover { background: var(--surface-alt); }
/* Identity row: avatar + text stack. */
.os-kanban-card__main {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.os-kanban-card__body { flex: 1 1 0%; min-width: 0; }
.os-kanban-card__title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 20px;
  color: var(--ink);
  text-decoration: none;
}
/* :where() keeps the hover at class weight so a consumer's stretched-link
   rule (which must read as plain text) can override it. */
:where(a.os-kanban-card__title) { transition: color var(--t-fast) ease; }
:where(a.os-kanban-card__title):hover { color: var(--accent); }
.os-kanban-card__sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-xs);
  color: var(--muted);
}
/* Fact row. Wraps (row-gap) so a trailing chip cluster never overflows. */
.os-kanban-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px var(--space-3);
  margin-top: 10px;
  font-size: var(--text-xs);
}
.os-kanban-card__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
  color: var(--muted);
}
.os-kanban-card__chip--mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
/* Status + actions row. */
.os-kanban-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--hairline-2);
}
/* ── Compact: denser lanes (tighter padding + rhythm) ─────────────────── */
.os-kanban-card--compact { padding: var(--space-2) 10px; }
.os-kanban-card--compact .os-kanban-card__meta { margin-top: 6px; }
.os-kanban-card--compact .os-kanban-card__foot { margin-top: 6px; padding-top: 6px; }
/* ────────────────────────────────────────────────────────────────────────
   Kanban board placement — the only app-specific part of the board.

   The board itself (scroll shell + edge fades, track, columns, cards, drop
   and drag states) is the os-ds `.os-kanban` / `.os-kanban-card` component
   (os_ds/components/kanban.css, #354). What stays here is DiveOS layout:
   the shell breaks out of the centered `.diveos-content` column (same bleed
   math as `.dv-page-band`) so it uses the full pane width — otherwise the
   columns hit the 48px inner padding and get sliced early, reading as a
   broken clip instead of a scrollable board. The first column stays aligned
   with the page content via padding-inline-start; columns scroll under the
   pane edges.
   ──────────────────────────────────────────────────────────────────────── */
.os-kanban {
  width: var(--bleed-w);                 /* full-bleed to pane; lanes scroll edge-to-edge */
  margin-inline: var(--bleed-mx);
  padding-inline: var(--bleed-pad);      /* first lane aligns to the tier column */
  scroll-padding-inline-start: var(--bleed-pad);
}
/* DiveOS — M1 Today Dashboard (T9)
   Visual system locked in DESIGN.md. Status palette + spacing scale + typography
   are project-wide; this file scopes them to `.dashboard` to avoid bleeding into
   other Bullet Train surfaces during the v1 fork. */
/* Fonts loaded by tokens.css — no import needed here. */
/* ════════════════════════════════════════════════════════════════════
   WL "Today (open)" benchmark — open-row layout (synced 2026-06-02)
   Mirrors White-label project/pages/index.html `.dv-open-row` family.
   Replaces the boxed-card trip row + KPI cards with the inline stat
   strip + full-bleed status-railed open rows. DM class names kept where
   they already existed (.status-pill); new structural primitives below.
   ════════════════════════════════════════════════════════════════════ */
/* Inline-text stat strip (replaces boxed KPI cards). WL §6. */
:is(.stat-strip, .os-stat-strip) {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 14px 56px;
  margin: 0;
}
:is(.stat-strip__item, .os-stat-strip__item) { display: flex; align-items: baseline; gap: 10px; }
:is(.stat-strip__num, .os-stat-strip__num) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-3xl);
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--accent);
}
:is(.stat-strip__num--briefing, .os-stat-strip__num--briefing) { color: var(--status-briefing-fg); }
:is(.stat-strip__label, .os-stat-strip__label) { font-size: var(--text-sm); color: var(--muted); }
/* Section label — MORNING / AFTERNOON. WL §2 (no trip count). WL uses
   px-14 pt-8 pb-4 = 56px L/R, 32px top, 16px bottom. */
:is(.day-section, .os-day-section) {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 32px 56px 16px;
}
:is(.day-section__label, .os-day-section__label) {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}
/* Open-row grid — WL §5. rail | time | body | divers | chevron. */
:is(.dv-open-row, .os-open-row) {
  display: grid;
  grid-template-columns: 16px 124px 1fr 168px 24px;
  gap: 28px;
  align-items: start;
  padding: 22px 56px 22px 40px;
  border-top: 1px solid var(--hairline);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--t-med) ease;
}
/* The last row closes the list with a bottom hairline. Each .dv-open-row now
   sits in its own [role=listitem] wrapper (#144), so :last-of-type on the <a>
   would match every row — target the last wrapper instead. */
[role="listitem"]:last-child > :is(.dv-open-row, .os-open-row) { border-bottom: 1px solid var(--hairline); }
/* Kill Bullet Train's global a:hover underline on the whole clickable row. */
:is(.dv-open-row, .os-open-row):hover { background: var(--hover-warm); text-decoration: none; }
:is(.dv-open-row, .os-open-row):hover, :is(.dv-open-row, .os-open-row):hover * { text-decoration: none; }
/* Full-bleed band: extends a section's background to the .diveos-main edges
   (past the centered .diveos-content gutters), then re-insets its content to
   the column so it aligns with the body. Content-edge bleed: cancel the fluid
   --gutter to span the tier column, then re-pad by --gutter. Used for the white
   Today header band. */
:is(.dv-full-bleed, .os-full-bleed) {
  width: var(--bleed-w);
  margin-inline: var(--bleed-mx);
  padding-inline: var(--bleed-pad);
}
:is(.dv-open-row, .os-open-row):focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: -2px;
}
:is(.dv-open-row__rail, .os-open-row__rail) {
  width: 3px;
  height: 52px;
  background: var(--bar-pending);
  border-radius: 3px;
  margin-top: 8px;
  transition: background var(--t-med) ease;
}
:is(.dv-open-row, .os-open-row)[data-status="briefing"]  :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--bar-briefing); }
:is(.dv-open-row, .os-open-row)[data-status="in_water"]   :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--bar-inwater); }
:is(.dv-open-row, .os-open-row)[data-status="confirmed"] :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--bar-confirmed); }
:is(.dv-open-row, .os-open-row)[data-status="cancelled"] :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--bar-cancelled); }
:is(.dv-open-row, .os-open-row)[data-status="briefing"]:hover  :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--status-briefing-fg); }
:is(.dv-open-row, .os-open-row)[data-status="in_water"]:hover   :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--status-in-water-fg); }
:is(.dv-open-row, .os-open-row)[data-status="confirmed"]:hover :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--status-confirmed-fg); }
:is(.dv-open-row, .os-open-row)[data-status="cancelled"]:hover :is(.dv-open-row__rail, .os-open-row__rail) { background: var(--status-cancelled-fg); }
/* Time column */
:is(.dv-open-row__time, .os-open-row__time) {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
:is(.dv-open-row__time-sep, .os-open-row__time-sep) { color: var(--muted-2); margin: 0 1px; }
:is(.dv-open-row__time-label, .os-open-row__time-label) {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Body: title + route + guide/vessel */
:is(.dv-open-row__title, .os-open-row__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.01em;
  color: var(--ink);
}
:is(.dv-open-row__stops, .os-open-row__stops) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  font-size: var(--text-sm);
  color: var(--muted);
}
:is(.dv-open-row__stops, .os-open-row__stops) :is(.sep, .os-sep) { color: var(--muted-2); }
:is(.dv-open-row__crew, .os-open-row__crew) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  font-size: var(--text-xs);
  color: var(--muted);
}
:is(.dv-open-row__crew, .os-open-row__crew) b { font-weight: 600; color: var(--ink); }
:is(.dv-open-row__vessel, .os-open-row__vessel) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-2);
  padding-left: 14px;
  border-left: 1px solid var(--hairline);
}
/* Divers count column */
:is(.dv-open-row__count, .os-open-row__count) {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
:is(.dv-open-row__count--confirmed, .os-open-row__count--confirmed) { color: var(--status-confirmed-fg); }
:is(.dv-open-row__count--briefing, .os-open-row__count--briefing)  { color: var(--status-briefing-fg); }
:is(.dv-open-row__count-max, .os-open-row__count-max) { color: var(--muted-2); font-size: var(--text-md); font-weight: 400; }
:is(.dv-open-row__count-label, .os-open-row__count-label) {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-2);
}
/* Progress underline (track + status-colored fill). DM had no equivalent
   primitive — the old row used an inline Tailwind bar. GAP-001 flagged. */
:is(.progress-underline, .os-progress-underline) {
  position: relative;
  width: 100%;
  height: 3px;
  background: var(--hairline);
  border-radius: 999px;
  overflow: hidden;
  margin: 10px 0 6px;
}
:is(.progress-underline__fill, .os-progress-underline__fill) {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width var(--t-med) ease;
}
:is(.progress-underline__fill--confirmed, .os-progress-underline__fill--confirmed) { background: var(--status-confirmed-fg); }
:is(.progress-underline__fill--briefing, .os-progress-underline__fill--briefing)  { background: var(--status-briefing-fg); }
:is(.progress-underline__fill--in_water, .os-progress-underline__fill--in_water)  { background: var(--status-in-water-fg); }
:is(.progress-underline__fill--cancelled, .os-progress-underline__fill--cancelled) { background: var(--status-cancelled-fg); }
/* Chevron — revealed on row hover */
:is(.dv-open-row__chev, .os-open-row__chev) {
  align-self: center;
  width: 18px;
  height: 18px;
  color: var(--muted-2);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity var(--t-fast) ease, transform var(--t-med) var(--ease-out-quart);
}
:is(.dv-open-row, .os-open-row):hover :is(.dv-open-row__chev, .os-open-row__chev) { opacity: 1; transform: translateX(0); }
/* Cancelled-state row styling (WL page-local <style>, promoted here) */
:is(.dv-open-row, .os-open-row)[data-status="cancelled"] :is(.dv-open-row__title, .os-open-row__title), :is(.dv-open-row, .os-open-row)[data-status="cancelled"] :is(.dv-open-row__time, .os-open-row__time) { color: var(--muted); }
:is(.dv-open-row, .os-open-row)[data-status="cancelled"] :is(.dv-open-row__stops, .os-open-row__stops) {
  text-decoration: line-through;
  text-decoration-color: var(--hairline);
}
@media (max-width: 720px) {
  :is(.dv-open-row, .os-open-row) {
    grid-template-columns: 12px 88px 1fr;
    gap: 16px;
    padding: 18px 16px;
  }
  :is(.dv-open-row__count-col, .os-open-row__count-col) { display: none; }
  :is(.dv-open-row__chev, .os-open-row__chev) { display: none; }
  :is(.stat-strip, .os-stat-strip) { gap: 10px 28px; }
  :is(.day-section, .os-day-section) { padding: 24px 16px 12px; }
}
:is(.dashboard, .os-dashboard) {
  font-family: var(--font-sans);
  color: var(--text-primary);
  background: var(--bg);
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 16px 96px;
}
@media (min-width: 768px) {
  :is(.dashboard, .os-dashboard) { padding: 32px 24px 96px; }
}
/* Offline banner — sticky at top */
:is(.dashboard__offline-banner, .os-dashboard__offline-banner) {
  position: sticky;
  top: 0;
  margin: -24px -16px 16px;
  padding: 8px 16px;
  background: #FEF3C7;
  color: #92400E;
  font-size: var(--text-sm);
  font-weight: 500;
  z-index: 10;
}
/* T-M2 Service-Due dashboard widget. Briefing palette (amber) per
   DESIGN.md — recoverable, not destructive. Sits between header + trips. */
:is(.dashboard__service-due, .os-dashboard__service-due) {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 16px;
  padding: 12px 16px;
  background: #FEF3C7;
  color: #92400E;
  border: 1px solid #FBBF24;
  border-radius: var(--radius-md);
}
:is(.dashboard__service-due-icon, .os-dashboard__service-due-icon) { flex-shrink: 0; padding-top: 1px; }
:is(.dashboard__service-due-body, .os-dashboard__service-due-body) { flex: 1; }
:is(.dashboard__service-due-label, .os-dashboard__service-due-label) {
  margin: 0 0 2px 0;
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
:is(.dashboard__service-due-meta, .os-dashboard__service-due-meta) {
  margin: 0;
  font-size: var(--text-sm);
}
:is(.dashboard__service-due-link, .os-dashboard__service-due-link) {
  color: inherit;
  text-decoration: underline;
  font-weight: 500;
}
:is(.dashboard__service-due-link, .os-dashboard__service-due-link):hover { text-decoration: none; }
/* Header */
:is(.dashboard__header, .os-dashboard__header) {
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
:is(.dashboard__header-left, .os-dashboard__header-left) {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
:is(.dashboard__logo, .os-dashboard__logo) {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
}
:is(.dashboard__title, .os-dashboard__title) {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
}
@media (min-width: 768px) {
  :is(.dashboard__title, .os-dashboard__title) { font-size: var(--text-3xl); }
}
:is(.dashboard__summary, .os-dashboard__summary) {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
}
:is(.dashboard__summary-stat, .os-dashboard__summary-stat) {
  font-variant-numeric: tabular-nums;
}
:is(.dashboard__summary-sep, .os-dashboard__summary-sep) { color: var(--text-muted); margin: 0 6px; }
/* Trip list */
:is(.dashboard__trips, .os-dashboard__trips) {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Trip row */
:is(.trip-row, .os-trip-row) {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
:is(.trip-row__link, .os-trip-row__link) {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 16px;
  min-height: 88px;
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
@media (min-width: 768px) {
  :is(.trip-row__link, .os-trip-row__link) { grid-template-columns: 80px 1fr auto; }
}
/* QA-002: at narrow viewports the BT account sidebar leaves ~300px for the
   dashboard column; the auto-width meta column was eating into the body
   (site + boat + guide) and hiding it via overflow:hidden. Hide the chevron
   (the whole row is already a link — chevron is redundant) and tighten the
   capacity chip to give the body room. */
@media (max-width: 640px) {
  :is(.trip-row__chevron, .os-trip-row__chevron) { display: none; }
  :is(.trip-row__meta, .os-trip-row__meta) { gap: 6px; }
  :is(.trip-row__capacity, .os-trip-row__capacity) { padding: 2px 6px; font-size: var(--text-xs); }
}
:is(.trip-row__link, .os-trip-row__link):hover { background: var(--surface-alt); }
:is(.trip-row__link, .os-trip-row__link):focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: -2px;
  border-radius: var(--radius-md);
}
:is(.trip-row__time, .os-trip-row__time) {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  letter-spacing: -0.02em;
}
@media (min-width: 768px) {
  :is(.trip-row__time, .os-trip-row__time) { font-size: var(--text-3xl); }
}
:is(.trip-row__body, .os-trip-row__body) { min-width: 0; }
:is(.trip-row__primary, .os-trip-row__primary) {
  font-size: var(--text-md);
  font-weight: 500;
  margin: 0 0 2px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is(.trip-row__secondary, .os-trip-row__secondary) {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is(.trip-row__sep, .os-trip-row__sep) { color: var(--text-muted); margin: 0 6px; }
:is(.trip-row__missing, .os-trip-row__missing) { color: var(--text-muted); font-style: italic; }
/* OBS-002: +N badge for multi-site / multi-guide trips. Small, neutral,
   tucked inline. font-variant-numeric: tabular-nums keeps "+12" and "+1"
   aligned on the same row. */
:is(.trip-row__extra, .os-trip-row__extra) {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  background: var(--surface-alt);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  vertical-align: 1px;
}
:is(.trip-row__meta, .os-trip-row__meta) {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
:is(.trip-row__capacity, .os-trip-row__capacity) {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  padding: 2px 8px;
  background: var(--surface-alt);
  border-radius: var(--radius-pill);
}
:is(.trip-row__chevron, .os-trip-row__chevron) {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}
/* Row state modifiers — kept light per DESIGN.md visual restraint. The
   status pill chip carries the meaning. --now adds a slim accent edge
   indicator on the left; no full-row background tint (that competed
   with the status pill colors and made the page feel busy). */
:is(.trip-row--now, .os-trip-row--now) {
  border-left: 3px solid var(--accent);
}
:is(.trip-row--completed, .os-trip-row--completed) { opacity: 0.65; }
:is(.trip-row--cancelled, .os-trip-row--cancelled) { opacity: 0.65; }
:is(.trip-row--cancelled, .os-trip-row--cancelled) :is(.trip-row__time, .os-trip-row__time) {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
}
/* Signature pulse — fires when a Turbo Stream replaces the row */
@keyframes dashboard-pulse {
  0%   { background-color: var(--accent-tint); }
  100% { background-color: var(--surface); }
}
:is(.trip-row--pulse, .os-trip-row--pulse) { animation: dashboard-pulse 200ms cubic-bezier(0, 0, 0.2, 1); }
/* Status pills — MOVED to the os-ds gem (os_ds/patterns.css, "Status pill").
   The gem now owns the whole component: the .status-pill base, .status-icon,
   the --sm/--square modifiers, both dot spellings, the seven colour variants,
   and the button.status-pill interactive states. Do NOT redefine any
   `.status-pill*` rule here — a local copy silently overrides the gem and the
   two systems drift apart. The app keeps only the Ruby side: status nicknames,
   labels, and the domain->variant mapping (app/helpers/status_palette_helper.rb). */
/* Empty state */
:is(.dashboard__empty, .os-dashboard__empty) {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 96px 16px 64px;
  color: var(--text-secondary);
}
:is(.dashboard__empty-art, .os-dashboard__empty-art) {
  color: var(--gray-300);
  width: 240px;
  height: 160px;
  margin-bottom: 32px;
  opacity: 0.7;
}
:is(.dashboard__empty-art, .os-dashboard__empty-art) svg { width: 100%; height: 100%; }
:is(.dashboard__empty-line, .os-dashboard__empty-line) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  color: var(--text-secondary);
  margin: 0 0 8px;
}
:is(.dashboard__empty-hint, .os-dashboard__empty-hint) {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0 0 24px;
  max-width: 360px;
}
:is(.dashboard__empty-photo, .os-dashboard__empty-photo) {
  width: 100%;
  max-width: 480px;
  margin-bottom: 24px;
  border-radius: var(--radius-lg, 12px);
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
:is(.dashboard__empty-photo, .os-dashboard__empty-photo) img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  display: block;
}
:is(.dashboard__empty-cta, .os-dashboard__empty-cta) {
  display: inline-flex;
  align-items: center;
  padding: 10px 20px;
  background: var(--accent);
  color: white;
  font-size: var(--text-sm);
  font-weight: 500;
  border-radius: var(--radius-sm);
  text-decoration: none;
  min-height: 44px;
  box-sizing: border-box;
  transition: background-color 150ms ease;
}
:is(.dashboard__empty-cta, .os-dashboard__empty-cta):hover { background: var(--accent-strong); }
:is(.dashboard__empty-cta, .os-dashboard__empty-cta):focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}
/* Skeleton loader */
@keyframes skeleton-shimmer {
  0% { opacity: 0.5; }
  50% { opacity: 0.8; }
  100% { opacity: 0.5; }
}
:is(.trip-row--skeleton, .os-trip-row--skeleton) :is(.trip-row__time, .os-trip-row__time), :is(.trip-row--skeleton, .os-trip-row--skeleton) :is(.trip-row__body, .os-trip-row__body), :is(.trip-row--skeleton, .os-trip-row--skeleton) :is(.trip-row__meta, .os-trip-row__meta) {
  pointer-events: none;
}
:is(.skeleton-bar, .os-skeleton-bar) {
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
:is(.skeleton-bar--time, .os-skeleton-bar--time)      { height: 28px; width: 64px; }
:is(.skeleton-bar--primary, .os-skeleton-bar--primary)   { height: 16px; width: 70%; margin-bottom: 6px; }
:is(.skeleton-bar--secondary, .os-skeleton-bar--secondary) { height: 14px; width: 50%; }
:is(.skeleton-bar--chip, .os-skeleton-bar--chip)      { height: 20px; width: 80px; }
/* Partial-state warning icon — accompanies "— site TBD" / "— guide unassigned" */
:is(.trip-row__missing-icon, .os-trip-row__missing-icon) {
  display: inline-block;
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  color: var(--status-briefing-fg, #92400E);
  margin-right: 2px;
}
:is(.trip-row__missing-text, .os-trip-row__missing-text) { /* hook for emphasis if needed */ }
/* Error state — design spec D4 */
:is(.dashboard__error, .os-dashboard__error) {
  margin: 24px auto;
  padding: 32px 24px;
  max-width: 480px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 8px);
  text-align: center;
}
:is(.dashboard__error-line, .os-dashboard__error-line) {
  font-size: var(--text-lg);
  font-weight: 500;
  color: var(--text);
  margin: 0 0 16px;
}
:is(.dashboard__error-actions, .os-dashboard__error-actions) { margin-bottom: 16px; }
:is(.dashboard__error-retry, .os-dashboard__error-retry) {
  display: inline-block;
  padding: 8px 20px;
  background: var(--accent);
  color: #FFFFFF;
  border-radius: var(--radius-pill, 999px);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
}
:is(.dashboard__error-retry, .os-dashboard__error-retry):hover { opacity: 0.9; }
:is(.dashboard__error-details, .os-dashboard__error-details) {
  margin-top: 16px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: left;
}
:is(.dashboard__error-details, .os-dashboard__error-details) summary { cursor: pointer; }
:is(.dashboard__error-details, .os-dashboard__error-details) pre {
  margin-top: 8px;
  padding: 8px;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  white-space: pre-wrap;
  overflow-x: auto;
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  :is(.trip-row--pulse, .os-trip-row--pulse) { animation: none; }
  :is(.skeleton-bar, .os-skeleton-bar) { animation: none; }
  :is(.trip-row, .os-trip-row), :is(.dashboard__empty-cta, .os-dashboard__empty-cta) { transition-duration: 1ms !important; }
}
/* Phase 5 — Trip workflow split layout + stepper + timeline.
   Fonts loaded by tokens.css — no import needed here. */
/* ─── Split layout ──────────────────────────────────────────── */
:is(.dv-trip-split, .os-trip-split) {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 24px;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 24px 64px;
}
@media (max-width: 1023px) {
  :is(.dv-trip-split, .os-trip-split) { grid-template-columns: 1fr; }
  :is(.dv-trip-split__rail, .os-trip-split__rail) { order: -1; }
}
/* ─── Trip header ───────────────────────────────────────────── */
:is(.dv-trip-header, .os-trip-header) { margin-bottom: 24px; }
:is(.dv-trip-header__breadcrumb, .os-trip-header__breadcrumb) {
  font-size: var(--text-sm);
  color: var(--text-muted, #6B7280);
  margin-bottom: 8px;
}
:is(.dv-trip-header__crumb-link, .os-trip-header__crumb-link) {
  color: var(--accent, #0369A1);
  text-decoration: none;
}
:is(.dv-trip-header__crumb-link, .os-trip-header__crumb-link):hover { text-decoration: underline; }
:is(.dv-trip-header__crumb-current, .os-trip-header__crumb-current) { color: var(--text-primary, #111827); }
:is(.dv-trip-header__title, .os-trip-header__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-3xl);
  letter-spacing: -0.02em;
  color: var(--text-primary, #111827);
  margin: 0 0 8px;
}
:is(.dv-trip-header__time, .os-trip-header__time) {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--text-xl);
  color: var(--text-muted, #6B7280);
  margin-left: 12px;
}
:is(.dv-trip-header__meta, .os-trip-header__meta) {
  font-size: var(--text-sm);
  color: var(--text-muted, #6B7280);
}
/* ─── Tab bar ───────────────────────────────────────────────── */
:is(.dv-tabs, .os-tabs) {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border, #E5E7EB);
  margin-bottom: 24px;
}
:is(.dv-tab, .os-tab) {
  padding: 12px 16px;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted, #6B7280);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color 150ms ease-out, border-color 150ms ease-out;
}
:is(.dv-tab, .os-tab):hover { color: var(--text-primary, #111827); }
:is(.dv-tab--active, .os-tab--active), :is(.dv-tab, .os-tab)[aria-selected="true"] {
  color: var(--accent, #0369A1);
  border-bottom-color: var(--accent, #0369A1);
}
:is(.dv-tab__count, .os-tab__count) {
  font-size: var(--text-xs);
  color: var(--text-muted, #9CA3AF);
  margin-left: 4px;
}
:is(.dv-tab--active, .os-tab--active) :is(.dv-tab__count, .os-tab__count) { color: var(--accent, #0369A1); }
/* ─── Stepper ───────────────────────────────────────────────── */
:is(.dv-stepper, .os-stepper) {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  padding: 16px;
  background: var(--surface, #FFFFFF);
  border: 1px solid var(--border, #E5E7EB);
  border-radius: 10px;
  margin-bottom: 16px;
}
:is(.dv-stepper__step, .os-stepper__step) {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
:is(.dv-stepper__circle, .os-stepper__circle) {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 600;
  background: var(--surface-alt, #F3F4F6);
  color: var(--text-muted, #9CA3AF);
  border: 1.5px solid var(--border, #E5E7EB);
  transition: all 200ms ease-out;
}
:is(.dv-stepper__step--done, .os-stepper__step--done) :is(.dv-stepper__circle, .os-stepper__circle) {
  background: #15803D;
  color: #FFFFFF;
  border-color: #15803D;
}
:is(.dv-stepper__step--current, .os-stepper__step--current) :is(.dv-stepper__circle, .os-stepper__circle) {
  background: var(--accent, #0369A1);
  color: #FFFFFF;
  border-color: var(--accent, #0369A1);
  box-shadow: 0 0 0 3px rgba(3, 105, 161, 0.15);
}
:is(.dv-stepper__label, .os-stepper__label) {
  font-size: var(--text-2xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted, #9CA3AF);
  text-align: center;
}
:is(.dv-stepper__step--done, .os-stepper__step--done) :is(.dv-stepper__label, .os-stepper__label) { color: #15803D; }
:is(.dv-stepper__step--current, .os-stepper__step--current) :is(.dv-stepper__label, .os-stepper__label) { color: var(--accent, #0369A1); font-weight: 600; }
/* ─── Next Action card ──────────────────────────────────────── */
:is(.dv-next-action, .os-next-action) {
  padding: 16px;
  background: rgba(3, 105, 161, 0.04);
  border: 1px solid rgba(3, 105, 161, 0.15);
  border-radius: 10px;
  margin-bottom: 16px;
}
:is(.dv-next-action__label, .os-next-action__label) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--text-primary, #111827);
  margin-bottom: 4px;
}
:is(.dv-next-action__hint, .os-next-action__hint) {
  font-size: var(--text-sm);
  color: var(--text-muted, #6B7280);
  margin: 0 0 12px;
}
:is(.dv-next-action__btn, .os-next-action__btn) {
  display: inline-flex;
  padding: 8px 16px;
  background: var(--accent, #0369A1);
  color: #FFFFFF;
  border: none;
  border-radius: 8px;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms ease-out;
}
:is(.dv-next-action__btn, .os-next-action__btn):hover { background: var(--accent-strong); }
/* (The boxed .dv-timeline operation-timeline block retired — the trip
   page's timeline moved to shared/patterns/rail_card + timeline, and the
   class names collided with the drawer stop timeline in account/dives.css.) */
/* ─── Guide row ─────────────────────────────────────────────── */
:is(.dv-guide-row, .os-guide-row) {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
}
:is(.dv-badge, .os-badge) {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-radius: 9999px;
  border: 1px solid;
  /* A badge is an atomic pill: never let a narrow flex parent (e.g. the mobile
     card-stack DIVES cell) shrink it and wrap "Fun Dive" one letter per line.
     The label beside it is the flexible member that truncates, not the badge. */
  white-space: nowrap;
  flex-shrink: 0;
}
:is(.dv-badge--lead, .os-badge--lead) { color: var(--confirmed); background: var(--confirmed-bg); border-color: var(--confirmed-border); }
:is(.dv-badge--assistant, .os-badge--assistant) { color: var(--inwater); background: var(--inwater-bg); border-color: var(--inwater-border); }
/* Non-status modifiers: count chip (accent) + neutral tag. Not uppercase/tracked
   like the base — these are inline counts/labels, so they reset those props. */
:is(.dv-badge--count, .os-badge--count) { color: var(--accent); background: var(--accent-soft); border-color: transparent; text-transform: none; letter-spacing: 0; }
:is(.dv-badge--neutral, .os-badge--neutral) { color: var(--ink); background: var(--surface-alt); border-color: transparent; text-transform: none; letter-spacing: 0; }
/* Muted entity-TYPE tag — stays uppercase/tracked (unlike --neutral), muted on
   a quiet surface fill. For role/type labels (Instructor, Divemaster). */
:is(.dv-badge--muted, .os-badge--muted) { color: var(--muted); background: var(--surface-alt); border-color: transparent; }
/* Status variants — quiet status badges (same triplets as the status pills).
   Promoted from .bk-detail scope so .dv-badge is a complete GLOBAL component:
   the showcase + any surface can render a status badge, and hand-rolled
   lookalikes can migrate to it. The .bk-detail copies (bookings.css) are now
   redundant but harmless (identical values, just higher specificity). */
/* Variant names match the status enum KEYS exactly (in_water, not inwater) so a
   surface can map programmatically: dv-badge--#{presentation[:key]}. */
:is(.dv-badge--confirmed, .os-badge--confirmed) { color: var(--confirmed); background: var(--confirmed-bg); border-color: var(--confirmed-border); }
:is(.dv-badge--pending, .os-badge--pending)   { color: var(--pending);   background: var(--pending-bg);   border-color: var(--pending-border); }
:is(.dv-badge--briefing, .os-badge--briefing)  { color: var(--briefing);  background: var(--briefing-bg);  border-color: var(--briefing-border); }
:is(.dv-badge--in_water, .os-badge--in_water)  { color: var(--inwater);   background: var(--inwater-bg);   border-color: var(--inwater-border); }
:is(.dv-badge--returning, .os-badge--returning) { color: var(--status-returning-fg); background: var(--status-returning-bg); border-color: var(--status-returning-border); }
:is(.dv-badge--completed, .os-badge--completed) { color: var(--status-completed-fg); background: var(--status-completed-bg); border-color: var(--status-completed-border); }
:is(.dv-badge--cancelled, .os-badge--cancelled) { color: var(--cancelled); background: var(--cancelled-bg); border-color: var(--cancelled-border); }
/* Shape + size + leading-dot modifiers. */
:is(.dv-badge--square, .os-badge--square) { border-radius: var(--radius-sm); }
:is(.dv-badge--sm, .os-badge--sm) { font-size: var(--text-2xs); padding: 1px 6px; }
/* Value chip size — sentence-case data values (gear sizes, tag lists), not a
   10px uppercase status label. Pairs with --neutral. */
:is(.dv-badge--lg, .os-badge--lg) {
  font-size: var(--text-sm);
  font-weight: 500;
  padding: 4px 10px;
  gap: 6px;
  text-transform: none;
  letter-spacing: 0;
}
/* Removable badge: inline delete affordance with a 44×44 hit target (WCAG
   AAA touch size) that overhangs the chip via negative margins so the chip
   keeps its visual density. Hosts a Lucide x icon. */
:is(.dv-badge__remove, .os-badge__remove) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -14px -16px -14px -8px;
  border-radius: var(--radius-pill);
  color: var(--muted-2);
}
:is(.dv-badge__remove, .os-badge__remove):hover { color: var(--cancelled); }
:is(.dv-badge-dot, .os-badge-dot) { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
/* Trip Plan stops timeline (.dv-stops) — the reorderable dive rows live in
   their own .dv-stops__rows scope (dives-reorder walks siblings, so the
   Board/Return bookends must sit outside it). That makes the last dive row the
   :last-child of .dv-stops__rows, where timeline.css hides the connector line —
   but here it still needs to reach down to the Return bookend below. Re-show it. */
:is(.dv-stops__rows, .os-stops__rows) :is(.dv-stops__row, .os-stops__row):last-child :is(.dv-stops__line, .os-stops__line) { display: block; }
/* v4 Plan inline-edit units (dive_stops_controller): the display wrapper
   flattens its children (grip · title · actions) into the .dv-stops__card--stop
   flex row via display:contents, then collapses when the inline edit form is
   revealed. */
:is(.dv-stops__display, .os-stops__display) { display: contents; }
:is(.dv-stops__display, .os-stops__display)[hidden] { display: none; }
/* End "Add stop" cap — the card-lane cell (grid col 3) holding the button + its
   hidden inline create form. */
:is(.dv-stops__endwrap, .os-stops__endwrap) { min-width: 0; }
/* Trip head reopen rows (Reopen run / Reopen): the reason field and its
   button share one row, so they share one height — the base 36 on desktop,
   the 48 touch rung on phones (#609 R2). Was a 32/44px --sm field beside a
   36px button. */
:is(.trip-reopen-form, .os-trip-reopen-form) { --control-h: var(--control-h-base); }
:is(.trip-reopen-form, .os-trip-reopen-form) :is(.os-input, .os-btn) { height: var(--control-h); min-height: 0; }
:is(.trip-reopen-form, .os-trip-reopen-form) .os-input { padding-top: 0; padding-bottom: 0; }
@media (max-width: 640px) {
  :is(.trip-reopen-form, .os-trip-reopen-form) { --control-h: var(--control-h-touch); }
}
/* Modal component — native <dialog>.arena-modal (backdrop, centered card,
   header/body/footer). Used by shared/_modal and the invoice record-payment
   dialog. Without this import the dialog renders as an unstyled white box with
   no backdrop (the panel is opacity:0 until [data-state="open"], the card
   chrome and dim backdrop all live here). */
/* Modal Component Styles
 * Built on native <dialog> element.
 * Visual design from ArenaDiveClub, accessibility from Primer.
 */
/* Reset native dialog defaults.
 * IMPORTANT: Do NOT set `display` here — the browser default
 * `dialog:not([open]) { display: none }` must remain in effect
 * so the closed dialog doesn't create an invisible overlay
 * that blocks clicks and drag events on the page content. */
dialog:is(.arena-modal, .os-arena-modal) {
  padding: 0;
  border: none;
  background: transparent;
  max-width: none;
  max-height: none;
  overflow: visible;
  /* A dialog renders in the top layer but still inherits from its DOM parent:
     the refund dialog lives in a right-aligned table cell, so its labels came
     out right-aligned. Reset to the start edge. */
  text-align: start;
}
/* When open (via showModal), use flex to center the panel.
 * The dialog enters the top layer with position:fixed + inset:0
 * from the browser UA styles, so width/height:100% fills the viewport. */
dialog:is(.arena-modal, .os-arena-modal)[open] {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 1rem;
}
/* Backdrop - ArenaDiveClub: bg-slate-900/60 backdrop-blur-sm */
dialog:is(.arena-modal, .os-arena-modal)::backdrop {
  background-color: rgb(15 23 42 / 0.6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity 200ms ease-out;
}
dialog:is(.arena-modal, .os-arena-modal)[data-state="open"]::backdrop {
  opacity: 1;
}
dialog:is(.arena-modal, .os-arena-modal)[data-state="closing"]::backdrop {
  opacity: 0;
  transition: opacity 150ms ease-in;
}
/* Panel - ArenaDiveClub: bg-white rounded-2xl shadow-2xl max-h-[90vh] */
dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel] {
  background-color: white;
  width: 100%;
  border-radius: 1rem;
  box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 90vh;
  /* Entrance animation */
  opacity: 0;
  transform: scale(0.95) translateY(8px);
  transition: opacity 200ms ease-out, transform 200ms ease-out;
}
dialog:is(.arena-modal, .os-arena-modal)[data-state="open"] [data-modal-panel] {
  opacity: 1;
  transform: scale(1) translateY(0);
}
dialog:is(.arena-modal, .os-arena-modal)[data-state="closing"] [data-modal-panel] {
  opacity: 0;
  transform: scale(0.95) translateY(8px);
  transition: opacity 150ms ease-in, transform 150ms ease-in;
}
/* Header - ArenaDiveClub: px-6 py-4 border-b border-slate-100 bg-slate-50 */
dialog:is(.arena-modal, .os-arena-modal) [data-modal-header] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #f1f5f9;
  background-color: #f8fafc;
  flex-shrink: 0;
}
/* Scrollable body */
dialog:is(.arena-modal, .os-arena-modal) [data-modal-body] {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
  color: #1f2937; /* gray-800 */
}
:is(.dark, .os-dark) dialog:is(.arena-modal, .os-arena-modal) [data-modal-body] {
  color: #d1d5db; /* base-300 equivalent */
}
/* Footer - ArenaDiveClub: px-6 py-4 bg-slate-50 border-t border-slate-100 */
dialog:is(.arena-modal, .os-arena-modal) [data-modal-footer] {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  border-top: 1px solid #f1f5f9;
  background-color: #f8fafc;
  flex-shrink: 0;
}
/* Dark mode */
:is(.dark, .os-dark) dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel] {
  background-color: #1e293b;
}
:is(.dark, .os-dark) dialog:is(.arena-modal, .os-arena-modal)::backdrop {
  background-color: rgb(0 0 0 / 0.7);
}
:is(.dark, .os-dark) dialog:is(.arena-modal, .os-arena-modal) [data-modal-header] {
  background-color: #1b2636;
  border-bottom-color: #374151;
}
:is(.dark, .os-dark) dialog:is(.arena-modal, .os-arena-modal) [data-modal-footer] {
  background-color: #1b2636;
  border-top-color: #374151;
}
/* Desktop (>1024px): scale up panel widths — default sizes are too narrow on large screens */
@media (min-width: 1025px) {
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-sm, .os-max-w-sm)  { max-width: 28rem; }   /* keep intentionally small */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-md, .os-max-w-md)  { max-width: 36rem; }   /* 28→36rem */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-lg, .os-max-w-lg)  { max-width: 42rem; }   /* 32→42rem */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-xl, .os-max-w-xl)  { max-width: 52rem; }   /* 36→52rem */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-2xl, .os-max-w-2xl) { max-width: min(80vw, 64rem); } /* 42→64rem, capped */
}
/* Tablet (641px–1024px): moderate size bump + reduced max-height */
@media (min-width: 641px) and (max-width: 1024px) {
  dialog:is(.arena-modal, .os-arena-modal)[open] {
    padding: 1rem;
  }

  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel] {
    max-height: 88vh;
  }

  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-lg, .os-max-w-lg)  { max-width: 36rem; }   /* 32→36rem */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-xl, .os-max-w-xl)  { max-width: 44rem; }   /* 36→44rem */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel]:is(.max-w-2xl, .os-max-w-2xl) { max-width: min(90vw, 52rem); }
}
/* Mobile (≤640px): bottom sheet — slides up from bottom of screen */
@media (max-width: 640px) {
  dialog:is(.arena-modal, .os-arena-modal)[open] {
    padding: 0;
    align-items: flex-end;
  }

  dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel] {
    max-height: 90dvh;
    border-radius: 1rem 1rem 0 0;
    width: 100%;
    /* Override entrance: slide up instead of scale */
    transform: translateY(1.5rem);
  }

  dialog:is(.arena-modal, .os-arena-modal)[data-state="open"] [data-modal-panel] {
    transform: translateY(0);
  }

  dialog:is(.arena-modal, .os-arena-modal)[data-state="closing"] [data-modal-panel] {
    transform: translateY(1.5rem);
  }

  /* Drag-handle indicator */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-header] {
    position: relative;
    padding-top: 1.25rem;
  }

  dialog:is(.arena-modal, .os-arena-modal) [data-modal-header]::before {
    content: '';
    position: absolute;
    top: 0.4rem;
    left: 50%;
    transform: translateX(-50%);
    width: 2.5rem;
    height: 0.25rem;
    background-color: #cbd5e1;
    border-radius: 9999px;
  }

  :is(.dark, .os-dark) dialog:is(.arena-modal, .os-arena-modal) [data-modal-header]::before {
    background-color: #4b5563;
  }

  /* Respect notch / home-bar on iOS */
  dialog:is(.arena-modal, .os-arena-modal) [data-modal-body] {
    padding-bottom: max(1.5rem, env(safe-area-inset-bottom));
  }
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  dialog:is(.arena-modal, .os-arena-modal)::backdrop, dialog:is(.arena-modal, .os-arena-modal) [data-modal-panel] {
    transition: none;
  }
}
/* ─── Payment dialog (native <dialog>, separate from .arena-modal) ───
   Browsers position <dialog> via `margin:auto`. Override on mobile
   so the panel snaps to the bottom of the viewport (bottom sheet).
   Mirrors the .arena-modal mobile pattern but without the JS state
   transitions, since payment-dialog uses native showModal/close. */
@media (max-width: 640px) {
  dialog:is(.payment-dialog, .os-payment-dialog) {
    margin: auto auto 0;
    max-width: 100%;
    width: 100%;
    border-radius: 1rem 1rem 0 0;
  }
}
/* DiveOS component library (ported from design-system-theming / WL).
   .dv-btn family, the unified list header (.dv-page-head/.dv-page-tools/
   .dv-scope-tab/.dv-filter-btn), and the boxed stat-card grid. Token-driven. */
/* ─────────────────────────────────────────────────────────────────────
   Shared component layer — button primitives.

   Consolidates the primary-action button that was previously repeated as an
   identical inline utility string across seven index/header views:

     inline-flex items-center gap-1.5 h-9 px-3.5 text-sm font-medium
     text-white bg-accent rounded-btn hover:bg-accent-strong
     transition-colors no-underline

   (New Trip · Trip · Add diver · Add · Add vessel · New booking).

   PARITY NOTE — these values are matched BYTE-FOR-BYTE to the Tailwind output
   of the inline string above, NOT to WL's `.dv-btn` spec. WL's `.dv-btn` uses
   16px horizontal padding + 13px font; DM's shipped buttons use px-3.5 (14px) +
   text-sm (14px). To guarantee ZERO visual change we keep DM's exact metrics
   under the WL class name. If/when the two are unified, change here once.

   Tailwind → CSS mapping used:
     inline-flex      → display:inline-flex
     items-center     → align-items:center
     gap-1.5          → gap:0.375rem (6px)
     h-9              → height:2.25rem (36px)
     px-3.5           → padding-left/right:0.875rem (14px)
     text-sm          → font-size:0.875rem; line-height:1.25rem
     font-medium      → font-weight:500
     rounded-btn      → border-radius:6px (var(--radius-btn) / borderRadius.btn)
     transition-colors→ transition: color/bg/border 150ms cubic-bezier(.4,0,.2,1)
     no-underline     → text-decoration-line:none

   Token-driven; consumes the semantic aliases from tokens.css. @imported from
   application.css right after components/header_band.css.
   ───────────────────────────────────────────────────────────────────── */
/* ── Base button ──────────────────────────────────────────────────────
   Layout + typography shared by every variant. Color/background come from
   the modifier so the base alone is never used directly. */
.os-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center; /* centre when stretched full-width */
  gap: 0.375rem;
  /* Sized by the CONTROL TRIO, not literals. At the default density these
     resolve to exactly the shipped 36px / 14px / 14px, so nothing moves;
     inside an .os-density--* scope the button follows the surface. Every
     size modifier below re-declares the trio on itself, which pins it
     against any enclosing scope (see tokens/density.css). */
  height: var(--control-h);
  padding-left: var(--control-pad-x);
  padding-right: var(--control-pad-x);
  font-size: var(--control-fs);
  line-height: 1.25rem;
  font-weight: 500;
  border-radius: 6px;
  /* Own the border instead of inheriting the UA's `2px outset` on <button>.
     Variants that want a border set it themselves, each a full `border:
     1px solid`: --secondary, --ghost, --danger, --confirmed. That list is
     enumerated from the source, not remembered — the first draft of this
     comment named a `--outline` variant that has never existed. No rule
     gem-wide sets border-color or border-width alone on .dv-btn, so
     zeroing the shorthand here cannot strand a half-declared border.

     NOTE: this comment deliberately contains no curly braces. An earlier draft
     spelled a CSS rule out inline, and the stray closing brace broke three
     separate block parsers in one session — every one of them stopped reading
     the rule early and reported the wrong declarations. Same hazard class as a
     star followed by a slash inside comment prose, which once closed a comment
     early, destroyed a :root block and killed 21 tokens app-wide.
     Describe CSS in comments; do not spell it.

     This is NOT redundant with a reset. DiveOS gets a zero button border-width
     free from Tailwind Preflight, so this component looked correct there for its
     whole life. arena-ops has no Tailwind, and every one of its 61
     `<button class="dv-btn">` rendered with a black outset border — a defect
     visible on the guest portal's "Save my details" and invisible to the whole
     test suite, because nothing computes style on real DOM.

     Same failure shape as `turbo-frame[hidden]` (v0.22.1): a component that
     silently depends on the consumer's reset is a component that behaves
     differently per consumer. The base must be self-sufficient. */
  border: 0;
  /* Same reasoning as the border, and found the same way — by computing style
     on a real <button> rather than reading the CSS. A bare `.dv-btn` in
     arena-ops rendered `rgb(239, 239, 239)` on black: the UA's ButtonFace
     fill. Preflight sets a transparent background-color on button; arena's
     base.css has no `button` rule at all.

     An older comment here claimed the base is "never used directly because the
     background comes from the modifier". That is not true of real markup —
     five live arena buttons carry `.dv-btn` with no colour variant, including
     one half of a segmented control in front_office/new_reservation.html.erb
     whose other half has `--secondary`, so the two tabs render differently.

     A base that is only correct when a modifier is also present should either
     declare its own neutral ground or not be usable alone. This declares it. */
  background-color: transparent;
  color: inherit;
  text-decoration-line: none;
  cursor: pointer;
  white-space: nowrap;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, box-shadow, transform;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
/* Keyboard focus ring — focus-visible only, so mouse clicks don't ring. */
.os-btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* Pressed feedback — shared across every variant. */
.os-btn:active {
  transform: translateY(1px);
}
.os-btn:disabled, .os-btn[disabled] {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
  pointer-events: none;
}
/* aria-disabled twin — same dimmed look, but the button stays focusable so
   assistive tech can reach it and hear why it's inert (turnaround bulk bars
   disable until a selection exists; the Stimulus guard blocks the submit). */
.os-btn[aria-disabled="true"] {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
}
/* ── Primary (accent fill) ────────────────────────────────────────────
   Replaces: bg-accent text-white hover:bg-accent-strong. */
/* An <a class="dv-btn"> must not inherit link-hover styling (underline +
   link color) from global `a:hover` rules — those out-specify the variant's
   base `color` on hover. Lock decoration off on every interactive state, and
   re-assert each variant's text color on :hover below. */
.os-btn:hover, .os-btn:focus, .os-btn:focus-visible, .os-btn:active { text-decoration-line: none; }
.os-btn--primary {
  color: #fff;
  background-color: var(--accent);
}
.os-btn--primary:hover {
  color: #fff;
  background-color: var(--accent-strong);
}
/* ── Large size ───────────────────────────────────────────────────────
   Taller, heavier weight. For prominent full-width CTAs (e.g. the sidebar
   "New Dive Plan"). Pair with a layout class for width/block behaviour. */
.os-btn--lg {
  --control-h:     var(--control-h-lg);      /* 42px */
  --control-pad-x: var(--control-pad-x-lg);  /* 16px */
  --control-fs:    var(--control-fs-lg);     /* 14px */
  font-weight: 600;
}
/* ── Field-height size ────────────────────────────────────────────────
   46px tall — the canonical form-control height (matches .dv-field /
   .diveos-input on a filter row). Use for submit/clear buttons that sit
   inline with selects + date pickers so every control aligns on one
   baseline. Height-only; weight + 14px font stay the base size.

   Since v1.6.0 this is the PER-BUTTON escape hatch. If a whole form region
   should sit on the field baseline, wrap it in `.os-density--field` once
   instead of adding this modifier to each control. */
.os-btn--field {
  --control-h: var(--control-h-field);
}
/* ── Touch size — 48pt minimum target ─────────────────────────────────
   Practical UI Ch.7 + Fitts's Law: primary / touch-facing actions should be
   at least 48pt tall so they're fast and easy to hit. The base .dv-btn (36px)
   is right for dense DESKTOP admin rows; reach for .dv-btn--touch on the
   PRIMARY CTA of public + mobile flows (booking, waiver, checkout). */
.os-btn--touch {
  --control-h:     var(--control-h-touch);      /* 48px */
  --control-pad-x: var(--control-pad-x-touch);  /* 20px */
  font-weight: 600;
}
/* ── Secondary (surface + accent outline) ─────────────────────────────
   Outline button: surface fill, --interactive border + text (v1.32.0 — was
   hairline + ink; accent at rest is the "clickable" signifier), hover darkens
   to --interactive-hover on an accent-softer wash. WL `.dv-btn--secondary`. Used for "View public" / "Copy" on the
   booking-detail page.

   NOTE: the booking-detail "View public" button previously carried its own
   inline string (text-[13px], rounded-md). It is now unified to the canonical
   `.dv-btn` metrics (14px font, 6px radius). The radius is identical (rounded-md
   and rounded-btn both compute to 6px); only the font shifts 13px → 14px. This
   1px change is accepted in favour of a single shared button size (consistency
   over preserving a one-off). */
.os-btn--secondary {
  background-color: var(--surface);
  border: 1px solid var(--interactive-border);
  color: var(--interactive);
}
.os-btn--secondary:hover {
  color: var(--interactive-hover);
  border-color: var(--interactive-border-hover);
  background-color: var(--accent-softer);
}
/* ── Ghost (chromeless) ───────────────────────────────────────────────
   No fill, no border — an accent-text action that reads as a button but sits
   flat in a tinted container (callout trailing action, wizard "Back"). Hover
   tints with the accent-soft wash. Was referenced (callout, wizard footer)
   before it existed, so those rendered as bare links — now a real variant. */
.os-btn--ghost {
  background-color: transparent;
  border: 1px solid transparent;
  color: var(--accent);
}
.os-btn--ghost:hover {
  color: var(--accent-strong);
  background-color: var(--accent-soft);
}
/* ── View toggle (segmented control) ──────────────────────────────────
   A small inset segmented control for switching a surface between views
   (Bookings: Kanban / Table / Calendar). Options are <a> links, so they reset
   BT's global a:hover underline. Active = raised surface chip + accent text.
   Replaces the per-page utility-soup version (raw text-[12px], hover underline,
   no shared identity). */
.os-view-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
}
.os-view-toggle__opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Density via vertical padding (no declared height — see
     .os-segmented__option). (36 − 24) / 2 = 6px at base density. */
  padding: max(6px, calc((var(--control-h) - 24px) / 2)) 12px;
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  transition: background 120ms ease, color 120ms ease;
}
.os-view-toggle__opt:hover { color: var(--ink); background: var(--surface-alt); text-decoration: none; }
.os-view-toggle__opt--active, .os-view-toggle__opt--active:hover {
  background: var(--surface);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}
/* ── Danger (outlined cancelled) ──────────────────────────────────────
   Transparent fill, cancelled-tinted border + text, hover fills with the
   cancelled-bg wash. WL `.dv-btn--danger`. Used for "Cancel booking".

   NOTE: the inline original used bg-surface (opaque) rather than transparent.
   Over the page's surface background these render identically; transparent is
   the WL-canonical token treatment and is adopted here. */
.os-btn--danger {
  background-color: transparent;
  border: 1px solid var(--cancelled-border);
  color: var(--cancelled);
}
.os-btn--danger:hover {
  color: var(--cancelled);
  background-color: var(--cancelled-bg);
}
/* ── Icon-only (square) ───────────────────────────────────────────────
   Square button, no horizontal padding, centred glyph. WL `.dv-btn--icon`.
   Used for the Ledger date-navigation arrows.

   NOTE: the Ledger arrows were previously `.ledger-nav-arrow` — a 32px square
   with a hairline border and muted-ink glyph. The shared `.dv-btn--icon` is a
   36px square (matching the canonical `.dv-btn` height) with a muted glyph.
   To preserve the Ledger's 32px sizing AND its hairline outline, the arrows
   use `.dv-btn dv-btn--secondary dv-btn--icon dv-btn--sm` (secondary supplies
   the surface + hairline + ink, sm drops it to 32px). This keeps the existing
   look while consuming only shared classes. */
.os-btn--icon {
  /* Square: width tracks whatever height is in force, so an icon button is
     36px at base density and 48px in an .os-density--touch scope without a
     second modifier. Previously a 2.25rem literal that could not follow. */
  width: var(--control-h);
  padding-left: 0;
  padding-right: 0;
  justify-content: center;
  color: var(--interactive);
}
.os-btn--icon:hover {
  color: var(--interactive-hover);
  background-color: var(--accent-soft);
}
/* ── Small size modifier (h-8) ────────────────────────────────────────
   Denser button for inline/contextual actions. WL `.dv-btn--sm`:
   height 32px, padding 0 12px, font 12px. Used for the booking-detail
   "Assign" (primary sm) and "Copy" (secondary sm) buttons, and — combined
   with `--icon` — the Ledger nav arrows (32px square). */
.os-btn--sm {
  --control-h:     var(--control-h-sm);      /* 32px / h-8 */
  --control-pad-x: var(--control-pad-x-sm);  /* 12px / px-3 */
  --control-fs:    var(--control-fs-sm);     /* 12px */
}
/* --sm is declared AFTER --icon and has equal specificity, so its padding
   would otherwise win and un-square the icon button. Re-zero it here. Width
   needs no repeat: --icon reads var(--control-h), which --sm has re-pointed
   on this same element. */
.os-btn--sm.os-btn--icon {
  padding-left: 0;
  padding-right: 0;
}
/* Mini button — for an inline action that sits BESIDE a status badge and must
   align to its height, not the 32px --sm (e.g. waiver roster "Send link" next
   to the "Not signed" pill). 22px tall ≈ the .dv-badge--square height. */
.os-btn--xs {
  --control-h:     var(--control-h-xs);      /* 22px */
  --control-pad-x: var(--control-pad-x-xs);  /* 8px */
  --control-fs:    var(--control-fs-xs);     /* 10px */
  gap: 4px;
}
.os-btn--xs.os-btn--icon { padding-left: 0; padding-right: 0; }
/* ── Confirmed (green secondary) ──────────────────────────────────────
   Exactly the --secondary button (surface fill, 1px outline, base type), only
   recoloured to the confirmed hue: green-700 border + text. Hover fills with
   the confirmed-bg wash. Used for positive transactions — check a diver in,
   mark a diver back aboard (Trip Run v4). */
.os-btn--confirmed {
  background-color: var(--surface);
  border: 1px solid var(--confirmed);
  color: var(--confirmed);
}
.os-btn--confirmed:hover {
  color: var(--confirmed);
  background-color: var(--confirmed-bg);
}
/* Canonical text-link treatment (DS link).
   Single source for the accent text-link / "View all" styling that was
   previously duplicated as utility-class soup across kanban / roster / show
   surfaces. Token-clean: accent family only, no raw palette, no dark:. */
.os-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1;
  color: var(--accent);
  text-decoration: none;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color 0.15s ease;
}
.os-link:hover {
  color: var(--accent-strong);
}
.os-link :is(.lucide, .os-lucide), .os-link svg {
  flex-shrink: 0;
}
/* Count suffix — the "View all 12" number stays in the accent flow. */
.os-link__count {
  font-variant-numeric: tabular-nums;
}
/* header_band: component from the gem, DiveOS integration glue after it. */
/* ─────────────────────────────────────────────────────────────────────
   Shared component layer — header band + toolbar primitives.

   Consolidates two patterns that were previously repeated as inline class
   strings / duplicated page-scoped CSS across the app:

   1. `.dv-page-band` — the full-bleed white header band that sits at the top
      of (and between sections of) every index/detail page. Previously every
      band was written inline as
        `bg-surface border-b border-hairline dv-full-bleed …`
      on the wrapper div. This sheet folds the three shared invariants
      (surface background, bottom hairline, full-bleed horizontal breakout)
      into one named class.

      IMPORTANT — parity note: the *vertical* padding of each band is NOT
      uniform across pages (head bands use `-mt-10 pt-8 pb-6`, stat strips use
      `py-[22px]` on Today but `py-[18px]` on Dives, toolbars use `py-2` or
      `py-3`, and the bookings tab nav supplies its own padding via
      `.page-tabs`). To guarantee ZERO visual change, `.dv-page-band` owns ONLY
      the shared invariants; callers KEEP their existing per-band padding /
      margin Tailwind utilities. No `--head` / `--stats` padding modifiers are
      defined because that would force a single padding value and shift pixels
      on pages that use a different one.

   2. `.dv-toolbar`, `.dv-divider`, `.chip` (+ `.is-on` / `.count`) — toolbar
      filter primitives that were duplicated byte-for-byte in
      `account/divers.css` and `account/team.css`. Promoted here so both pages
      (and any future page) consume one canonical definition.

   Token-driven; consumes the semantic aliases from tokens.css. Loaded after
   patterns.css (see application.css).

   Full-bleed is the shell contract: the consuming shell defines --bleed-w /
   --bleed-mx / --bleed-pad on its content column (and makes the pane a query
   container). Each is read WITH a fallback, so a consumer that defines none
   degrades to a plain, non-bleeding band instead of a broken layout.
   ───────────────────────────────────────────────────────────────────── */
/* ── Page band (full-bleed white header band) ─────────────────────────
   Shared invariants only. Callers add their own vertical padding/margin
   utilities (e.g. `-mt-10 pt-8 pb-6`, `py-[18px]`, `py-[22px]`, `py-2`,
   `py-3`) to preserve each band's exact rhythm.

   The horizontal breakout is baked in: it extends the band to the content-pane
   edges via --bleed-*, then re-insets its content to the centered column. So
   callers add nothing alongside `.dv-page-band`. */
.os-page-band {
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  width: var(--bleed-w, auto);                 /* full-bleed background to the pane edges */
  margin-inline: var(--bleed-mx, 0);
  padding-inline: var(--bleed-pad, 0);      /* inner content aligns to the tier column */
}
/* ── Page-band tab nav (band 2) ───────────────────────────────────────
   The second .dv-page-band on a detail page: a full-bleed sticky tab row.
   Promoted (unscoped) from account/bookings.css so every detail header
   (booking, dive trip, …) shares ONE tab component. `.dv-tabnav` pins the
   band under band 1; `.page-tabs`/`.page-tab`/`.page-tab-count` style the
   underline tabs + badge counts. */
.os-tabnav { position: sticky; top: 0; z-index: 20; }
:is(.page-tabs, .os-page-tabs) {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
  /* Narrow screens: scroll the tab row horizontally rather than wrap/clip
     ("Run →" onto two lines, "Return" off the edge). No-op when they fit. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
:is(.page-tabs, .os-page-tabs)::-webkit-scrollbar { display: none; }
:is(.page-tab, .os-page-tab) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  white-space: nowrap;
  padding: 12px 12px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--interactive);
  border: none;
  background: none;
  cursor: pointer;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--t-fast, 0.15s) ease;
}
:is(.page-tab, .os-page-tab):hover { color: var(--interactive-hover); }
/* Keyboard focus ring — tabs are interactive (<a>/<button>); without this,
   keyboard users get no visible focus. `--shadow-focus` is ours (tokens.css);
   `--radius-xs` is NOT a token os-ds owns, so it carries a fallback — otherwise
   the ring renders square in any consumer that doesn't happen to define it. */
:is(.page-tab, .os-page-tab):focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--radius-xs, 4px);
}
:is(.page-tab, .os-page-tab).is-active, :is(.page-tab, .os-page-tab)[aria-selected="true"] {
  color: var(--accent) !important;
  border-bottom-color: var(--accent);
  font-weight: 600;
}
:is(.page-tab-count, .os-page-tab-count) {
  font-size: var(--text-2xs);
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  color: var(--muted-2);
}
:is(.page-tab, .os-page-tab).is-active :is(.page-tab-count, .os-page-tab-count), :is(.page-tab, .os-page-tab)[aria-selected="true"] :is(.page-tab-count, .os-page-tab-count) {
  color: var(--accent);
  border-color: var(--accent-border);
}
/* A thin separator between in-page tabs and a nav-away tab (e.g. Run opens
   the run flow on its own surface). */
:is(.page-tab-div, .os-page-tab-div) {
  align-self: center;
  width: 1px;
  height: 18px;
  margin: 0 6px;
  background: var(--hairline);
  flex-shrink: 0;
}
/* ── Toolbar (filter chips + search) ──────────────────────────────────
   Promoted from account/divers.css + account/team.css (identical copies). */
/* ── Page-band typography — canonical h1, h2, sub-copy ───────────────
   Every page header h1 inside .dv-page-band inherits the WL-exact style
   automatically. Views just write <h1>Title</h1> — no Tailwind utilities
   needed on the element. Same for the muted sub-copy <p>. */
.os-page-band h1 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.025em;
  color: var(--ink);
}
.os-page-band h1 + p, .os-page-band :is(.page-sub-copy, .os-page-sub-copy) {
  font-size: var(--text-sm);
  color: var(--muted);
  margin-top: 4px;
}
.os-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
/* Vertical separator between chip groups inside a toolbar. */
.os-toolbar .os-divider {
  width: 1px;
  height: 22px;
  background: var(--hairline);
  margin: 0 4px;
  flex-shrink: 0;
}
/* ── Chip (filter pill) ───────────────────────────────────────────────
   Promoted from account/divers.css + account/team.css (identical copies). */
:is(.chip, .os-chip) {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background 150ms ease-out, border-color 150ms ease-out;
}
:is(.chip, .os-chip):hover { background: var(--canvas); }
:is(.chip, .os-chip).is-on {
  background: var(--accent-soft);
  border-color: var(--accent-border);
  color: var(--accent);
}
:is(.chip, .os-chip) :is(.count, .os-count) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted);
  margin-left: 2px;
}
:is(.chip, .os-chip).is-on :is(.count, .os-count) { color: var(--accent); }
/* ─────────────────────────────────────────────────────────────────────
   Shared index-page primitives — page header, search box, table wrap.

   Previously duplicated byte-for-byte in account/divers.css and
   account/team.css (and consumed by account/gear.css + account/fleet.css).
   Promoted here so the canonical definition lives in one place and the next
   `thead th`-style correction only has to happen once. Loaded before all
   account/* page sheets, so page-scoped variants (e.g. team grouped-row
   rules) still cascade on top. ZERO visual change vs the duplicated copies.
   ───────────────────────────────────────────────────────────────────── */
/* ── Search box ───────────────────────────────────────────────────── */
:is(.search-wrap, .os-search-wrap) {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 32px;
}
:is(.search-wrap, .os-search-wrap) svg, :is(.search-wrap, .os-search-wrap) [data-lucide] {
  position: absolute;
  left: 10px;
  width: 14px;
  height: 14px;
  color: var(--muted-2);
  pointer-events: none;
}
:is(.search-wrap, .os-search-wrap) input {
  width: 100%;
  height: 32px;
  padding: 0 10px 0 30px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  color: var(--ink);
}
:is(.search-wrap, .os-search-wrap) input::-moz-placeholder { color: var(--muted-2); }
:is(.search-wrap, .os-search-wrap) input::placeholder { color: var(--muted-2); }
:is(.search-wrap, .os-search-wrap) input:focus {
  outline: none;
  border-color: var(--hairline-strong);
}
/* ── Table wrap ───────────────────────────────────────────────────── */
.os-table-wrap {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  /* BL-1a — clip vertically (keeps the rounded-corner mask), scroll horizontally
     at every breakpoint so no table clips/squeezes on narrow viewports. The
     border-radius still clips because overflow is non-visible on both axes. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  /* v1.37.0: the containing block for what it scrolls. An absolutely positioned
     descendant (a header's sr-only label, an .os-field-check__input) otherwise
     anchors to the page, escapes this clip and scrolls the whole page sideways
     on a phone (dive-os #609). */
  position: relative;
}
/* 14px body-cell floor. Set on the WRAPPER so it's INHERITED by cells — any cell
   that declares its own size (.dv-table__sub → 12px, Tailwind text-xs, thead th)
   overrides inheritance regardless of specificity, but a bare/super-scaffolded
   <td> with no sizing class inherits 14px instead of leaking to the 16px root.
   Complements the .dv-table__* classes (components/table.css); this catches the
   tables that don't use them (BT super-scaffold, box.table, hand-rolled cells). */
.os-table-wrap, :is(.box-table, .os-box-table) { font-size: var(--text-sm); }
.os-table-wrap table {
  min-width: 100%;
  border-collapse: collapse;
}
.os-table-wrap thead tr {
  background: var(--canvas);
  border-bottom: 1px solid var(--hairline);
}
.os-table-wrap thead th {
  /* Header cells own vertical rhythm just like body `td` below (14px ≈ one step
     tighter than the 16px body row, matching the opt-in `.os-table__th`). Without
     it the header row collapses to its ~10px text line and reads far shorter than
     every body row. */
  padding-top: 14px;
  padding-bottom: 14px;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-600);  /* WL table-header color (#4B5563); was --muted (gray-500), one step too light */
}
.os-table-wrap tbody tr { border-bottom: 1px solid var(--hairline-2); }
.os-table-wrap tbody tr:last-child { border-bottom: none; }
.os-table-wrap tbody tr:hover { background: var(--sky-50); }
/* Row/cell links (often dv_link_to names) shouldn't underline on hover inside
   a table — the row hover tint is the affordance; underline reads as noise. */
.os-table-wrap td a:hover, :is(.box-table, .os-box-table) td a:hover { text-decoration: none; }
/* Default cell rhythm — list-table rows are 1rem (16px = --space-4) top+bottom.
   This OVERRIDES per-cell py-* utilities (specificity 0,1,1 > a plain .py-3),
   so the row height is uniform across every list table from the component, not
   from scattered per-cell classes. Dense embedded sub-tables opt out with
   .dv-table--compact (8px). */
.os-table-wrap td { padding-top: var(--space-4); padding-bottom: var(--space-4); }
.os-table-wrap.os-table--compact td, .os-table--compact .os-table-wrap td { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.os-table-wrap td:first-child, .os-table-wrap th:first-child { padding-left: 16px; }
.os-table-wrap td:last-child, .os-table-wrap th:last-child { padding-right: 16px; }
/* NOTE (shell-agnostic): a consuming app whose table framework wraps index
   tables and leaks column insets onto .dv-table-wrap (e.g. Bullet Train's
   `.bulk-actions` "identity column" padding) should reset those in its OWN
   stylesheet — that's a product-framework concern, not part of the shared
   component. The gem stays free of framework-specific ancestor selectors. */
/* Reorderable tables (drag-handle first column). The leading handle cell is a
   narrow grip, not real content — the first-child 16px inset would push the
   whole table in past the canonical 12px (px-3) gutter and, on the header,
   misalign the labels against their data columns. Pin both the handle <td> and
   its matching leading <th> to 12px so the table's left content lines up at the
   canonical gutter, header above row. */
.os-table-wrap:has(tbody [data-sortable-target="handle"]) th:first-child, .os-table-wrap:has(tbody [data-sortable-target="handle"]) td:first-child { padding-left: var(--space-3); }
/* ── Box table ────────────────────────────────────────────────────────
   The shared themes/light/_box partial already supplies a bordered
   surface card. So `box.table` tables get the canonical .dv-table-wrap
   LOOK (canvas header band, uppercase 10px th, 12px td rhythm, hairline
   rows, hover surface-alt) WITHOUT a second outer border/radius. Mirrors
   the thead/td/hover rules above; intentionally omits the .dv-table-wrap
   outer border + radius (the box owns that chrome). */
/* BL-1a — box.table wrappers scroll horizontally too (the responsive_tables.css
   layer that used to supply this was deleted as dead card-stack CSS). */
:is(.box-table, .os-box-table) { overflow-x: auto; -webkit-overflow-scrolling: touch; }
:is(.box-table, .os-box-table) table { min-width: 100%; border-collapse: collapse; }
:is(.box-table, .os-box-table) thead tr {
  background: var(--canvas);
  border-bottom: 1px solid var(--hairline);
}
:is(.box-table, .os-box-table) thead th {
  /* Header rhythm — mirrors `.os-table-wrap thead th`; see the note there. */
  padding-top: 14px;
  padding-bottom: 14px;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-600);
}
:is(.box-table, .os-box-table) tbody tr { border-bottom: 1px solid var(--hairline-2); }
:is(.box-table, .os-box-table) tbody tr:last-child { border-bottom: none; }
:is(.box-table, .os-box-table) tbody tr:hover { background: var(--sky-50); }
:is(.box-table, .os-box-table) td { padding-top: var(--space-4); padding-bottom: var(--space-4); }
:is(.box-table, .os-box-table) td:first-child, :is(.box-table, .os-box-table) th:first-child { padding-left: 16px; }
:is(.box-table, .os-box-table) td:last-child, :is(.box-table, .os-box-table) th:last-child { padding-right: 16px; }
/* ════════════════════════════════════════════════════════════════════════
   Unified list/index page header (WL handoff — "header-applied-boards").
   ONE general header: row 1 .dv-page-head (title + actions) · row 2
   .dv-page-tools (scope tabs + facet chips + trailing). Replaces the old
   multi-band .dv-page-band stack. Reuses .dv-btn*, .search-wrap, .chip.
   Scope tabs = mutually-exclusive segmentation (one .is-on); chips = facets.
   ════════════════════════════════════════════════════════════════════════ */
/* Row 1 — title bar. White, full-bleed to the pane edges (same calc as
   .dv-full-bleed / .dv-page-band — keep in sync), bleeding up through
   the pane's top padding (via --shell-pad-top) so the white starts at the pane top. */
.os-page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  margin-top: calc(-1 * var(--shell-pad-top, 40px));
  width: var(--bleed-w, auto);
  margin-inline: var(--bleed-mx, 0);
  padding: 32px var(--bleed-pad, 0) 18px;
}
/* Mobile (<1023px): compact single-row header + auto-hiding page tools.
   SHELL-AGNOSTIC nav clearance: a shell that renders a FIXED mobile nav toggle
   (a hamburger overlapping the top-left) sets `--dv-nav-gutter` (horizontal
   inset, e.g. 64px) and `--dv-nav-gutter-top` (vertical clearance for a
   breadcrumb sitting under the toggle, e.g. 72px). Both default to 0, so a shell
   with no fixed toggle gets no phantom gutter — the gem assumes no shell. */
@media (max-width: 1023px) {
  /* List header (row 1): content clears the shell nav toggle via the gutter. */
  .os-page-head { padding-top: 16px; padding-left: var(--dv-nav-gutter, 0); }

  /* Detail headers carry a breadcrumb as their first line — extra top clearance
     so breadcrumb + title stack under the toggle (0 when no shell toggle). */
  .os-page-band { padding-top: var(--dv-nav-gutter-top, 0); }
  .os-page-band ~ .os-page-band { padding-top: var(--space-2, 8px); }
  nav.os-page-band { padding-top: var(--space-3, 12px); padding-left: var(--dv-nav-gutter, 0); }

  /* Page tools (row 2): at the page top the row sits below the header, clear of
     the toggle. The `page-tools` controller adds `--pinned` (applies the nav
     gutter) only while STUCK at the top, and `--hidden` to slide it out of view
     on scroll-down. Transform-based so hiding never reflows the page. */
  .os-page-tools {
    transition: transform .24s var(--ease-out-quart, ease), padding-left .12s ease;
  }
  .os-page-tools.os-page-tools--hidden { transform: translateY(-110%); }
  .os-page-tools.os-page-tools--pinned { padding-left: var(--dv-nav-gutter, 0); }
}
.os-page-head h1, h1.os-page-head__title {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 0;
}
.os-page-head__sub { font-size: var(--text-sm); color: var(--muted); margin-top: 4px; }
/* ── Head lead + title row ────────────────────────────────────────────
   The band is title-cluster (left) vs actions (right). `__lead` is that left
   cluster; `__titlerow` puts the h1 and its IDENTITY CHIPS (VIP, returning,
   lifecycle status) on ONE line.

   Both were previously undefined, so a consumer that used them got the browser
   default: the block-level h1 took the full width and pushed every chip onto
   its own line under the name. Additive — no existing markup in the DiveOS
   consumer references either class, so this changes nothing there. */
.os-page-head__lead {
  flex: 1 1 auto;
  min-width: 0;                        /* let a long name truncate, not overflow */
}
.os-page-head__titlerow {
  display: flex;
  align-items: center;                 /* chips optically centre on the title */
  flex-wrap: wrap;                     /* many chips wrap as a group, not per-chip */
  gap: 10px;
  min-width: 0;
}
.os-page-head__actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* Optional breadcrumb inside the head band (Settings/catalogue pages). It sits
   at the top of the title block, above the <h1>. The breadcrumb component is
   margin-free, so the band owns this gap — keeps the breadcrumb IN the header
   band (no stray wrapper div per page). */
.os-page-head .os-breadcrumb { margin-bottom: 10px; }
/* Below the two-column comfort width the actions (search · view toggle · CTA)
   can't fit beside the title and — being flex-shrink:0 — bleed off the right
   edge. Wrap them under the title as a full-width row: the search grows to fill,
   the toggle + CTA wrap beneath it. Desktop keeps the title/actions on one line.

   CONTAINER query (not viewport): the header lives in the content pane, so
   it must react to the PANE width (viewport minus the 240px sidebar), not the
   window. A viewport query left a dead band — e.g. at a 1024px window the pane
   is only ~784px, narrow enough to crush the sub/description and bleed the
   actions off the edge, yet a `max-width: 880px` window query never fired. The
   container query fires at pane ≤880 in every sidebar state (shown/collapsed). */
@container (max-width: 880px) {
  .os-page-head { flex-wrap: wrap; row-gap: 16px; }
  .os-page-head > :first-child { flex: 1 1 100%; }
  .os-page-head__actions {
    width: 100%;
    flex-wrap: wrap;
    justify-content: flex-start;
  }
  /* A search input grows to fill the row (it already carries flex-grow); a lone
     CTA button stays its natural width — never stretch a button full-bleed. */
  .os-page-head__actions > :is(.relative, .os-relative):first-child, .os-page-head__actions > form:first-child { flex: 1 1 240px; max-width: none; }
  .os-page-head__actions > :is(.relative, .os-relative):first-child :is(.max-w-sm, .os-max-w-sm), .os-page-head__actions :is(.search-wrap, .os-search-wrap) { max-width: none; }
}
/* v1.38.0 (dive-os #621): on tablets a head whose actions are only buttons and
   links (no search or other field) keeps them on the title row. The title block
   shrinks and its subtitle wraps; the actions drop below only when even a 15rem
   title would not fit beside them. A field still takes its own full row (above).
   Phones (<=640) keep their icon-only band, so this stops at 641px. */
@media (min-width: 641px) {
  @container (max-width: 880px) {
    .os-page-head:not(:has(.os-page-head__actions :is(input:not([type="hidden"], [type="submit"]), select, textarea, .os-hsearch))) {
      flex-wrap: wrap;
      align-items: flex-start;
    }
    .os-page-head:not(:has(.os-page-head__actions :is(input:not([type="hidden"], [type="submit"]), select, textarea, .os-hsearch))) > :first-child {
      flex: 1 1 15rem;
      min-width: 0;
    }
    .os-page-head:not(:has(.os-page-head__actions :is(input:not([type="hidden"], [type="submit"]), select, textarea, .os-hsearch))) > .os-page-head__actions {
      width: auto;
      flex: 0 1 auto;
      justify-content: flex-end;
    }
  }
}
/* Collapsible search wrapper. Desktop/tablet: the field shows inline (grows to
   its max-w-sm) and the toggle button is hidden; the phone rules below flip it. */
.os-hsearch { display: flex; align-items: center; flex-grow: 1; min-width: 0; }
.os-hsearch__field { flex-grow: 1; min-width: 0; }
/* Clear the leading search icon. A product input's padding shorthand can override
   a utility `pl-8`, so pad the field input here (higher specificity). */
.os-hsearch__field input { padding-left: 2rem; }
.os-hsearch__toggle { display: none; }
/* PHONES ONLY (≤640): compact single row — title + icon actions. The subtitle
   is dropped and each action button collapses to its icon (the bare-text label
   is zeroed via font-size:0; the Lucide SVG keeps its explicit width/height, so
   the glyph survives). Scoped to phones on purpose: the hamburger appears at
   ≤1023, but the TABLET range (641–1023) has room for the full header, so it
   keeps its subtitle + full-text actions (via the container-query stack above).
   Wide controls (search, view toggle) still wrap. */
@media (max-width: 640px) {
  /* Top-align so the title's FIRST line rides the hamburger band (below) and a
     wrapped 2nd line flows beneath it — instead of the whole title cluster being
     centred as a unit, which drops the title ~7px below the fixed toggle. */
  .os-page-head { flex-wrap: wrap; align-items: flex-start; row-gap: 8px; -moz-column-gap: 8px; column-gap: 8px; }
  .os-page-head > :first-child { flex: 1 1 auto; min-width: 0; }
  /* The shell hamburger is a 44px touch target pinned at top:12 (optical centre
     y=34). Drop the title line and the icon actions into a matching 44px band so
     both sit level with the toggle, not with the taller header box. */
  .os-page-head h1, h1.os-page-head__title { min-height: 44px; display: flex; align-items: center; }
  .os-page-head__sub { display: none; }
  .os-page-head__actions {
    width: auto;
    flex: 0 0 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    min-width: 0;
    min-height: 44px;                  /* ride the hamburger band, level with title */
    align-items: center;
  }
  /* Collapsible search: flatten any wrapper (search form / filter div) around
     the .dv-hsearch so it participates in the actions flex directly, then show a
     40px search-icon button and hide the field until the search-collapse
     controller opens it. When open, the actions take a full row so the field
     can breathe. Generic `:has(.dv-hsearch)` — not tied to any one controller. */
  .os-page-head__actions form:has(.os-hsearch), .os-page-head__actions > div:has(.os-hsearch) { display: contents; }
  .os-hsearch { flex: 0 0 auto; }
  .os-hsearch__toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; flex-shrink: 0;
    border: 1px solid var(--hairline); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--muted); cursor: pointer;
  }
  .os-hsearch__field { display: none; }
  .os-hsearch.is-open { flex: 1 1 100%; }
  .os-hsearch.is-open .os-hsearch__toggle { display: none; }
  .os-hsearch.is-open .os-hsearch__field { display: block; }
  .os-page-head__actions:has(.os-hsearch.is-open) { flex: 1 1 100%; justify-content: flex-start; }
  /* Fallback for pages whose header search isn't the collapsible .dv-hsearch yet
     (e.g. Leads): give the search form its own full-width row so it doesn't
     overflow — the pre-collapse behaviour. */
  /* v1.41.0: only a VISIBLE field takes the row (see "Phone page head" below).
     A button_to action is a form carrying a hidden authenticity token, and the
     date pager hides a transparent picker input under its chip; neither is a
     field, so neither drops the actions under the title. A product's own
     compact control with an input inside (a date pill) opts out the same way
     with `.os-head-inline` on its wrapper. */
  .os-page-head__actions:has(input:not([type="hidden"], [type="submit"], [type="button"], [type="reset"], [type="image"], .os-pager input, .os-head-inline input)):not(:has(.os-hsearch)) { flex: 1 1 100%; justify-content: flex-start; }
  .os-page-head__actions > form:has(input:not([type="hidden"], [type="submit"], [type="button"], [type="reset"], [type="image"], .os-pager input, .os-head-inline input)) { flex: 1 1 100%; min-width: 0; }
  .os-page-head__actions input { min-width: 0; }
  .os-page-head__actions .os-btn {
    gap: 0;
    width: 40px;
    min-width: 40px;
    padding-left: 0;
    padding-right: 0;
    justify-content: center;
    font-size: 0;
  }
  .os-page-head__actions .os-btn :is(.lucide, .os-lucide), .os-page-head__actions .os-btn > svg { width: 18px; height: 18px; font-size: initial; }
  /* The date stepper (< >) matches the 40px action-button height so the whole
     action cluster reads as one row (it shipped at 34/36px, shorter than the
     buttons). */
  .os-page-head__actions .os-pager { height: 40px; }
  .os-page-head__actions .os-pager :is(.os-pager__step, .os-pager__date) { height: 40px; }
  /* The view toggle collapses to icon-only segments (each option carries a
     Lucide icon). */
  .os-page-head__actions :is(.segmented__option, .os-segmented__option) span { display: none; }
  .os-page-head__actions :is(.segmented__option, .os-segmented__option) { padding-left: 11px; padding-right: 11px; }
}
/* Row 2 — scope / tools bar. White, full-bleed (matches row 1).
   Sticky: the scope/tools row pins to the top on scroll (the title row above
   scrolls away under it), so the filters stay reachable down a long list. */
.os-page-tools {
  display: flex;
  align-items: center;
  /* Wrap as a unit below ~1440px: the anchor-stat + scope-tabs + trailing note
     can exceed the pane width (Ledger has 6 money tabs). Without this the row
     stays one line and the scope-tabs wrap internally, leaving a stray tab on
     line 2 while the note floats top-right. row-gap keeps wrapped rows legible. */
  flex-wrap: wrap;
  row-gap: 10px;
  gap: 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  width: var(--bleed-w, auto);
  margin-inline: var(--bleed-mx, 0);
  padding: 12px var(--bleed-pad, 0);
  position: sticky;
  top: 0;
  z-index: 20;
}
/* Body gap — consistent 2rem between a page header and the content below,
   ACROSS ALL ARCHETYPES (#75). The list header is two full-bleed rows:
   row-1 `.dv-page-head`, optional row-2 `.dv-page-tools`; content follows
   whichever is last, the two header rows stay flush. Show/edit/form pages use
   `.page-header` (form/settings header) or a bare `.dv-page-band` (e.g.
   booking show) — those got no top gap before, so the first body element
   stacked flush against the header. The selectors below give every archetype
   the same 2rem gap. padding-top: 0 neutralises `pt-*` on content wrappers so
   the gap is exactly 2rem everywhere.

   Note: `.hero-show__band` (entity show pages) owns its own margin-bottom:2rem
   in patterns.css, so it is intentionally NOT matched here.

   We key the show/edit/form gap on `.page-header` (the form/settings header,
   which is `.dv-page-band.page-header`), NOT on a bare `.dv-page-band`. A bare
   band (e.g. booking show) is followed by a control-row WRAPPER — the
   `tab-panel` controller div that holds the band-2 tab nav — and that wrapper
   must stay flush; its internal nav→panel spacing lives in bookings.css. So a
   bare-`.dv-page-band` selector wrongly pushed the tab nav down 2rem (#75
   regression) and is deliberately absent.

   The `.dv-page-head` row excludes `form:has(> .dv-page-tools)` because a list's
   filter bar is often wrapped in a search `<form>` (e.g. Team) — without the
   exclusion the form (and the sticky tools bar inside it) gets a stray 2rem gap
   instead of sitting flush under the title. */
/* Underline tabs inside a toolbar band — a `.page-tabs` group sits alongside
   vertically-centered controls (search / filters / view toggle) in the same
   `.dv-page-tools` row, yet its active-tab underline must land flush on the
   band's BOTTOM hairline, not float at the centered mid-line. Stretch the group
   to the full band height (negative block margins cancel the band's 12px
   vertical padding) and drop the tabs' own vertical padding so the 2px
   border-bottom sits on the band edge. This promotes a pattern products were
   re-hacking locally (e.g. HotelOS `.fo-cstrip .fo-tabs`); a standalone
   `.dv-tabnav` band needs none of it (no centered siblings). */
.os-page-tools > :is(.page-tabs, .os-page-tabs) {
  align-self: stretch;
  flex-wrap: nowrap;
  flex-shrink: 0;
  margin-block: -12px;
}
.os-page-tools > :is(.page-tabs, .os-page-tabs) > :is(.page-tab, .os-page-tab) {
  align-items: center;
  padding-block: 0;
  margin-bottom: 0;
}
.os-page-tools + :not(.os-page-tools):not(:has(.os-page-tools)), .os-page-head + :not(.os-page-tools):not(.os-page-head):not(:has(.os-page-tools)), :is(.page-header, .os-page-header) + :not(.os-page-tools):not(.os-page-head):not(.os-page-band):not(:has(.os-page-tools)) { margin-top: 2rem; padding-top: 0; }
/* `<turbo-frame>` is an unknown element, so it defaults to `display: inline` —
   and vertical margin does nothing on an inline box. Any page whose first body
   element is a frame (a drawer, a lazy panel, a destructive confirm) therefore
   MATCHED the body-gap rule above and still rendered flush against the header.
   It looked like the gap rule was broken; the gap was landing on a box that
   cannot take it. Seen in both consuming apps.

   The `[hidden]` guard below is NOT optional. `[hidden] { display: none }` lives
   in the USER-AGENT stylesheet, and cascade origin is resolved before
   specificity — so this author-origin type selector beats it, and
   `<turbo-frame hidden>` RENDERS. That is the standard turbo-rails idiom for a
   lazy modal/drawer shell, so the rule above silently arms a landmine in every
   consumer without it.

   It also fails ASYMMETRICALLY, which is worse than failing outright: a Tailwind
   consumer gets Preflight's own `[hidden] { display: none }` at (0,1,0), which
   re-wins and masks the bug, while a consumer without Preflight shows it. Same
   markup, two behaviours, gem as the cause. Verified live in the HotelOS
   consumer: a hidden <turbo-frame> computed `display: block` and rendered, while
   a hidden <div> and <span> correctly computed `none`.

   Restore the guard rather than scoping the rule: it is already shipped and
   ~20 frames across both apps now depend on being block, so narrowing it would
   be a behaviour change wearing a bugfix's clothes. */
turbo-frame {
  display: block;
}
turbo-frame[hidden] {
  display: none;
}
.os-spacer { flex: 1 1 auto; }
.os-vrule { width: 1px; height: 22px; background: var(--hairline); flex-shrink: 0; }
/* Tools select — token-clean native <select> for .dv-page-tools filter rows.
   Native control kept (submit/keyboard); appearance stripped and a Lucide
   chevron overlaid. Matches .search-wrap height/typography. */
.os-tools-select { position: relative; display: inline-flex; align-items: center; }
.os-tools-select select {
  -moz-appearance: none;
       appearance: none;
  -webkit-appearance: none;
  height: 32px;
  min-width: 10rem;
  padding: 0 30px 0 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  color: var(--ink);
  cursor: pointer;
}
.os-tools-select select:hover { border-color: var(--hairline-strong); }
.os-tools-select select:focus { outline: none; border-color: var(--hairline-strong); }
.os-tools-select__chev {
  position: absolute;
  right: 10px;
  color: var(--muted-2);
  pointer-events: none;
}
.os-page-tools__note {
  font-size: var(--text-xs);
  color: var(--muted-2);
  font-family: var(--font-mono, ui-monospace, monospace);
  white-space: nowrap;
}
.os-toolbtn {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: 8px;
  color: var(--muted); cursor: pointer; text-decoration: none;
}
.os-toolbtn:hover { background: var(--canvas); color: var(--ink); }
/* Scope tabs — count/amount-forward, mutually-exclusive (one .is-on) */
.os-scope-tabs { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
/* Ledger tools row (the only one with an anchor-stat + trailing note) restacks
   below ~1400px instead of leaving orphan rows: the scope-tabs take their own
   full-width line, and the "N transactions" note pulls UP next to "Today net"
   on the first row (spacer hidden). Wide layout is unchanged (one line, note
   pushed right by the spacer). Scoped via :has() so other tools rows (divers /
   team facet bars) are untouched. */
@media (max-width: 1400px) {
  .os-page-tools:has(.os-anchor-stat) > .os-scope-tabs { flex: 0 0 100%; order: 3; }
  .os-page-tools:has(.os-anchor-stat) > .os-spacer { display: none; }
  .os-page-tools:has(.os-anchor-stat) > .os-page-tools__note { order: 1; }
}
/* Number-forward pill: mono count + label on one line, in a fully-rounded
   hairline pill. Active = clean white chip with a soft lift + accent number
   (was an accent-soft fill). Matches the mobile filter-sheet pills 1:1. */
.os-scope-tab {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 6px 13px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--hairline);
  cursor: pointer; font: inherit; text-decoration: none; white-space: nowrap;
}
.os-scope-tab:hover { background: var(--canvas); }
.os-scope-tab__n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-md); font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.os-scope-tab__l { font-size: var(--text-sm); color: var(--muted); }
.os-scope-tab.is-on { background: var(--surface); border-color: var(--accent-border, rgba(3,105,161,0.18)); box-shadow: 0 1px 2px rgba(15,23,42,0.08); }
.os-scope-tab.is-on .os-scope-tab__n { color: var(--accent); }
.os-scope-tab.is-on .os-scope-tab__l { color: var(--ink); }
.os-scope-tab__n--neg  { color: var(--error, #c13028); }
.os-scope-tab__n--zero { color: var(--muted-2); }
/* --md (v1.37.0): scope tabs on the control-height scale, for a filter row that
   sits with other controls. 40px tabs (--control-h-md) with an 8px gap between
   tabs and between wrapped rows; 48px (--control-h-touch) below md so each tab
   is a full touch target. The default size (no modifier) is unchanged. */
.os-scope-tabs--md { gap: var(--space-2); }
.os-scope-tabs--md .os-scope-tab {
  box-sizing: border-box;
  height: var(--control-h-md);
  align-items: center;
  padding-block: 0;
}
@media (max-width: 767px) {
  .os-scope-tabs--md .os-scope-tab { height: var(--control-h-touch); }
}
/* Scope-filter hide utility — toggled by the `scope-filter` Stimulus
   controller to show/hide items by the active tab's data-scope. !important
   beats element display rules (grid/flex items) so any item type hides. */
.os-hide { display: none !important; }
/* #107 — search-filter and cert-filter own their own hide classes so they
   compose with scope-filter (.dv-hide) instead of clobbering one shared class.
   A row is visible only when NONE of the three filters wants it hidden. */
:is(.search-hide, .os-search-hide), :is(.cert-hide, .os-cert-hide) { display: none !important; }
/* Filter control — row-2 of .dv-page-tools (date pickers, toggles, facets).
   32px at base density so controls align with each other + the scope tabs by
   construction; 40px under .os-density--touch, via its own --filter-btn-h
   (NOT --control-h, so a form-scoped field height never inflates it). ONE staff filter control: date pickers, facets, toggles all use
   it at --radius-sm. .is-on is the accent-soft active state.
   (.os-filter-pill is the portal-only chip — agent/guest surfaces, not staff.)
   (Canonical in WL design-system tokens.css#filter-control.) */
.os-filter-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: var(--filter-btn-h); padding: 0 12px;
  font-size: var(--text-xs); font-weight: 500;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--interactive-border);
  color: var(--interactive);
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: border-color var(--t-fast) ease, background var(--t-fast) ease, color var(--t-fast) ease;
}
.os-filter-btn:hover { border-color: var(--interactive-border-hover); color: var(--interactive-hover); }
.os-filter-btn svg, .os-filter-btn [data-lucide] { color: currentColor; flex-shrink: 0; }
.os-filter-btn__chev { margin-left: 2px; }
/* DEPRECATED (v1.27.0): --pill. Staff filters are square (--radius-sm); use the
   base .os-filter-btn (+ .is-on). Kept working for existing callers; slated for
   removal in a future major. Portal chips use .os-filter-pill instead. */
.os-filter-btn--pill { border-radius: 999px; color: var(--interactive); }
.os-filter-btn--pill:hover { color: var(--interactive-hover); }
.os-filter-btn.is-on { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent); }
.os-filter-btn.is-on svg, .os-filter-btn.is-on [data-lucide] { color: var(--accent); }
/* --kv: key/value applied-filter read-out — tracked-caps key + value
   ("ARRIVING Today"). With .is-on both parts take the accent. */
.os-filter-btn--kv { gap: 6px; font-size: var(--text-sm); }
.os-filter-btn__k {
  font-size: var(--text-2xs); font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted-2);
}
.os-filter-btn__v { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
.os-filter-btn.is-on :is(.os-filter-btn__k, .os-filter-btn__v) { color: var(--accent); }
/* Split: change + clear as two tap targets reading as one --radius-sm shape.
   <div class="os-filter-split"><button class="os-filter-btn …">…</button>
   <a class="os-filter-btn os-filter-btn__clear">×</a></div> */
.os-filter-split { display: inline-flex; flex: none; }
.os-filter-split > .os-filter-btn:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.os-filter-split > .os-filter-btn + .os-filter-btn { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px; }
.os-filter-btn__clear { justify-content: center; padding: 0; aspect-ratio: 1; }
.os-filter-btn__clear:hover { background: var(--accent-border); }
/* v1.42.0: phones (≤640) — the filter control draws at 32px (40 under
   .os-density--touch) but takes taps across at least 48px, as the page-head
   actions do (v1.41.0). A transparent ::after pads the hit box to 48 on each
   axis that is shorter, centred, so nothing moves. The button is its own
   stacking context and the pad sits BEHIND its content: a control that lays a
   transparent input over itself (a date chip) still gets every tap inside its
   drawn box; the pad only catches taps around it. In a split, the clear ×
   pads rightward only (at most the 12px toolbar gap), so it never takes taps
   from a neighbour. */
@media (max-width: 640px) {
  .os-filter-btn { position: relative; isolation: isolate; }
  .os-filter-btn::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: min(0px, calc(50% - 24px));
    bottom: min(0px, calc(50% - 24px));
    left: min(0px, calc(50% - 24px));
    right: min(0px, calc(50% - 24px));
  }
  /* Capped at 12px, the toolbar gap: past it the pad would take taps from the
     next control in the row. A 32px × is 44px wide and 48px tall. */
  .os-filter-split > .os-filter-btn__clear::after { left: 0; right: min(0px, calc(100% - 44px)); }
}
/* ── Filter bar (full-control row) ────────────────────────────────────
   A wrapping row of full-size form controls (search input, selects, date
   pickers, a checkbox toggle, submit + clear buttons). Every direct control is
   normalised to the canonical 46px field height so the row aligns on one
   baseline by construction — no per-control height utilities. Pair the buttons
   with `.dv-btn--field` (also 46px). Shell/framework-agnostic: normalises by
   ELEMENT + gem field classes (`.dv-select`, `.dv-field`), not any product form
   namespace — a consumer's own inputs/selects placed in the bar are covered. */
.os-filter-bar :is(input:not([type="checkbox"]):not([type="radio"]), select, .os-select, .os-select-field) { height: 46px; }
/* Checkbox toggle styled as a bordered control so it reads as a peer of the
   inputs in the row (box + label inside a 46px hairline pill). Apply `.dv-check`
   to the toggle wrapper. */
.os-filter-bar .os-check {
  height: 46px;
  align-items: center;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--t-fast) ease;
}
.os-filter-bar .os-check:hover { background: var(--canvas); }
/* Ledger title-level date nav (.dv-pager) + today tag */
.os-pager { display: inline-flex; align-items: center; border: 1px solid var(--hairline); border-radius: 10px; overflow: hidden; }
.os-pager__step {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer; color: var(--interactive); text-decoration: none;
}
.os-pager__step:hover { background: var(--accent-soft); color: var(--interactive-hover); }
.os-pager__date {
  display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px;
  background: transparent; border: none; border-left: 1px solid var(--hairline); border-right: 1px solid var(--hairline);
  font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; color: var(--accent); cursor: default;
}
.os-today-tag {
  display: inline-flex; align-items: center; height: 28px; padding: 0 12px;
  border-radius: 999px; background: var(--accent-soft); border: 1px solid var(--accent-border, rgba(3,105,161,0.18));
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent);
  cursor: pointer; text-decoration: none;
}
/* Ledger anchor stat (leads the scope row) */
.os-anchor-stat { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }
.os-anchor-stat__label { font-size: var(--text-2xs); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-2); }
/* Money anchor (Ledger "Today net") — Geist Mono tabular per the numerics rule,
   and sign-driven color: ink at zero, green only when positive, rose when
   negative (was hardcoded green, so $0.00 read as a gain). */
.os-anchor-stat__value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-xl); font-weight: 600; color: var(--ink); letter-spacing: -0.02em; }
.os-anchor-stat__value--pos { color: var(--confirmed); }
.os-anchor-stat__value--neg { color: var(--error, #c13028); }
/* ═══════════════════════════════════════════════════════════════════════
   Mobile list header (≤640) — inline, no collapse. The row-2 tools bar stays
   visible as one horizontal-scroll strip (a bottom-sheet collapse was tried and
   removed: a fixed overlay fought the app's board views, transformed shell
   containers and Turbo lifecycle, and a filter you can't see is a filter you
   can't use). The slim title bar (row 1) pins on scroll.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* The whole slim title bar sticks to the top on scroll, so the title, search
     and actions stay reachable down a long list.

     z-index kept LOW on purpose: a sticky (positioned) element already paints
     above the in-flow list without any z-index, so `5` is only here to order it
     against other positioned content. Critically it must stay BELOW the shell's
     fixed mobile nav toggle (the hamburger the shell overlays top-left) so the
     pinned white band never paints over it — shells put that toggle above
     content, and 5 leaves ample room under it. */
  .os-page-head {
    position: sticky;
    top: 0;
    z-index: 5;
    /* Tighten the desktop 32/18 padding to a symmetric phone rhythm. This both
       shrinks the bulky bar to the compact height the mocks show AND centres the
       title/actions cluster at ~32px from the pinned top — the vertical centre a
       shell hamburger sits at — so the toggle and the header row line up. */
    padding-top: 12px;
    padding-bottom: 12px;
    align-items: center;
  }

  /* Smaller pinned title — the desktop display size reads as oversized on a
     phone bar; step it down to the 2xl step (the mock size). */
  .os-page-head h1, h1.os-page-head__title { font-size: var(--text-2xl); }

  /* Equal-height action controls — search, the view toggle and the primary CTA
     all land on ONE 40px height so the cluster reads as a tidy row (the
     segmented control shipped taller than the icon buttons). */
  .os-page-head__actions :is(.os-btn, .os-btn--primary, .segmented, .os-segmented,
    .os-hsearch__toggle) {
    height: 40px;
  }
  .os-page-head__actions :is(.segmented, .os-segmented) { align-items: center; }

  /* Inline tools row: one horizontal-scroll strip so scope tabs + facet chips
     never wrap into a ragged multi-row block; swipe sideways to reach the rest.

     Sticks BELOW the pinned title bar (top = the header's height, set as
     `--os-tools-top` by the consumer's `page-tools` controller), so the two
     bands stack instead of colliding at top:0 (the "double bar"). z-index 4 is
     below the title bar (z 5) so the row slides up BEHIND it when hidden. The
     controller reveals it on scroll-UP (removes `--hidden`) and hides it on a
     sustained scroll-DOWN — quick access to filters without permanent chrome. */
  .os-page-tools {
    position: sticky;
    top: var(--os-tools-top, 0);
    z-index: 4;
    transition: transform 0.24s var(--ease-out-quart, ease);
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .os-page-tools.os-page-tools--hidden { transform: translateY(-165%); }
  /* When pinned on phones the row stacks BELOW the title bar, so it needs NO
     hamburger gutter — but it must keep the normal content inset (bleed-pad), so
     the first scope tab sits inset at rest and the strip still scrolls full-bleed
     to the edge. (The `page-tools` controller's --pinned gutter, meant for the
     top:0 case, would otherwise leave a 64px gap.) */
  .os-page-tools.os-page-tools--pinned { padding-left: var(--bleed-pad, 16px); }
  .os-page-tools::-webkit-scrollbar { display: none; }
  .os-page-tools > * { flex: 0 0 auto; }
  .os-page-tools > .os-spacer { display: none; }
  .os-page-tools .os-scope-tabs { flex-wrap: nowrap; }

  /* Primary facet strip (#329, v1.28.0). The list's main facet stays a
     horizontal-scroll strip BY DESIGN — it never wraps; secondary facets move
     into the `.os-filter-sheet` behind the Filters trigger. On phones the
     active pill takes the accent tint (desktop keeps the white chip). */
  .os-scope-tabs--primary { flex-wrap: nowrap; gap: 8px; }
  .os-scope-tabs--primary .os-scope-tab.is-on,
  .os-filter-sheet__body .os-scope-tab.is-on {
    background: var(--accent-soft);
    border-color: var(--accent-border);
    box-shadow: none;
  }
  :is(.os-scope-tabs--primary, .os-filter-sheet__body) .os-scope-tab.is-on :is(.os-scope-tab__n, .os-scope-tab__l) { color: var(--accent); }
}
/* ═══════════════════════════════════════════════════════════════════════
   Mobile treatment for the OTHER header component — `page_header`
   (`.os-page-band.page-header`), used by form / settings / simple pages. The
   same phone polish the list header (`.os-page-head`) gets, so a page reads the
   same on mobile regardless of which header component it was built with:
   pinned slim bar, stepped-down title, equal-height actions. Loaded after
   patterns.css, so these win over the component's base rules there.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  :is(.page-header, .os-page-header) {
    position: sticky;
    top: 0;
    z-index: 5;
    /* Tighten the desktop space-8/space-6 padding to the same compact phone
       rhythm as the list header. (`margin-top: -56px` from patterns.css keeps
       the bleed-up.) Clear the shell nav toggle HORIZONTALLY via the nav gutter
       (like `.os-page-head`), so the title sits BESIDE the hamburger, not below
       it — consistent across both header components. */
    padding-top: 12px;
    padding-bottom: 12px;
    padding-left: var(--dv-nav-gutter, 0);
  }
  :is(.page-header, .os-page-header) h1 { font-size: var(--text-2xl); }
  /* v1.37.0: the row wraps. A title + subtitle beside the actions ran past a
     370px phone; now the actions drop to their own line (and wrap among
     themselves) when they don't fit. Headers whose actions fit are unchanged. */
  :is(.page-header__row, .os-page-header__row) { align-items: center; flex-wrap: wrap; row-gap: var(--space-3); }
  :is(.page-header__actions, .os-page-header__actions) { flex-shrink: 1; flex-wrap: wrap; max-width: 100%; }
  /* Equal-height actions, matching the list header's 40px cluster. */
  :is(.page-header__actions, .os-page-header__actions) :is(.hero-show__action,
    .os-hero-show__action, .os-btn, .segmented, .os-segmented) {
    height: 40px;
  }

  /* Detail headers — hand-rolled `.os-page-band` bands carrying an entity title
     + status + actions (a booking, a dive trip, a diver). Same compact rhythm
     and stepped title. Only the TITLE LINE clears the hamburger, horizontally:
     the band keeps the page gutter, so whatever sits below the toggle (crumb,
     meta, chips, actions) lines up with the body instead of hanging 48px in
     (v1.43.0; the whole band used to take the nav gutter). Non-sticky: on these
     pages the band-2 tab nav (`.os-tabnav`) is what pins. `:has(h1)` keeps this
     off stat strips + tab navs; excludes page_header (above) + navs. */
  .os-page-band:has(h1):not(.os-tabnav):not(.page-header):not(.os-page-header):not(nav) {
    padding-top: 12px;
    padding-bottom: 12px;
    --os-nav-clear: max(0px, calc(var(--dv-nav-gutter, 0px) - var(--bleed-pad, 0px)));
  }
  .os-page-band:has(h1):not(.os-tabnav):not(.page-header):not(.os-page-header):not(nav):not(.hero-show__band):not(.os-hero-show__band) h1,
  :is(.hero-show__band, .os-hero-show__band) :is(.hero-show__title-row, .os-hero-show__title-row) {
    margin-left: var(--os-nav-clear, 0px);
  }
  /* The detail head's crumb sits under the title, which rides the toggle's
     line; keep it a step clear of the toggle's bottom edge. */
  :is(.hero-show__band, .os-hero-show__band) > .os-breadcrumb { margin-top: var(--space-2, 8px); }
  /* A tab nav right under a detail head is not at the page top, so it keeps
     the page gutter too (also when a controller wrapper sits between them). Pinned (`.is-stuck`), it takes the nav gutter again. */
  .os-page-band:has(h1) ~ nav.os-page-band:not(.is-stuck),
  .os-page-band:has(h1) ~ * nav.os-page-band:not(.is-stuck) { padding-left: var(--bleed-pad, 0); }
  .os-page-band:not(.os-tabnav) h1 { font-size: var(--text-2xl); }

  /* Band-2 tab nav: when it pins to the top it collides with the fixed
     hamburger, so inset the tab row by the gutter while stuck (the `stuck`
     controller adds `.is-stuck`). At rest it sits below the header, un-inset. */
  .os-tabnav.is-stuck { padding-left: var(--dv-nav-gutter, 0); }
}
/* ═══════════════════════════════════════════════════════════════════════
   Phone page head (≤640) — v1.41.0, os-ds #7. docs/mobile-header.md.

   One layout for every page head on a phone, in DiveOS and HotelOS alike:
     row 1   [shell ☰] · page title (h1) · primary action(s)
     row 2             ‹ Parent
   The title rides the hamburger's line; the breadcrumb, collapsed to its
   parent link (components/breadcrumb.css), sits UNDER the title. It reads "you
   are on X, inside Y" and leaves the line beside the hamburger to the title.
   A section screen inside a hub (Settings → Branding) titles itself with the
   section and crumbs back to the hub ("‹ Settings").

   Covers the list head (.os-page-head, also a shell-rendered one whose lead is
   `.os-page-head__lead`), the form / settings head (.page-header, from
   _page_header) and the detail head (.hero-show__band). Tablet and desktop are
   untouched: the crumb stays above the title there.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* Row 2: the crumb goes under the title. The title block becomes a column and
     the crumb is ordered after the title; anything after the title (a
     subtitle, a shell's section nav) is ordered after the crumb, so "‹ Parent"
     stays directly under the h1. */
  .os-page-head > :first-child:has(> .os-breadcrumb) { display: flex; flex-direction: column; }
  .os-page-head > :first-child > .os-breadcrumb { order: 1; margin-bottom: 0; }
  .os-page-head > :first-child > :is(h1, .os-page-head__titlerow) ~ :not(.os-breadcrumb) { order: 2; }
  /* Top-aligned, so the actions stay level with the title line, not centred on
     the title + crumb pair. */
  .os-page-head:has(> :first-child > .os-breadcrumb) { align-items: flex-start; }

  /* The form / settings head (_page_header): crumb · [title · subtitle | actions].
     The row and the title block step aside (display: contents) so the band is
     one grid: title and actions on row 1, crumb on row 2, subtitle on row 3.
     Actions that carry an icon fold to it (40px), as in the list head, so
     they fit beside the title; the label stays as the accessible name. */
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    -moz-column-gap: 8px;
         column-gap: 8px;
    align-items: start;
  }
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) :is(.page-header__row, .os-page-header__row, .page-header__identity, .os-page-header__identity) { display: contents; }
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) h1 { grid-column: 1; grid-row: 1; }
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) :is(.page-header__actions, .os-page-header__actions) { grid-column: 2; grid-row: 1; justify-content: flex-end; min-height: 44px; flex-wrap: nowrap; gap: 6px; }
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) :is(.page-header__actions, .os-page-header__actions) :is(.hero-show__action, .os-hero-show__action, .os-btn):has(svg) {
    gap: 0;
    width: 40px;
    min-width: 40px;
    padding-left: 0;
    padding-right: 0;
    justify-content: center;
    font-size: 0;
  }
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) :is(.page-header__actions, .os-page-header__actions) :is(.hero-show__action, .os-hero-show__action, .os-btn) > svg { width: 18px; height: 18px; }
  :is(.page-header, .os-page-header) > .os-breadcrumb { grid-column: 1 / -1; grid-row: 2; margin-bottom: 0; }
  :is(.page-header, .os-page-header):has(> .os-breadcrumb) :is(.page-header__identity, .os-page-header__identity) > :not(h1) { grid-column: 1 / -1; grid-row: 3; margin-top: var(--space-2, 8px); }
  /* Its title rides the hamburger's 44px band, as the list head's does. */
  :is(.page-header, .os-page-header) h1 { min-height: 44px; display: flex; align-items: center; }

  /* The detail head (hero_show): crumb · [eyebrow · title row · subtitle · meta]
     · actions. On phones it is already one column; the header and identity
     step aside so the crumb can sit right under the title row, ahead of the
     rest. */
  :is(.hero-show__band, .os-hero-show__band):has(> .os-breadcrumb) { display: flex; flex-direction: column; }
  :is(.hero-show__band, .os-hero-show__band):has(> .os-breadcrumb) :is(.hero-show__header, .os-hero-show__header, .hero-show__identity, .os-hero-show__identity) { display: contents; }
  :is(.hero-show__band, .os-hero-show__band):has(> .os-breadcrumb) :is(.hero-show__identity, .os-hero-show__identity) > *,
  :is(.hero-show__band, .os-hero-show__band):has(> .os-breadcrumb) :is(.hero-show__actions, .os-hero-show__actions) { order: 2; }
  :is(.hero-show__band, .os-hero-show__band):has(> .os-breadcrumb) :is(.hero-show__actions, .os-hero-show__actions) { margin-top: 16px; }
  :is(.hero-show__band, .os-hero-show__band):has(> .os-breadcrumb) :is(.hero-show__title-row, .os-hero-show__title-row) { order: 0; min-height: 44px; margin-bottom: 0; }
  :is(.hero-show__band, .os-hero-show__band) > .os-breadcrumb { order: 1; margin-bottom: 8px; }

  /* The title is left-aligned, beside the hamburger: a head never centres it,
     whatever the page's own alignment. */
  :is(.os-page-head > :first-child, .page-header__identity, .os-page-header__identity, .hero-show__identity, .os-hero-show__identity) { text-align: start; }
  :is(.os-page-head, .page-header, .os-page-header, .hero-show__band, .os-hero-show__band) h1 { justify-content: flex-start; text-align: start; }

  /* Touch target: the icon actions draw at 40px (level with the 44px hamburger)
     but take taps across 48px. A transparent ::after pads the hit area 4px on
     each side; the 6px gap between actions means neighbours overlap by 2px at
     most, and the later one wins there. */
  .os-page-head__actions :is(.os-btn, .os-hsearch__toggle),
  :is(.page-header__actions, .os-page-header__actions) :is(.hero-show__action, .os-hero-show__action, .os-btn) { position: relative; }
  .os-page-head__actions :is(.os-btn, .os-hsearch__toggle)::after,
  :is(.page-header__actions, .os-page-header__actions) :is(.hero-show__action, .os-hero-show__action, .os-btn)::after {
    content: "";
    position: absolute;
    inset: -4px;
  }
}
/* ─────────────────────────────────────────────────────────────────────
   header_band — DiveOS integration layer.

   The COMPONENT now comes from os-ds (`os_ds/components/header_band.css`,
   imported in application.css just above this file). This sheet holds only
   the rules the gem cannot own:

     - adaptations to DiveOS's shell (.diveos-main, the mobile hamburger)
     - a fix for a Bullet Train theme leak (.bulk-actions)
     - the one token the gem expects the host app to supply

   De-vendored 2026-07-21. 119 of the previous 125 local rules were
   byte-identical to the gem and were deleted; what remains is below.

   PARITY NOTE — the gem tokenised the nav gutter as
   `nav.dv-page-band { padding-left: var(--dv-nav-gutter, 0) }`, where the
   old local copy hardcoded 64px. Without the :root token below, that
   gutter silently collapses to 0 with no error and no failing test.
   ───────────────────────────────────────────────────────────────────── */
/* Gutters the gem reads but does not define — the host app supplies them,
   because only the host knows it has a fixed mobile hamburger.
     --dv-nav-gutter     → horizontal inset  (was hardcoded 64px locally)
     --dv-nav-gutter-top → vertical clearance (was hardcoded 72px locally)
   Both fall back to 0 in the gem, so omitting either collapses the gutter
   silently: no error, no failing test. --dv-nav-gutter-top only bites below
   1023px, which is why a desktop-only visual check cannot catch it. */
:root {
  --dv-nav-gutter: 64px;
  --dv-nav-gutter-top: 72px;
}
/* Bullet Train's bulk-actions theme ($ThemeStylesheet) leaks
   `.bulk-actions:not(.selectable) th:nth-child(2) { padding-left: 2rem }` — its
   sticky "identity column" inset — onto OUR .dv-table-wrap headers (BT wraps
   index tables in .bulk-actions). That over-pads the 2nd-column header so its
   label no longer sits above its data column (esp. visible on reorderable
   tables where col 2 is the Name). Reset it to the canonical px-3 (12px) gutter
   so headers align with their cells. The leak is (0,3,1) (.bulk-actions +
   :not(.selectable) + th + :nth-child), so we match the .bulk-actions ancestor
   too — (0,3,2) — to win without !important. */
:is(.bulk-actions, .os-bulk-actions) :is(.dv-table-wrap, .os-table-wrap) thead th:nth-child(2) { padding-left: var(--space-3); }
/* The SAME BT leak also lands on the BODY cell:
   `.bulk-actions:not(.selectable) td:nth-child(2) { padding-left: 1.25rem }` (20px)
   over-pads the 2nd-column <td> so the row content (e.g. the Name/Slug link) sits
   8px to the right of its header label (which we pin to 12px above). Reset the td
   to the canonical px-3 (12px) gutter so header text sits directly above row text. */
:is(.bulk-actions, .os-bulk-actions) :is(.dv-table-wrap, .os-table-wrap) tbody td:nth-child(2) { padding-left: var(--space-3); }
/* ── Filter bar control sizing ────────────────────────────────────────
   A wrapping row of full-size form controls normalised to the canonical
   46px field height so the row aligns on one baseline by construction.
   Depends on DiveOS's .diveos-input/.diveos-select, so it stays local. */
:is(.dv-filter-bar, .os-filter-bar) :is(.diveos-input, .os-input), :is(.dv-filter-bar, .os-filter-bar) :is(.diveos-select, .os-field-select) { height: 46px; }
/* Checkbox toggle styled as a bordered control so it reads as a peer of the
   inputs in the row (box + label inside a 46px hairline pill). */
:is(.dv-filter-bar, .os-filter-bar) :is(.diveos-check, .os-field-check) {
  height: 46px;
  align-items: center;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--t-fast) ease;
}
:is(.dv-filter-bar, .os-filter-bar) :is(.diveos-check, .os-field-check):hover { background: var(--canvas); }
/* Mobile header gutter: OWNED BY os-ds, not here. The gem's header_band.css
   already parametrises every mobile rule on `--dv-nav-gutter` /
   `--dv-nav-gutter-top` (list header left gutter, detail-band top clearance,
   the `--pinned` tools gutter, and the ≤640 compact treatment). The shell's ONLY
   job is to supply those values — done in the `:root` block above. The block
   that used to re-hardcode 64px/72px here was pure duplication and drift; it was
   removed so DiveOS inherits the generic pattern from OS. */
/* Tablets (641px+, pane ≤880) — the v1.38 rule keeps a head's button/link
   actions on the title row, but counts any visible input as a search field
   and drops the actions to a full-width row. The day pager's transparent
   picker input (.fo-date-pick__input) isn't a field: the desk and Ledger heads
   keep their pager + actions on the title row like other button heads. */
@media (min-width: 641px) {
  @container (max-width: 880px) {
    .os-page-head:has(.os-page-head__actions .fo-date-pick__input):not(:has(.os-page-head__actions :is(input:not([type="hidden"], [type="submit"], .fo-date-pick__input), select, textarea, .os-hsearch))) {
      flex-wrap: wrap;
      align-items: flex-start;
    }
    .os-page-head:has(.os-page-head__actions .fo-date-pick__input):not(:has(.os-page-head__actions :is(input:not([type="hidden"], [type="submit"], .fo-date-pick__input), select, textarea, .os-hsearch))) > :first-child {
      flex: 1 1 var(--sidebar-w);
      min-width: 0;
    }
    .os-page-head:has(.os-page-head__actions .fo-date-pick__input):not(:has(.os-page-head__actions :is(input:not([type="hidden"], [type="submit"], .fo-date-pick__input), select, textarea, .os-hsearch))) > .os-page-head__actions {
      width: auto;
      flex: 0 1 auto;
      justify-content: flex-end;
    }
  }
}
/* table.css — list/index cell TYPOGRAPHY (.dv-table__primary/sub/meta/th/figure).
   MUST load after header_band.css (owns the .dv-table-wrap chrome) so the cell
   type classes win where the two overlap. Without this import the .dv-table__*
   classes don't exist and cells fall back to the 16px root (bookings, team, …). */
/* ─────────────────────────────────────────────────────────────────────
   .dv-table — list/index table TYPOGRAPHY component (maturity ladder ①②③).

   Promotes the cell typography that every account/* list table was
   re-inventing with bespoke utilities (text-[13.5px], text-[12px] mt-0.5,
   font-mono, mixed medium/semibold, 13/13.5/14.5px sizes). This sheet owns
   the *cell content* vocabulary; the surrounding chrome (outer border,
   radius, canvas header band, hairline rows, hover, py-3 rhythm,
   first/last-child padding) STILL lives in header_band.css under
   `.dv-table-wrap` / `.box-table` and is NOT moved or duplicated here.
   The two COEXIST: a table renders inside `.dv-table-wrap` for chrome and
   uses `.dv-table__*` classes on its cells for typography.

   Canonical type scale (anchored on bookings/divers — the closest pair):
     .dv-table__primary  13.5px / 500 / --ink   (link → hover accent, no underline)
     .dv-table__sub      12px   / --muted        (+2px top INSIDE the stack)
     .dv-table__stack    flex column owning the 2px primary→sub gap
     .dv-table__meta     13px   / --muted        (--mono → mono tabular-nums)
     .dv-table__th       11px uppercase tracking / --muted header cell

   Token-only (var(--token)); no raw hex, no raw Tailwind palette.
   Loaded after header_band.css (see application.css).
   ───────────────────────────────────────────────────────────────────── */
/* ── Optional element hook ────────────────────────────────────────────
   `.dv-table` may be added to a <table> for scoping, but the cell classes
   work standalone so existing `.dv-table-wrap table` markup adopts them
   incrementally with zero structural change. */
.os-table { width: 100%; border-collapse: collapse; }
/* ── Primary cell text (the row's headline: name, ID, title) ──────────── */
.os-table__primary {
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink);
}
/* A link inside the primary slot: inherits the headline type, lifts to the
   accent on hover, never underlines (the row-hover tint is the affordance). */
.os-table__primary a, a.os-table__primary {
  color: inherit;
  text-decoration: none;
  transition: color var(--t-fast) ease;
}
.os-table__primary a:hover, a.os-table__primary:hover {
  color: var(--accent);
  text-decoration: none;
}
/* ── Sub text (secondary line under the primary: email, brand, serial) ─── */
.os-table__sub {
  font-size: var(--text-xs);
  line-height: 1.3;
  color: var(--muted);
}
/* ── Stack (primary + sub) — owns the 2px gap so cells stop using mt-0.5 ── */
.os-table__stack {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.os-table__stack .os-table__sub { margin-top: 2px; }
/* ── Meta cell (neutral data: dates, counts, specialties, condition) ───── */
.os-table__meta {
  font-size: var(--text-sm);
  color: var(--muted);
}
.os-table__meta--mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
/* ── Figure cell (prominent commercial numeric: price, total, commission) ──
   Like __meta--mono but INK, not muted — a price is primary data, not neutral
   meta. Mono + tabular so a column of figures aligns. */
.os-table__figure {
  font-size: var(--text-sm);
  color: var(--ink);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
/* ── Header cell — matches the existing .dv-table-wrap thead th treatment
   so promoting a header to this class doesn't shift pixels. ─────────────── */
.os-table__th {
  /* Component owns the header band height — mirrors how `.dv-table-wrap td`
     owns body-row rhythm (header_band.css), so a surface never has to remember
     a py-* utility on every <th>. ~14px ≈ divers/index's py-3.5, one step
     tighter than the 16px body row. */
  padding-top: 14px;
  padding-bottom: 14px;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
}
/* ── Row interaction states (consistent with header_band.css's
   `.dv-table-wrap tbody tr:hover { background: var(--surface-alt) }`). ──── */
.os-table tbody tr.is-interactive { cursor: pointer; }
.os-table tbody tr.is-interactive:hover, .os-table tbody tr.is-interactive:focus-within { background: var(--hover-warm); }
.os-table tbody tr.is-selected {
  background: var(--accent-soft);
  box-shadow: inset 2px 0 0 var(--accent);
}
.os-table tbody tr.is-selected:hover { background: var(--accent-soft); }
/* ════════════════════════════ Variants ════════════════════════════════ */
/* --avatar — first cell pairs an avatar with the primary/sub stack. The
   avatar partial owns its own size; this just sets the flex pairing + gap. */
.os-table--avatar td:first-child .os-table__cell, .os-table__avatar-cell {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
/* --compact — tighter vertical rhythm for dense lists (overrides the gated
   py-3 baseline on cells that don't set their own padding). */
.os-table--compact td:not([class*="py-"]) {
  padding-top: var(--space-2, 8px);
  padding-bottom: var(--space-2, 8px);
}
.os-table--compact .os-table__primary { font-size: var(--text-sm); }
/* --numeric — right-align numeric columns and tabularise their figures so
   digits line up column-wise (amounts, pax, counts). */
.os-table--numeric td.os-table__num, .os-table--numeric th.os-table__num, .os-table__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.os-table--numeric td.os-table__num { font-family: var(--font-mono); }
/* ════════════════════ __actions — right-pinned action column ═══════════════
   Keeps the row's actions (edit/delete/overflow) visible without scrolling to
   the end of a wide table. The cell sticks to the right edge of the scroll
   container; a gradient bleed on its left signals that body content passes
   UNDER it (shown only when the table actually overflows — the
   `dv-table-scroll` Stimulus controller toggles `.is-scrollable`, so a table
   that fits shows no fade over real content). Add `.dv-table__actions` to BOTH
   the actions `<th>` and each row's actions `<td>`.

   --dv-pin-bg is the opaque backing the pinned cell paints (so scrolled cells
   don't bleed through it) AND the solid end of the gradient — it tracks the
   row background (surface → hover sky-50 → selected accent-soft) so the pin and
   its fade always match the row underneath. Token-only; light-only. */
.os-table-wrap { --dv-pin-bg: var(--surface); }
.os-table-wrap thead th.os-table__actions { --dv-pin-bg: var(--canvas); }
.os-table-wrap tbody tr:hover { --dv-pin-bg: var(--sky-50); }
.os-table-wrap tbody tr.is-selected { --dv-pin-bg: var(--accent-soft); }
.os-table__actions {
  position: sticky;
  right: 0;
  z-index: 1;
  background: var(--dv-pin-bg);
}
/* Transparency bleed: the scrolling body content fades out just before the
   pinned actions instead of hard-cutting under them. The ::before sits to the
   LEFT of the (opaque) cell so the fade falls over the CONTENT, never over the
   action icons themselves; its solid end tracks --dv-pin-bg so it matches the
   row (surface / hover / selected). Shown only when the wrap overflows. */
.os-table__actions::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 28px;
  transform: translateX(-100%);
  pointer-events: none;
  background: linear-gradient(to right, transparent, var(--dv-pin-bg));
  opacity: 0;
  transition: opacity var(--t-fast) ease;
}
.os-table-wrap.is-scrollable .os-table__actions::before { opacity: 1 !important; }
/* Touch / tablet have no hover, so the desktop hover-reveal pattern
   (`opacity-0 group-hover:opacity-100` on the action group) leaves row actions
   permanently invisible. Force them visible on ANY touch device (hover: none,
   any width) and across the whole tablet range (≤1024px — portrait 768 +
   landscape 1024). Mouse desktop (>1024) keeps the hover-reveal declutter. */
@media (hover: none), (max-width: 1024px) {
  .os-table__actions > * { opacity: 1 !important; }
}
/* ════════════════════ --stack — card-stack below 640px ═════════════════════
   BL-1b. Opt-in modifier on the `.dv-table-wrap` for NARROW ENTITY tables
   (bookings, divers, roster, renters, invoices). Below the sm boundary each
   <tr> collapses into a bordered card and each <td> becomes a label→value row,
   the label sourced from `data-label` on the cell. Wide financial grids DO NOT
   get this — they scroll (BL-1a) instead. Token-only; light-only. */
@media (max-width: 639px) {
  /* Drop the desktop table FRAME in card-stack. `.dv-table-wrap` (header_band.css)
     carries its own surface/border/radius so a desktop table reads as one framed
     card; but here each row is already its own bordered card, so that frame draws
     a redundant outer box around the stack and its white fill shows through the
     inter-card gaps. Make the wrap a transparent, borderless container so the
     cards float on the page canvas. */
  .os-table-wrap--stack {
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow: visible;
  }

  /* Cards fill the wrap: drop the desktop min-width AND become a block that
     stretches to 100% (a bare table would shrink to its content width, leaving
     the cards narrower than the container). */
  .os-table-wrap--stack table { min-width: 0; width: 100%; display: block; }
  .os-table-wrap--stack tbody { display: block; }
  .os-table-wrap--stack thead { display: none; }

  .os-table-wrap--stack tbody tr {
    display: block;
    padding: var(--space-3, 12px) var(--space-4, 16px);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-md, 8px);
    background: var(--surface);
  }
  .os-table-wrap--stack tbody tr + tr { margin-top: var(--space-3, 12px); }

  /* Card-stack has no horizontal scroll, so the pinned/sticky action column is
     pointless here — worse, its stacking context paints cells OVER a sticky page
     header while the list scrolls (the row's "…/Fit gear" cell surfacing above
     the pinned title). Flatten every cell to normal flow in card mode.
     !important because the sticky rule that sets the high z is more specific. */
  .os-table-wrap--stack tbody td,
  .os-table-wrap--stack tbody th,
  .os-table-wrap--stack .os-table__actions {
    position: static !important;
    z-index: auto !important;
  }

  /* Cell → label/value row. data-label drives the field name on the left.
     Undo any desktop truncation/nowrap so long values (dive lists, notes) wrap
     instead of clipping; the value column may shrink and wrap under its label. */
  .os-table-wrap--stack tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3, 12px);
    padding: var(--space-1, 4px) 0;
    border: 0;
    text-align: right;
    white-space: normal;
    max-width: none;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
    /* Every cell aligns to the CARD's own inner padding. Kill the desktop
       per-cell horizontal padding that otherwise indents the title/status
       inconsistently: header_band's `td:first-child`/`:last-child` (16px) and
       `.bulk-actions … td:nth-child(2)` (12px), plus Tailwind px-3/pl-0/pr-3 —
       all out-specify the shorthand above, so force them off. */
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  /* Truly-empty cells (no value, e.g. an unset Stay glyph) are tagged by the
     dv-table-scroll controller and dropped so the card has no bare label rows. */
  .os-table-wrap--stack tbody td.os-td-empty { display: none; }
  .os-table-wrap--stack tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    text-align: left;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
  }
  /* A cell with no data-label (or explicitly blank) drops the label column. */
  .os-table-wrap--stack tbody td:not([data-label])::before, .os-table-wrap--stack tbody td[data-label=""]::before { content: none; }

  /* A leading drag-handle column (sortable catalog tables) is meaningless in the
     card stack and would render as an empty bordered stub above the name. Hide
     it and let the NEXT cell become the card header. */
  .os-table-wrap--stack tbody td:is(.cursor-grab, .os-cursor-grab), .os-table-wrap--stack tbody td:has([data-sortable-target="handle"]) { display: none; }

  /* Card header = the first CONTENT cell (the name/title): the literal first
     cell, OR the cell right after a hidden drag handle. Bold accent title, no
     label row, status pill kept on the right. */
  .os-table-wrap--stack tbody td:first-child, .os-table-wrap--stack tbody td:is(.cursor-grab, .os-cursor-grab) + td, .os-table-wrap--stack tbody td:has([data-sortable-target="handle"]) + td {
    padding-top: 0;
    padding-bottom: var(--space-2, 8px);
    margin-bottom: var(--space-1, 4px);
    border-bottom: 1px solid var(--hairline);
    align-items: center;
    /* The title is a heading, not a value — left-align it (the generic cell rule
       right-aligns values, which would shove an avatar-cell name to the right). */
    text-align: left;
  }
  .os-table-wrap--stack tbody td:first-child::before, .os-table-wrap--stack tbody td:is(.cursor-grab, .os-cursor-grab) + td::before, .os-table-wrap--stack tbody td:has([data-sortable-target="handle"]) + td::before { content: none; }
  .os-table-wrap--stack tbody td:first-child .os-table__primary, .os-table-wrap--stack tbody td:is(.cursor-grab, .os-cursor-grab) + td .os-table__primary, .os-table-wrap--stack tbody td:has([data-sortable-target="handle"]) + td .os-table__primary {
    font-weight: 600;
    color: var(--accent);
  }
  .os-table-wrap--stack tbody td:first-child .os-table__primary a, .os-table-wrap--stack tbody td:is(.cursor-grab, .os-cursor-grab) + td .os-table__primary a, .os-table-wrap--stack tbody td:has([data-sortable-target="handle"]) + td .os-table__primary a { color: var(--accent); }

  /* Cards stack vertically — no horizontal scroll — so the sticky pin is
     meaningless. Return the actions cell to normal flow and make it a COMPACT
     footer: buttons right-aligned and ALWAYS visible (no hover on touch, so the
     desktop `opacity-0 group-hover:opacity-100` reveal would hide them). Tight
     padding — a full divider + generous padding reads as dead space under two
     small icons. */
  .os-table-wrap--stack .os-table__actions {
    position: static;
    background: transparent;
    box-shadow: none;
    justify-content: flex-end;
    padding: 0;
    margin-top: var(--space-2, 8px);
    border-top: 0;
  }
  .os-table-wrap--stack .os-table__actions > * { opacity: 1 !important; }
}
/* ─────────────────────────────────────────────────────────────────────
   Shared component layer — boxed stat card grid.

   Promoted from the one-off `.ledger-stat-card` (+ `-grid`, `-label`, `-value`)
   that lived in account/ledger.css. This is the canonical BOXED stat component
   (surface card per stat), distinct from the inline `.kpi-strip` pattern in
   patterns.css. Use `.dv-stat-card-grid` when you want each KPI in its own
   bordered card (e.g. the Ledger day summary); use `.kpi-strip` for the flat
   inline stat strip.

   Values are matched BYTE-FOR-BYTE to the former `.ledger-stat-*` rules so the
   Ledger page renders identically. Token-driven; @imported from application.css
   after components/header_band.css.
   ───────────────────────────────────────────────────────────────────── */
/* ── Grid ─────────────────────────────────────────────────────────────
   5-up by default (the Ledger day summary). Callers can override
   grid-template-columns inline / page-scoped for other counts. */
.os-stat-card-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}
/* ── Card shell ─────────────────────────────────────────────────────── */
.os-stat-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
/* ── Label (uppercase eyebrow) ──────────────────────────────────────── */
.os-stat-card-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
/* ── Value (mono numeric) ───────────────────────────────────────────── */
.os-stat-card-value {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  margin-top: var(--space-2);
  line-height: 1;
}
/* ── Interactive variant (gear registry category filter cards) ────────
   A stat card that IS the interaction: rendered as an <a>, the whole
   card toggles a filter / navigates. Hover strengthens the border;
   `.is-active` carries the selected state (accent border + ultra-soft
   tint — mirrors the selected-row treatment). Focus ring per DESIGN.md
   accessibility rules. */
.os-stat-card--interactive {
  display: block;
  cursor: pointer;
  text-decoration: none;
  transition: border-color 150ms cubic-bezier(0, 0, 0.2, 1),
    background-color 150ms cubic-bezier(0, 0, 0.2, 1);
}
.os-stat-card--interactive:hover { border-color: var(--hairline-strong); }
.os-stat-card--interactive:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}
.os-stat-card--interactive.is-active {
  border-color: var(--accent);
  background: var(--accent-softer);
}
/* ── Sub line (one line of supporting data under the value, e.g.
   "3 new this month"). NOT decorative — carries a secondary metric. ──── */
.os-stat-card-sub {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--muted);
}
.os-stat-card-sub strong { font-weight: 600; color: var(--ink); }
.os-stat-card-sub a { color: var(--accent); font-weight: 500; }
.os-stat-card-sub a:hover { text-decoration: underline; }
/* ── Column modifiers ────────────────────────────────────────────────
   The base grid is 5-up (Ledger day summary). These give the common
   responsive 4-up / 3-up layouts without per-call inline overrides. The
   full-width modifier is for a single emphasis stat. */
.os-stat-card-grid--full { grid-template-columns: 1fr; }
.os-stat-card-grid--4 { grid-template-columns: 1fr; }
.os-stat-card-grid--3 { grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .os-stat-card-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .os-stat-card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .os-stat-card-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* These DS component stylesheets existed but were never wired into the bundle,
   so their components rendered UNSTYLED app-wide (e.g. .dv-table__primary fell
   back to the inherited body size, .dv-callout to plain text). Same class of
   gap as the earlier modal.css / desclist.css fixes.
   (table.css is already imported above — the duplicate is omitted.) */
/* ── .dv-callout ──────────────────────────────────────────────────────────
   Tinted status/info notice panel — the hand-rolled bg-*-bg panels promoted
   to a canonical component. NOT a card (no card shell); a flagged message.
   Layout: leading icon + content (optional eyebrow + body) + optional action.
   Tones key to the status palette triplets. Token-only; light-only.
   ───────────────────────────────────────────────────────────────────────── */
.os-callout {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  color: var(--ink);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.os-callout__icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: var(--space-0-5);
}
.os-callout__icon svg, .os-callout__icon [data-lucide] {
  width: 16px;
  height: 16px;
}
.os-callout__content {
  flex: 1 1 auto;
  min-width: 0;
}
.os-callout__eyebrow {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--space-1);
}
.os-callout__title {
  font-weight: 600;
  color: var(--ink);
}
.os-callout__body {
  color: var(--text-secondary);
}
.os-callout__title + .os-callout__body {
  margin-top: var(--space-0-5);
}
.os-callout__action {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  /* Centre the trailing action against the message instead of top-aligning it
     (the callout itself is flex-start so the icon hugs the first body line). A
     32px button beside a single-line title looked dropped without this. */
  align-self: center;
  margin-left: auto;
}
/* ── Tones ───────────────────────────────────────────────────────────────── */
.os-callout--info {
  background: var(--accent-soft);
  border-color: var(--accent-border);
  color: var(--ink);
}
.os-callout--info .os-callout__icon, .os-callout--info .os-callout__eyebrow {
  color: var(--accent);
}
.os-callout--briefing {
  background: var(--briefing-bg);
  border-color: var(--briefing-border);
  color: var(--briefing);
}
.os-callout--briefing .os-callout__icon, .os-callout--briefing .os-callout__eyebrow, .os-callout--briefing .os-callout__title {
  color: var(--briefing);
}
.os-callout--confirmed {
  background: var(--confirmed-bg);
  border-color: var(--confirmed-border);
  color: var(--confirmed);
}
.os-callout--confirmed .os-callout__icon, .os-callout--confirmed .os-callout__eyebrow, .os-callout--confirmed .os-callout__title {
  color: var(--confirmed);
}
.os-callout--cancelled {
  background: var(--cancelled-bg);
  border-color: var(--cancelled-border);
  color: var(--cancelled);
}
.os-callout--cancelled .os-callout__icon, .os-callout--cancelled .os-callout__eyebrow, .os-callout--cancelled .os-callout__title {
  color: var(--cancelled);
}
.os-callout--inwater {
  background: var(--inwater-bg);
  border-color: var(--inwater-border);
  color: var(--inwater);
}
.os-callout--inwater .os-callout__icon, .os-callout--inwater .os-callout__eyebrow, .os-callout--inwater .os-callout__title {
  color: var(--inwater);
}
/* ───────────────────────────────────────────────────────────────────────────
   .dv-segment — segmented control for a small set of mutually-exclusive
   options rendered as a native radio group (accessible, keyboard-navigable).
   Button chrome lives here so views never hand-roll bg-accent + rounded-btn
   utility soup (which trips the design-system lookalike gate).

   Markup:
     <div class="dv-segment dv-segment--block">
       <label class="dv-segment__option">
         <input type="radio" class="dv-segment__input sr-only" ...>
         <span class="dv-segment__label">DIN</span>
       </label>
       ...
     </div>
   ─────────────────────────────────────────────────────────────────────────── */
.os-segment {
  display: inline-flex;
  gap: 0.5rem;
}
.os-segment--block {
  display: flex;
  width: 100%;
}
.os-segment__option {
  flex: 1 1 0;
  cursor: pointer;
}
.os-segment__label {
  display: block;
  text-align: center;
  /* Density via vertical padding — same reasoning as .os-segmented__option in
     patterns.css: this label declares no height and is sized by its line box,
     so introducing a min-height would impose a floor it has never had.
     (36 − 20) / 2 = 8px at base density, identical to the 0.5rem literal it
     replaces; the 8px floor holds --compact at today's size. */
  padding: max(8px, calc((var(--control-h) - 20px) / 2)) 0.75rem;
  font-size: 0.875rem;
  color: var(--ink);
  background-color: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.os-segment__option:hover .os-segment__label {
  background-color: var(--surface-alt);
}
.os-segment__input:checked + .os-segment__label {
  background-color: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.os-segment__input:focus-visible + .os-segment__label {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* ── Breadcrumb (.dv-breadcrumb) ───────────────────────────────────────────
   The canonical in-body breadcrumb for Settings-accessed pages
   (Settings › Section › Record). Chevron-separated crumbs; the last crumb is
   the current (non-link) page. Standalone component — margin-free so the host
   (hero_show / page_header) owns vertical spacing. Promoted from the legacy
   .hero-show__breadcrumb / .hero-show__crumb* rules in patterns.css. */
.os-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-sm);
}
.os-breadcrumb__crumb { color: var(--muted); text-decoration: none; }
.os-breadcrumb__crumb:hover { color: var(--ink); }
.os-breadcrumb__crumb--current { color: var(--ink); font-weight: 600; }
.os-breadcrumb__sep { display: inline-flex; color: var(--muted-2); }
/* Phones: the full trail is noise — the last crumb is the current page, which
   just repeats the <h1> beneath it. Collapse to a single `‹ Parent` back-link
   (the immediate parent, tagged `--parent` by the partial). Chevron is a CSS
   corner so no extra markup. Desktop keeps the full trail. */
@media (max-width: 640px) {
  .os-breadcrumb__sep,
  .os-breadcrumb__crumb:not(.os-breadcrumb__crumb--parent) { display: none; }
  .os-breadcrumb__crumb--parent {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--muted);
    font-weight: 500;
  }
  .os-breadcrumb__crumb--parent::before {
    content: "";
    width: 7px;
    height: 7px;
    border-left: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    flex-shrink: 0;
  }
  /* v1.41.0 (os-ds #7): one back glyph on phones, the "‹" above. A crumb that
     brings its own leading icon (HotelOS renders an arrow-left) drops it here, so
     both products read "‹ Parent". Desktop keeps the product's icon. */
  .os-breadcrumb__crumb--parent > svg:first-child { display: none; }
  /* The parent link is the only way back on a phone, so it takes taps across
     48px (Fitts) while its text line keeps its 22px place. A transparent ::after
     centred on the line does it: no layout shift, and nothing above the text
     changes hands. The pad runs right only; to the left sits the shell
     hamburger. It stacks over the title line it overlaps. */
  .os-breadcrumb__crumb--parent { position: relative; z-index: 1; }
  .os-breadcrumb__crumb--parent::after {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: calc(100% + 12px);
    min-width: 48px;
    height: 48px;
    transform: translateY(-50%);
  }
}
/* ─────────────────────────────────────────────────────────────────────
   DiveOS chart card — .dv-chart-card

   Canonical panel for hand-rolled Chartkick chart containers (the
   `bg-surface border border-hairline rounded-lg shadow-card p-6` + an
   `<h3 class="text-lg ...">` pattern dotted around dashboards). White
   surface, 1px hairline, radius-lg, padding via the --space scale, and a
   head (title + optional actions) that flows into a body holding the
   chart canvas.

   Unlike .dv-card (eyebrow head, flush body), the chart card keeps a
   prominent --text-lg display title and a generous body min-height so the
   chart canvas has room before Chartkick measures it.

   Token-driven; @imported from application.css after components/card.css.
   ───────────────────────────────────────────────────────────────────── */
.os-chart-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
/* --raised : soft elevation for cards floating above the canvas. */
.os-chart-card--raised { box-shadow: var(--shadow-sm); }
/* Head — title (left) + optional actions (right). */
.os-chart-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.os-chart-card__title {
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-family: var(--font-display);
}
.os-chart-card__sub {
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--muted);
}
.os-chart-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
/* Body — holds the chart canvas. min-height keeps the panel from
   collapsing before Chartkick renders / when data is empty. */
.os-chart-card__body {
  min-height: 300px;
}
/* ─────────────────────────────────────────────────────────────────────
   .dv-share-card — copyable share-link card.

   A shareable URL chip + Copy/Open actions, an optional eyebrow title +
   leading icon + description, and an optional QR code (beside the link, or
   stacked below — collapsible for the booking rail). Promotes the four
   hand-rolled "copyable URL" cards (3 in Settings → Storefront, 1 in the
   bookings show rail) into one component. Rendered by
   shared/patterns/_share_link_card.html.erb.

   Token-only (var(--token)); no raw hex, no raw Tailwind palette. Loaded
   after card.css (see application.css).

   Anatomy:
     .dv-share-card                 outer (clipboard controller host)
       .dv-share-card__head         icon + eyebrow title row (optional)
       .dv-share-card__desc         .dv-meta description (optional)
       .dv-share-card__body         link chip + actions  (+ QR when horizontal)
         .dv-share-card__field      the mono URL chip
         .dv-share-card__actions    Copy / Open buttons
       .dv-share-card__qr           QR tile (beside or below)
       .dv-share-card__qr-cap       QR caption

   Modifiers:
     .dv-share-card--boxed          card chrome (border + padding + radius)
     .dv-share-card--sm / --lg      size (padding / gap step; md is the base)
     .dv-share-card--vertical       QR stacks BELOW the link row
     .dv-share-card--default        baseline emphasis (no extra rules)
     .dv-share-card--accent         accent-soft header BAND + prominent QR
     .dv-share-card--quiet          inline-field actions, minimal chrome
   ───────────────────────────────────────────────────────────────────── */
:is(.dv-share-card, .os-share-card) {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
  /* Query container so the horizontal QR-beside layout can stack based on the
     card's OWN width — it's used both full-width (storefront settings) and in a
     fixed ~336px rail (booking detail), so a viewport/pane query is wrong. */
  container-type: inline-size;
}
/* Boxed chrome — surface fill, hairline border, rounded-card, padded. */
:is(.dv-share-card--boxed, .os-share-card--boxed) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: 16px;
}
:is(.dv-share-card--boxed, .os-share-card--boxed):is(.dv-share-card--sm, .os-share-card--sm) { padding: 12px; }
:is(.dv-share-card--boxed, .os-share-card--boxed):is(.dv-share-card--lg, .os-share-card--lg) { padding: 20px; }
/* Head — leading icon + eyebrow title. */
:is(.dv-share-card__head, .os-share-card__head) {
  display: flex;
  align-items: center;
  gap: 8px;
}
:is(.dv-share-card__head, .os-share-card__head) svg, :is(.dv-share-card__head, .os-share-card__head) [data-lucide] { color: var(--accent); flex-shrink: 0; }
/* Description line. */
:is(.dv-share-card__desc, .os-share-card__desc) { margin-top: -2px; }
/* Body — link chip + actions (horizontal: QR sits beside via __layout). */
:is(.dv-share-card__body, .os-share-card__body) {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
/* URL chip — mono, on the quiet canvas surface, single line + ellipsis so a
   long URL never reflows to a tower of one-char-per-line in a narrow column
   (e.g. when a QR sits beside it). Matches the mockup's `truncate` field. */
:is(.dv-share-card__field, .os-share-card__field) {
  flex: 1 1 auto;
  min-width: 0;
  padding: 6px 10px;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is(.dv-share-card__actions, .os-share-card__actions) {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
/* QR tile — boxed crop on the canvas surface. */
:is(.dv-share-card__qr, .os-share-card__qr) {
  flex-shrink: 0;
  display: inline-block;
  padding: 8px;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  line-height: 0;
}
:is(.dv-share-card__qr, .os-share-card__qr) svg { display: block; }
:is(.dv-share-card__qr-cap, .os-share-card__qr-cap) { margin-top: 8px; text-align: center; }
/* QR + Download button, stacked. The button spans the tile width beneath it. */
.os-share-card__qr-group {
  display: inline-flex;
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
}
.os-share-card__qr-dl { justify-content: center; }
/* ── Horizontal layout (default) — QR beside the link + actions column ──
   The __layout wraps the QR + the (body + desc-less) text column side by
   side. We model it directly: when a QR is present and horizontal, the
   card uses a row with the QR first and a min-width:0 text column. */
:is(.dv-share-card__layout, .os-share-card__layout) {
  display: flex;
  align-items: center;   /* QR + its link/actions read as one balanced pair */
  gap: 16px;
  min-width: 0;
}
:is(.dv-share-card__layout, .os-share-card__layout) > :is(.dv-share-card__col, .os-share-card__col) {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* Narrow card: stack the QR above its text column so the description keeps a
   readable measure and the URL field + Copy button don't clip. */
@container (max-width: 400px) {
  :is(.dv-share-card__layout, .os-share-card__layout) { flex-direction: column; align-items: stretch; }
  :is(.dv-share-card__layout, .os-share-card__layout) > :is(.dv-share-card__qr, .os-share-card__qr, .os-share-card__qr-group) { align-self: flex-start; }
}
/* ── Vertical — QR stacks BELOW the link row (booking rail). The QR is a
   normal flex-column child, so no extra rule needed beyond alignment. */
:is(.dv-share-card--vertical, .os-share-card--vertical) :is(.dv-share-card__qr, .os-share-card__qr, .os-share-card__qr-group) { align-self: flex-start; }
/* Disclosure (collapsible QR) — accent summary, no marker, tidy spacing. */
:is(.dv-share-card__disclosure, .os-share-card__disclosure) { margin-top: 0; }
:is(.dv-share-card__disclosure, .os-share-card__disclosure) > summary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  list-style: none;
  cursor: pointer;
  color: var(--accent);
  font-size: var(--text-xs);
}
:is(.dv-share-card__disclosure, .os-share-card__disclosure) > summary::-webkit-details-marker { display: none; }
:is(.dv-share-card__disclosure, .os-share-card__disclosure) > summary:hover { color: var(--accent-strong); }
:is(.dv-share-card__disclosure, .os-share-card__disclosure) > summary svg { flex-shrink: 0; }
:is(.dv-share-card__disclosure, .os-share-card__disclosure)[open] > summary { margin-bottom: 12px; }
/* ══════════════════════ Emphasis: --accent (Direction C) ══════════════════
   Accent-soft header band flush to the card top + a padded content wrapper
   below it, a PRIMARY Copy CTA, and a prominent white QR tile. For share
   actions you want used on sight (booking-engine / walk-in flows). */
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--boxed, .os-share-card--boxed) {
  padding: 0;                 /* the band + __content own the padding */
  overflow: hidden;           /* clip the band to the card radius */
}
/* Header band — accent-soft fill, hairline underline, accent icon + eyebrow. */
:is(.dv-share-card--accent, .os-share-card--accent) :is(.dv-share-card__head, .os-share-card__head) {
  background: var(--accent-soft);
  border-bottom: 1px solid var(--hairline);
  padding: 10px 16px;
  margin: 0;
}
:is(.dv-share-card--accent, .os-share-card--accent) :is(.dv-share-card__head, .os-share-card__head) :is(.dv-eyebrow, .os-eyebrow) { color: var(--accent); }
/* Padded body wrapper below the band; owns the vertical rhythm. */
:is(.dv-share-card--accent, .os-share-card--accent) :is(.dv-share-card__content, .os-share-card__content) {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 16px;
  min-width: 0;
}
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--sm, .os-share-card--sm) :is(.dv-share-card__head, .os-share-card__head) { padding: 8px 12px; }
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--sm, .os-share-card--sm) :is(.dv-share-card__content, .os-share-card__content) { padding: 12px; }
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--lg, .os-share-card--lg) :is(.dv-share-card__head, .os-share-card__head) { padding: 12px 20px; }
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--lg, .os-share-card--lg) :is(.dv-share-card__content, .os-share-card__content) { padding: 20px; }
/* Prominent QR — raised white tile (vs the recessed canvas tile elsewhere).
   Cap the intrinsic QR SVG to a proportionate size so it pairs with the link
   column instead of towering over it (RQRCode renders at module_size px, which
   for a longer URL can exceed 180px). Vector QR stays crisp when scaled. */
:is(.dv-share-card--accent, .os-share-card--accent) :is(.dv-share-card__qr, .os-share-card__qr) {
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
/* Larger than the old 132px: the walk-in QR is scanned off a screen / print,
   so bigger modules read more reliably. The SVG carries a viewBox (qr_svg), so
   this scales the whole code — it never clips. */
:is(.dv-share-card--accent, .os-share-card--accent) :is(.dv-share-card__qr, .os-share-card__qr) svg {
  width: 168px;
  height: 168px;
}
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--sm, .os-share-card--sm) :is(.dv-share-card__qr, .os-share-card__qr) svg { width: 104px; height: 104px; }
:is(.dv-share-card--accent, .os-share-card--accent):is(.dv-share-card--lg, .os-share-card--lg) :is(.dv-share-card__qr, .os-share-card__qr) svg { width: 160px; height: 160px; }
/* ══════════════════════ Emphasis: --quiet (Direction A) ═══════════════════
   Minimal chrome — the Copy/Open actions live INSIDE the URL field as ghost
   buttons; the field is a single inline chip. QR stays in the disclosure.
   Disappears into dense rails. */
:is(.dv-share-card__field--inline, .os-share-card__field--inline) {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 4px 3px 10px;  /* tighter right pad — ghost buttons sit inside */
}
:is(.dv-share-card__url, .os-share-card__url) {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is(.dv-share-card--quiet, .os-share-card--quiet) :is(.dv-share-card__actions, .os-share-card__actions) { flex-shrink: 0; gap: 2px; }
/* Package-Builder (C8b) components: option card, vertical step rail, and the
   sidebar collapse / 64px icon-rail mode. Token-driven. */
/*
 * package_builder.css — Package-Builder (C8b) components.
 *
 * Three foundational pieces, grounded in DM's design system (tokens.css):
 *   1. .pkb-optcard  — selectable option card (single / multi select)
 *   2. .pkb-vrail    — vertical step rail (current / done / upcoming)
 *   3. .diveos-sidebar.is-collapsed — 64px icon-rail collapse mode
 *
 * Token-only. Durations use DM's --t-fast/--t-med/--t-slow; easing uses
 * --ease-out-quart. No raw hex, no --space-* (DM has no space scale → raw px).
 *
 * Source spec: Design/design_handoff_package_builder/components/*.md
 */
/* ─── 1. Option card ───────────────────────────────────────────────── */
:is(.pkb-stack, .os-pkb-stack) {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
:is(.pkb-optcard, .os-pkb-optcard) {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1.5px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: border-color var(--t-fast) ease,
              background var(--t-fast) ease,
              transform var(--t-fast) ease,
              box-shadow var(--t-fast) ease;
}
:is(.pkb-optcard, .os-pkb-optcard):hover {
  border-color: var(--accent-border);
  transform: translateY(-1px);
  box-shadow: var(--shadow-hover);
}
:is(.pkb-optcard, .os-pkb-optcard).is-on {
  border-color: var(--accent);
  background: var(--accent-softer);
}
:is(.pkb-optcard, .os-pkb-optcard):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
:is(.pkb-optcard__icon, .os-pkb-optcard__icon) {
  width: 44px;
  height: 44px;
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
:is(.pkb-optcard__body, .os-pkb-optcard__body) {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
:is(.pkb-optcard__title, .os-pkb-optcard__title) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.01em;
  color: var(--ink);
}
:is(.pkb-optcard__desc, .os-pkb-optcard__desc) {
  font-size: var(--text-sm);
  color: var(--muted);
  line-height: 1.4;
}
:is(.pkb-optcard__price, .os-pkb-optcard__price) {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
:is(.pkb-optcard, .os-pkb-optcard).is-on :is(.pkb-optcard__price, .os-pkb-optcard__price) { color: var(--accent); }
/* check indicator — round (single) / square (multi via --square) */
:is(.pkb-optcard__check, .os-pkb-optcard__check) {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--hairline-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  flex-shrink: 0;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease;
}
:is(.pkb-optcard__check--square, .os-pkb-optcard__check--square) { border-radius: var(--radius-sm); }
:is(.pkb-optcard, .os-pkb-optcard).is-on :is(.pkb-optcard__check, .os-pkb-optcard__check) {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--surface);
}
/* the check glyph is hidden until selected (color:transparent above) */
:is(.pkb-optcard__check, .os-pkb-optcard__check) svg { width: 14px; height: 14px; }
/* ─── 2. Vertical step rail ────────────────────────────────────────── */
:is(.pkb-vrail, .os-pkb-vrail) {
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
  position: sticky;
  top: 48px;
  align-self: start;
}
:is(.pkb-vrail__brand, .os-pkb-vrail__brand) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px 14px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.01em;
  color: var(--ink);
}
:is(.pkb-vrail__brand, .os-pkb-vrail__brand) :is(.pkb-vrail__brand-ic, .os-pkb-vrail__brand-ic) {
  color: var(--accent);
  display: flex;
  flex-shrink: 0;
}
:is(.pkb-vrail__steps, .os-pkb-vrail__steps) {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
:is(.pkb-vstep, .os-pkb-vstep) {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 12px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  text-align: left;
  color: var(--muted);
  cursor: default;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.pkb-vstep, .os-pkb-vstep)[disabled] { opacity: 0.55; cursor: not-allowed; }
/* the vertical bar (replaces a circle) */
:is(.pkb-vstep, .os-pkb-vstep) :is(.bar, .os-bar) {
  flex-shrink: 0;
  width: 3px;
  height: 16px;
  border-radius: var(--radius-pill);
  background: var(--hairline-strong);
  transition: background var(--t-fast) ease, height var(--t-fast) ease,
              box-shadow var(--t-fast) ease;
}
:is(.pkb-vstep, .os-pkb-vstep) :is(.lbrow, .os-lbrow) {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
:is(.pkb-vstep, .os-pkb-vstep) :is(.tk, .os-tk) {
  display: none;
  align-items: center;
  color: var(--accent);
  flex-shrink: 0;
}
:is(.pkb-vstep, .os-pkb-vstep) :is(.tk, .os-tk) svg { width: 15px; height: 15px; }
:is(.pkb-vstep, .os-pkb-vstep) :is(.lb, .os-lb) {
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* done — accent bar + check pip, tappable */
:is(.pkb-vstep, .os-pkb-vstep).is-done { color: var(--text-secondary); cursor: pointer; }
:is(.pkb-vstep, .os-pkb-vstep).is-done :is(.bar, .os-bar) { background: var(--accent); }
:is(.pkb-vstep, .os-pkb-vstep).is-done :is(.tk, .os-tk) { display: flex; }
/* nav (any reachable, non-current step) — gray hover affordance */
:is(.pkb-vstep, .os-pkb-vstep).is-nav { cursor: pointer; }
:is(.pkb-vstep, .os-pkb-vstep).is-nav:hover { background: var(--gray-100); }
:is(.pkb-vstep, .os-pkb-vstep).is-nav:hover :is(.bar, .os-bar) { background: var(--accent); }
/* on — accent-soft pill, raised halo'd bar, leading dot, bold accent label */
:is(.pkb-vstep, .os-pkb-vstep).is-on {
  background: var(--accent-soft);
  color: var(--accent);
  cursor: default;
}
:is(.pkb-vstep, .os-pkb-vstep).is-on :is(.bar, .os-bar) {
  height: 20px;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
:is(.pkb-vstep, .os-pkb-vstep).is-on :is(.lb, .os-lb) { font-weight: 600; }
/* leading dot for the current step */
:is(.pkb-vstep, .os-pkb-vstep).is-on :is(.lbrow, .os-lbrow)::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  flex-shrink: 0;
}
:is(.pkb-vstep, .os-pkb-vstep):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
:is(.pkb-vrail__count, .os-pkb-vrail__count) {
  margin-top: 14px;
  padding: 0 12px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--muted);
}
/* ─── 4. Price slider (.pkb-slider) ────────────────────────────────────
   A native <input type="range"> owns value + keyboard a11y; the visible
   track/fill/thumb are positioned by the pkb-slider Stimulus controller,
   which snaps to 5%. Token-only; webkit + moz thumb/track zeroed so only
   our custom visuals show. */
:is(.pkb-slider, .os-pkb-slider) {
  position: relative;
  height: 24px;
  margin: 6px 0;
  display: flex;
  align-items: center;
}
/* the real range input — full-bleed, invisible, drives the value */
:is(.pkb-slider__input, .os-pkb-slider__input) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
       appearance: none;
  z-index: 2;
}
:is(.pkb-slider__input, .os-pkb-slider__input):focus { outline: none; }
:is(.pkb-slider__input, .os-pkb-slider__input)::-webkit-slider-runnable-track {
  -webkit-appearance: none;
  appearance: none;
  height: 100%;
  background: transparent;
}
:is(.pkb-slider__input, .os-pkb-slider__input)::-moz-range-track { height: 100%; background: transparent; }
/* the native thumb is invisible but full-height so the whole bar is grabbable */
:is(.pkb-slider__input, .os-pkb-slider__input)::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
}
:is(.pkb-slider__input, .os-pkb-slider__input)::-moz-range-thumb {
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
}
/* visible track (full, gray) */
:is(.pkb-slider__track, .os-pkb-slider__track) {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--hairline-strong);
  pointer-events: none;
}
/* accent fill (cost → current value) */
:is(.pkb-slider__fill, .os-pkb-slider__fill) {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 6px;
  width: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  pointer-events: none;
}
/* draggable-looking thumb (positioned by JS via left:%) */
:is(.pkb-slider__thumb, .os-pkb-slider__thumb) {
  position: absolute;
  top: 50%;
  left: 0;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 2.5px solid var(--accent);
  box-shadow: var(--shadow-sm);
  transform: translate(-50%, -50%);
  pointer-events: none;
  transition: box-shadow var(--t-fast) ease;
}
:is(.pkb-slider__thumb, .os-pkb-slider__thumb)::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: var(--radius-pill);
  background: var(--accent);
}
:is(.pkb-slider, .os-pkb-slider):hover :is(.pkb-slider__thumb, .os-pkb-slider__thumb) {
  box-shadow: 0 0 0 6px var(--accent-soft), var(--shadow-sm);
}
:is(.pkb-slider__input, .os-pkb-slider__input):focus-visible ~ :is(.pkb-slider__thumb, .os-pkb-slider__thumb) {
  box-shadow: 0 0 0 3px var(--focus-ring), var(--shadow-sm);
}
/* ─── 5. Pill group (.pkb-pillgroup) ───────────────────────────────────
   Single-select row of pills, radio-backed (native, no JS) like the
   _segmented field. Active = accent-soft bg + accent text + accent border,
   resolved via :has() on the checked radio. */
:is(.pkb-pillgroup, .os-pkb-pillgroup) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
:is(.pkb-pill, .os-pkb-pill) {
  display: inline-flex;
  align-items: center;
  padding: 8px 15px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--gray-700);
  background: var(--surface);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease,
              color var(--t-fast) ease;
}
:is(.pkb-pill, .os-pkb-pill):hover { border-color: var(--accent-border); }
/* visually-hidden radio (kept focusable for a11y) */
:is(.pkb-pill__radio, .os-pkb-pill__radio) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* active state */
:is(.pkb-pill, .os-pkb-pill):has(:is(.pkb-pill__radio, .os-pkb-pill__radio):checked) {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: var(--accent);
  font-weight: 600;
}
:is(.pkb-pill, .os-pkb-pill):has(:is(.pkb-pill__radio, .os-pkb-pill__radio):focus-visible) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
/* ─── 6. Round checkbox (.diveos-checkbox--round) ──────────────────────
   ROUND variant of DM's square .diveos-checkbox. Native input + CSS only;
   checked = accent fill + white check glyph. The square checkbox is reused
   as-is (this only adds the circular shape + accent-fill treatment). */
:is(.diveos-checkbox--round, .os-checkbox--round) {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}
/* visually-hidden native input (focusable, not display:none) */
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__input, .os-pkb-checkbox__input) {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__box, .os-pkb-checkbox__box) {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--hairline-strong);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  flex-shrink: 0;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease;
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__box, .os-pkb-checkbox__box) svg { width: 14px; height: 14px; }
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__input, .os-pkb-checkbox__input):checked + :is(.pkb-checkbox__box, .os-pkb-checkbox__box) {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--surface);
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__input, .os-pkb-checkbox__input):focus-visible + :is(.pkb-checkbox__box, .os-pkb-checkbox__box) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__label, .os-pkb-checkbox__label) {
  font-size: var(--text-sm);
  color: var(--ink);
}
/* ─── 4. Price slider (.pkb-slider) ────────────────────────────────────
   A native <input type="range"> owns value + keyboard a11y; the visible
   track/fill/thumb are positioned by the pkb-slider Stimulus controller,
   which snaps to 5%. Token-only; webkit + moz thumb/track zeroed so only
   our custom visuals show. */
:is(.pkb-slider, .os-pkb-slider) {
  position: relative;
  height: 24px;
  margin: 6px 0;
  display: flex;
  align-items: center;
}
/* the real range input — full-bleed, invisible, drives the value */
:is(.pkb-slider__input, .os-pkb-slider__input) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
       appearance: none;
  z-index: 2;
}
:is(.pkb-slider__input, .os-pkb-slider__input):focus { outline: none; }
:is(.pkb-slider__input, .os-pkb-slider__input)::-webkit-slider-runnable-track {
  -webkit-appearance: none;
  appearance: none;
  height: 100%;
  background: transparent;
}
:is(.pkb-slider__input, .os-pkb-slider__input)::-moz-range-track { height: 100%; background: transparent; }
/* the native thumb is invisible but full-height so the whole bar is grabbable */
:is(.pkb-slider__input, .os-pkb-slider__input)::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
}
:is(.pkb-slider__input, .os-pkb-slider__input)::-moz-range-thumb {
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
}
/* visible track (full, gray) */
:is(.pkb-slider__track, .os-pkb-slider__track) {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--hairline-strong);
  pointer-events: none;
}
/* accent fill (cost → current value) */
:is(.pkb-slider__fill, .os-pkb-slider__fill) {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 6px;
  width: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  pointer-events: none;
}
/* draggable-looking thumb (positioned by JS via left:%) */
:is(.pkb-slider__thumb, .os-pkb-slider__thumb) {
  position: absolute;
  top: 50%;
  left: 0;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 2.5px solid var(--accent);
  box-shadow: var(--shadow-sm);
  transform: translate(-50%, -50%);
  pointer-events: none;
  transition: box-shadow var(--t-fast) ease;
}
:is(.pkb-slider__thumb, .os-pkb-slider__thumb)::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: var(--radius-pill);
  background: var(--accent);
}
:is(.pkb-slider, .os-pkb-slider):hover :is(.pkb-slider__thumb, .os-pkb-slider__thumb) {
  box-shadow: 0 0 0 6px var(--accent-soft), var(--shadow-sm);
}
:is(.pkb-slider__input, .os-pkb-slider__input):focus-visible ~ :is(.pkb-slider__thumb, .os-pkb-slider__thumb) {
  box-shadow: 0 0 0 3px var(--focus-ring), var(--shadow-sm);
}
/* ─── 5. Pill group (.pkb-pillgroup) ───────────────────────────────────
   Single-select row of pills, radio-backed (native, no JS) like the
   _segmented field. Active = accent-soft bg + accent text + accent border,
   resolved via :has() on the checked radio. */
:is(.pkb-pillgroup, .os-pkb-pillgroup) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
:is(.pkb-pill, .os-pkb-pill) {
  display: inline-flex;
  align-items: center;
  padding: 8px 15px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--gray-700);
  background: var(--surface);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease,
              color var(--t-fast) ease;
}
:is(.pkb-pill, .os-pkb-pill):hover { border-color: var(--accent-border); }
/* visually-hidden radio (kept focusable for a11y) */
:is(.pkb-pill__radio, .os-pkb-pill__radio) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* active state */
:is(.pkb-pill, .os-pkb-pill):has(:is(.pkb-pill__radio, .os-pkb-pill__radio):checked) {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: var(--accent);
  font-weight: 600;
}
:is(.pkb-pill, .os-pkb-pill):has(:is(.pkb-pill__radio, .os-pkb-pill__radio):focus-visible) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
/* ─── 6. Round checkbox (.diveos-checkbox--round) ──────────────────────
   ROUND variant of DM's square .diveos-checkbox. Native input + CSS only;
   checked = accent fill + white check glyph. The square checkbox is reused
   as-is (this only adds the circular shape + accent-fill treatment). */
:is(.diveos-checkbox--round, .os-checkbox--round) {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}
/* visually-hidden native input (focusable, not display:none) */
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__input, .os-pkb-checkbox__input) {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__box, .os-pkb-checkbox__box) {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--hairline-strong);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  flex-shrink: 0;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease;
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__box, .os-pkb-checkbox__box) svg { width: 14px; height: 14px; }
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__input, .os-pkb-checkbox__input):checked + :is(.pkb-checkbox__box, .os-pkb-checkbox__box) {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--surface);
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__input, .os-pkb-checkbox__input):focus-visible + :is(.pkb-checkbox__box, .os-pkb-checkbox__box) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
:is(.diveos-checkbox--round, .os-checkbox--round) :is(.pkb-checkbox__label, .os-pkb-checkbox__label) {
  font-size: var(--text-sm);
  color: var(--ink);
}
/* ─── 7. Guided builder layout (C8b shell) ─────────────────────────────
   Three zones inside the app content area: left vertical step rail (236px),
   centered conversational column (max 660px), right live-summary rail
   (296px). A sticky footer spans the full width. Spec: flow-c8b.md.
   The app sidebar is collapsed on entry (see §3). Token-only. */
/* full-bleed: the wizard layout removes the centered 1280px content cap so the
   three-zone grid spans the whole main pane (rail hard-left, summary hard-right) */
:is(.diveos-content--full, .os-content--full) {
  max-width: none;
  margin-inline: 0;
  padding: 0;
}
:is(.pkb-guided, .os-pkb-guided) {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 1px);
  background: var(--canvas);
}
:is(.pkb-guided__grid, .os-pkb-guided__grid) {
  flex: 1;
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr) 296px;
  gap: 56px;
  padding: 48px 56px 56px;
  align-items: start;
}
/* center conversational column — centered, capped at 660px */
:is(.pkb-guided__center, .os-pkb-guided__center) {
  min-width: 0;
  display: flex;
  justify-content: center;
}
:is(.pkb-guided-inner, .os-pkb-guided-inner) {
  width: 100%;
  max-width: 660px;
  text-align: center;
}
/* shared step chrome */
:is(.pkb-guided, .os-pkb-guided) :is(.step-eyebrow, .os-step-eyebrow) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--accent);
  margin-bottom: 14px;
}
:is(.pkb-guided-q, .os-pkb-guided-q) {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.12;
  color: var(--ink);
  margin: 0;
}
:is(.pkb-guided-help, .os-pkb-guided-help) {
  margin-top: 14px;
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--muted);
}
/* step bodies sit left-aligned within the centered column */
:is(.pkb-guided-body, .os-pkb-guided-body) {
  margin-top: 32px;
  text-align: left;
}
/* centered variant — for short single-decision bodies (pills, big field) that
   should sit under the centered question rather than left-aligned */
:is(.pkb-guided-body--center, .os-pkb-guided-body--center) {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
:is(.pkb-guided-body--center, .os-pkb-guided-body--center) :is(.pkb-pillgroup, .os-pkb-pillgroup) { justify-content: center; }
/* big underline field (Name step) */
:is(.pkb-bigfield, .os-pkb-bigfield) {
  margin-top: 32px;
}
:is(.pkb-bigfield__input, .os-pkb-bigfield__input) {
  display: block;
  width: 100%;
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--hairline);
  border-radius: 0;
  padding: 10px 0;
  transition: border-color var(--t-fast) ease;
}
:is(.pkb-bigfield__input, .os-pkb-bigfield__input)::-moz-placeholder { color: var(--input-placeholder); }
:is(.pkb-bigfield__input, .os-pkb-bigfield__input)::placeholder { color: var(--input-placeholder); }
:is(.pkb-bigfield__input, .os-pkb-bigfield__input):focus {
  outline: none;
  border-bottom-color: var(--accent);
}
/* inline header row (e.g. duration/pax on the Dives step) */
:is(.pkb-inline-row, .os-pkb-inline-row) {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 20px;
  padding-bottom: 22px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--hairline);
}
:is(.pkb-inline-field, .os-pkb-inline-field) {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
:is(.pkb-inline-field__label, .os-pkb-inline-field__label) {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}
:is(.pkb-inline-field__control, .os-pkb-inline-field__control) {
  display: flex;
  align-items: center;
  gap: 8px;
}
:is(.pkb-num, .os-pkb-num) {
  width: 64px;
  padding: 7px 10px;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink);
  background: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
:is(.pkb-num, .os-pkb-num):focus {
  outline: none;
  border-color: var(--input-border-focus);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
:is(.pkb-inline-field__suffix, .os-pkb-inline-field__suffix) { font-size: var(--text-sm); color: var(--muted); }
/* native toggle (flexible duration) */
:is(.pkb-toggle, .os-pkb-toggle) { position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
:is(.pkb-toggle__input, .os-pkb-toggle__input) { position: absolute; opacity: 0; width: 0; height: 0; }
:is(.pkb-toggle__track, .os-pkb-toggle__track) {
  position: relative;
  width: 36px;
  height: 20px;
  border-radius: var(--radius-pill);
  background: var(--hairline-strong);
  transition: background var(--t-fast) ease;
  flex-shrink: 0;
}
:is(.pkb-toggle__track, .os-pkb-toggle__track)::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-fast) ease;
}
:is(.pkb-toggle__input, .os-pkb-toggle__input):checked + :is(.pkb-toggle__track, .os-pkb-toggle__track) { background: var(--accent); }
:is(.pkb-toggle__input, .os-pkb-toggle__input):checked + :is(.pkb-toggle__track, .os-pkb-toggle__track)::after { transform: translateX(16px); }
:is(.pkb-toggle__input, .os-pkb-toggle__input):focus-visible + :is(.pkb-toggle__track, .os-pkb-toggle__track) { box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.pkb-toggle__state, .os-pkb-toggle__state) { font-size: var(--text-sm); color: var(--muted); }
/* review ledger (Review step) */
:is(.pkb-guided-review, .os-pkb-guided-review) {
  /* matches the DS card stroke (.bk-detail .balance-card): border-only, no
     shadow, radius-lg, clipped corners. Centered within the review column. */
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  max-width: 560px;
  margin-inline: auto;
}
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 22px;
  border-top: 1px solid var(--hairline-2);
}
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr):first-child { border-top: 0; }
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) :is(.ic, .os-ic) { color: var(--accent); display: flex; flex-shrink: 0; }
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) :is(.k, .os-k) { flex: 1; min-width: 0; color: var(--muted); font-size: var(--text-sm); }
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) :is(.v, .os-v) { color: var(--ink); font-size: var(--text-sm); font-weight: 500; text-align: right; }
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) :is(.v, .os-v):is(.mono, .os-mono) { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) :is(.v, .os-v).is-profit { color: var(--confirmed); font-weight: 700; }
/* component-summary row: small uppercase category tag before the item name */
:is(.pkb-guided-review, .os-pkb-guided-review) :is(.rr, .os-rr) :is(.rr-cat, .os-rr-cat) {
  font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted-2);
  margin-right: 8px;
}
/* count chip (multi-select steps) */
:is(.pkb-guided-count, .os-pkb-guided-count) {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 18px;
  padding: 6px 14px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-pill);
}
/* Action bar (#637) — the os-ds pinned wizard footer (`.os-wz-foot--pinned`,
   wizard/_wizard_footer): fixed to the viewport bottom at every width, one
   row on phones. On desktop the band starts after the sidebar instead of
   running under it (240px open, 64px collapsed, gliding with the rail; below
   1024px the sidebar is an overlay drawer, so the band is full width), and its
   buttons keep the old 40px gutter. The .os-shell prefix outweighs os-ds's own
   `inset` (wizard-footer.css loads after this file). */
:is(.pkb-guided, .os-pkb-guided) { --os-wz-foot-gutter: var(--space-4); }
@media (min-width: 641px) { :is(.pkb-guided, .os-pkb-guided) { --os-wz-foot-gutter: var(--space-6); } }
@media (min-width: 1024px) {
  :is(.pkb-guided, .os-pkb-guided) { --os-wz-foot-gutter: var(--space-10); }
  .os-shell :is(.pkb-guided, .os-pkb-guided) .os-wz-foot--pinned .os-wz-foot-inner {
    left: var(--sidebar-w);
    transition: left var(--t-slow) var(--ease-out-quart);
  }
  .os-shell.is-rail-collapsed :is(.pkb-guided, .os-pkb-guided) .os-wz-foot--pinned .os-wz-foot-inner { left: var(--space-16); }
}
/* The controller hides Back / Continue / the Review primary / Save with the
   hidden attribute; .os-btn's display:inline-flex would otherwise win. */
:is(.pkb-guided, .os-pkb-guided) .os-wz-foot .os-btn[hidden] { display: none; }
/* App-bar + segmented progress (#637). Below 1024px the staff shell floats its
   menu button over the page; the builder is a focused flow there (as the
   staff new-booking wizard), so the button goes and the bar names the package
   and step, with Cancel as the way out. The bar is the app's .dv-wizm-bar
   (wizard-mobile.css styles it at ≤640px); the rules here extend it to the
   tablet band. The bars strip shows once the left step rail drops (≤820px). */
:is(.pkb-wzbar, .os-pkb-wzbar) { display: none; }
@media (max-width: 1023px) {
  body:has(.pkb-guided) :is(.diveos-hamburger, .os-hamburger) { display: none; }
  :is(.pkb-wzbar, .os-pkb-wzbar) {
    display: block;
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--surface);
    border-bottom: 1px solid var(--hairline);
  }
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: calc(env(safe-area-inset-top) + var(--space-3)) var(--space-6) var(--space-3);
    background: var(--surface);
  }
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar__ttl { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar__ttl .t {
    font-family: var(--font-display); font-size: var(--text-md); font-weight: 600;
    letter-spacing: -0.01em; color: var(--ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar__ttl .s {
    font-size: var(--text-xs); font-weight: 500; color: var(--muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* A 48px touch target for the only way out of the flow. */
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar__cancel {
    margin-left: auto; flex: 0 0 auto;
    display: inline-flex; align-items: center; min-height: var(--control-h-touch); padding: 0 var(--space-2);
    font-size: var(--text-sm); font-weight: 600; color: var(--muted); text-decoration: none; white-space: nowrap;
  }
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar__cancel:hover { color: var(--ink); }
  :is(.pkb-wzbar, .os-pkb-wzbar) .wz-couple { display: none; }
  /* The footer's Cancel duplicates the bar's. */
  :is(.pkb-guided, .os-pkb-guided) .os-wz-foot .pkb-foot-cancel { display: none; }
}
@media (max-width: 820px) {
  :is(.pkb-wzbar, .os-pkb-wzbar) .wz-couple { display: block; padding: 0 var(--space-6) var(--space-3); }
  :is(.pkb-wzbar, .os-pkb-wzbar) .wz-bars-inner { gap: 6px; }
  /* Bars only: the app-bar's step line names the step. */
  :is(.pkb-wzbar, .os-pkb-wzbar) .wz-seg .lbrow { display: none; }
  :is(.pkb-wzbar, .os-pkb-wzbar) .wz-seg { padding: 7px 0; gap: 0; }
}
@media (max-width: 640px) {
  :is(.pkb-wzbar, .os-pkb-wzbar) .dv-wizm-bar { padding-inline: var(--space-4); }
  :is(.pkb-wzbar, .os-pkb-wzbar) .wz-couple { padding-inline: var(--space-4); }
  /* os-ds centres the footer's quiet actions via the end zone's first child;
     here that is the (hidden) Cancel, so Save takes the auto margin. */
  :is(.pkb-guided, .os-pkb-guided) .os-wz-foot--pinned .os-grp.os-end > .pkb-foot-cancel + .os-btn { margin-left: auto; }
}
/* summary rail (right, 296px) — package roll-up + economics */
:is(.pkb-summary, .os-pkb-summary) {
  position: sticky;
  top: 48px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
/* (.pkb-summary__card retired by #493 — the rail cards are .os-card.) */
/* section header: uppercase mono eyebrow + optional status pill */
:is(.pkb-summary__head, .os-pkb-summary__head) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
:is(.pkb-summary__eyebrow, .os-pkb-summary__eyebrow) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted-2);
}
:is(.pkb-summary__draftpill, .os-pkb-summary__draftpill) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--muted);
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  padding: 2px 8px;
}
/* icon roll-up line: soft accent tile · two-line label · trailing value */
:is(.pkb-summary__line, .os-pkb-summary__line) {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
}
:is(.pkb-summary__line, .os-pkb-summary__line) + :is(.pkb-summary__line, .os-pkb-summary__line) { border-top: 1px solid var(--hairline-2); }
:is(.pkb-summary__line-ic, .os-pkb-summary__line-ic) {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
}
:is(.pkb-summary__line-ic, .os-pkb-summary__line-ic) svg { width: 17px; height: 17px; }
:is(.pkb-summary__line-body, .os-pkb-summary__line-body) { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
:is(.pkb-summary__line-main, .os-pkb-summary__line-main) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.pkb-summary__line-sub, .os-pkb-summary__line-sub) { font-size: var(--text-xs); color: var(--muted); }
:is(.pkb-summary__line-val, .os-pkb-summary__line-val) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
/* SELLING PRICE block — accent-soft, sits at the foot of the roll-up card */
:is(.pkb-summary__sell, .os-pkb-summary__sell) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 14px -18px -16px;
  padding: 14px 18px;
  background: var(--accent-soft);
  border-top: 1px solid var(--accent-border);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
:is(.pkb-summary__sell, .os-pkb-summary__sell) :is(.pkb-summary__eyebrow, .os-pkb-summary__eyebrow) { color: var(--accent); }
:is(.pkb-summary__sell-v, .os-pkb-summary__sell-v) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-xl);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
}
/* economics rows */
:is(.pkb-summary__row, .os-pkb-summary__row) {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  font-size: var(--text-sm);
}
:is(.pkb-summary__row, .os-pkb-summary__row) :is(.k, .os-k) { color: var(--muted); }
:is(.pkb-summary__row, .os-pkb-summary__row) :is(.v, .os-v) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  font-weight: 600;
  text-align: right;
}
:is(.pkb-summary__row--accent, .os-pkb-summary__row--accent) :is(.v, .os-v) { color: var(--accent); }
:is(.pkb-summary__divider, .os-pkb-summary__divider) { height: 1px; background: var(--hairline-2); margin: 6px 0; }
/* responsive: drop the summary rail, then the step rail, on narrow viewports */
@media (max-width: 1180px) {
  :is(.pkb-guided__grid, .os-pkb-guided__grid) { grid-template-columns: 200px minmax(0, 1fr); gap: 40px; }
  :is(.pkb-summary, .os-pkb-summary) { display: none; }
}
@media (max-width: 820px) {
  :is(.pkb-guided__grid, .os-pkb-guided__grid) { grid-template-columns: minmax(0, 1fr); padding: 28px 24px 40px; }
  :is(.pkb-guided, .os-pkb-guided) :is(.pkb-vrail, .os-pkb-vrail) { display: none; }
}
/* The C8b pricer (.pkb-pricer / .pkb-pricefield / .pkb-recbtn / .pkb-quickbtn /
   .pkb-guided-marginchip) was retired by packages-v2 Phase 2.3: the Price step
   is the group-size tier grid (os-table + currency-input). .pkb-slider stays for
   the design-system showcase. */
/* ─── 9. Dives catalogue picker (Dives step) ───────────────────────────
   Spec: components/dive-catalogue.md. dv2-/dv- prefixed (bare .row/.chip/.meta
   collide with global app CSS). Token-only. */
/* widen + left-align the centered column for the picker (set by the wizard
   controller when the shown step opts in via data-wide) */
:is(.pkb-guided-inner, .os-pkb-guided-inner).has-picker { max-width: 720px; text-align: left; }
:is(.pkb-guided-inner, .os-pkb-guided-inner).has-picker :is(.step-eyebrow, .os-step-eyebrow), :is(.pkb-guided-inner, .os-pkb-guided-inner).has-picker :is(.pkb-guided-q, .os-pkb-guided-q), :is(.pkb-guided-inner, .os-pkb-guided-inner).has-picker :is(.pkb-guided-help, .os-pkb-guided-help) { text-align: center; }
/* duration toolbar — exact to "Duration Toolbar - Spec (standalone)".
   One content-width container, cells split by a light (--hairline-2) divider;
   Fixed/Flexible pill toggle; − [value] + steppers with a .val display span. */
:is(.dv-durbar, .os-durbar) {
  display: flex;
  width: -moz-fit-content;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto 28px;
  align-items: stretch;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-family: var(--font-sans);
}
:is(.dv-cseg, .os-cseg) {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 18px;
  border-left: 1px solid var(--hairline-2);
}
:is(.dv-cseg, .os-cseg):first-child { border-left: 0; padding-left: 20px; }
:is(.dv-cseg, .os-cseg):last-child { padding-right: 20px; }
:is(.dv-cseg, .os-cseg)[hidden] { display: none; }
/* #637 — narrow widths: the one-row bar clipped (Duration's + at 375,
   Location at 768). The cells wrap into a full-width grid instead, Length on
   a row of its own; each cell draws its top and left divider outside itself
   and the bar clips the ones on its outer edge. */
@media (max-width: 820px) {
  :is(.dv-durbar, .os-durbar) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(calc(var(--space-12) * 3), 1fr));
    width: 100%;
  }
  :is(.dv-cseg, .os-cseg) { border-left: 0; padding: 14px 16px; box-shadow: -1px -1px 0 var(--hairline-2); }
  :is(.dv-cseg, .os-cseg):first-child { grid-column: 1 / -1; padding-left: var(--space-4); }
  :is(.dv-cseg, .os-cseg):last-child { padding-right: var(--space-4); }
  :is(.dv-cseg, .os-cseg) > :is(.dv-segtog, .os-segtog) { align-self: flex-start; }
  :is(.dv-cseg, .os-cseg) :is(.dv-gearpick__select, .os-gearpick__select) { width: 100%; min-width: 0; }
}
:is(.dv-clabel, .os-clabel) {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
}
/* Fixed/Flexible segmented toggle — pill */
:is(.dv-segtog, .os-segtog) {
  display: inline-flex;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
:is(.dv-segtog, .os-segtog) button {
  height: 32px;
  padding: 0 14px;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--muted);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.dv-segtog, .os-segtog) button:is(.on, .os-on) {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}
/* − [value] + stepper */
:is(.dv-cstep, .os-cstep) { display: inline-flex; align-items: center; gap: 1rem; }
:is(.dv-cstep, .os-cstep) button {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--muted-2);
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--t-fast) ease, border-color var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.dv-cstep, .os-cstep) button:hover:not(:disabled) { background: var(--surface-alt); border-color: var(--accent-border); color: var(--ink); }
:is(.dv-cstep, .os-cstep) button:disabled { opacity: 0.5; cursor: default; }
:is(.dv-cstep, .os-cstep) :is(.val, .os-val) {
  min-width: 2.5rem;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--ink);
}
:is(.dv-cstep, .os-cstep) :is(.val, .os-val) :is(.un, .os-un) {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--muted);
  margin-left: 3px;
}
:is(.pkb-stepper__unit, .os-pkb-stepper__unit) { font-size: var(--text-xs); color: var(--muted); }
/* picker controls */
:is(.dv2-pick, .os-dv2-pick) { text-align: left; margin-top: 8px; }
:is(.dv2-results, .os-dv2-results) { margin-top: 18px; }
:is(.dv2-seg, .os-dv2-seg) {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  margin-bottom: 12px;
  overflow-x: auto;
}
:is(.dv2-seg-btn, .os-dv2-seg-btn) {
  flex: 1;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 14px;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--muted);
  background: transparent;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
:is(.dv2-seg-btn, .os-dv2-seg-btn) :is(.c, .os-c) { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; opacity: 0.8; }
:is(.dv2-seg-btn, .os-dv2-seg-btn).is-on { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-sm); }
:is(.dv2-seg-btn, .os-dv2-seg-btn).is-on :is(.c, .os-c) { color: var(--accent); opacity: 1; }
:is(.dv-search, .os-search) {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 42px;
  padding: 0 14px;
  background: var(--surface);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
}
:is(.dv-search, .os-search):focus-within { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.dv-search, .os-search) :is(.ico, .os-ico) { color: var(--muted-2); display: flex; flex-shrink: 0; }
:is(.dv-search, .os-search) input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; font: inherit; font-size: var(--text-sm); color: var(--ink); }
:is(.dv-search, .os-search) input::-moz-placeholder { color: var(--muted-2); }
:is(.dv-search, .os-search) input::placeholder { color: var(--muted-2); }
:is(.dv-search, .os-search) :is(.clr, .os-clr) {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border: 0; border-radius: var(--radius-pill);
  background: var(--gray-100); color: var(--muted); cursor: pointer; flex-shrink: 0;
}
:is(.dv-search, .os-search) :is(.clr, .os-clr):hover { background: var(--gray-200); color: var(--ink); }
/* group label */
:is(.dv-grouplabel, .os-grouplabel) { display: flex; align-items: center; gap: 9px; margin: 38px 2px 12px; }
/* only the very first group's label is flush — every later group keeps its
   top margin so sections are clearly separated (NOT :first-child, which would
   match every group's label since each is first inside its own group div). */
:is(.dv2-results, .os-dv2-results) > [data-dv-group]:first-child :is(.dv-grouplabel, .os-grouplabel) { margin-top: 0; }
:is(.dv-grouplabel, .os-grouplabel) :is(.t, .os-t) { font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
:is(.dv-grouplabel, .os-grouplabel) :is(.ln, .os-ln) { flex: 1; height: 1px; background: var(--hairline-2); }
:is(.dv-grouplabel, .os-grouplabel) :is(.c, .os-c) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); }
/* dense selectable row */
:is(.dv-rows, .os-rows) { display: flex; flex-direction: column; gap: 6px; }
:is(.dv-row, .os-row) {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 14px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: left;
  transition: border-color var(--t-fast) ease, background var(--t-fast) ease;
}
:is(.dv-row, .os-row):hover { border-color: var(--accent-border); }
:is(.dv-row, .os-row).is-on { border-color: var(--accent); background: var(--accent-softer); }
:is(.dv-row, .os-row):focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
:is(.dv-row, .os-row) :is(.box, .os-box) {
  width: 20px; height: 20px; border-radius: 6px; flex-shrink: 0;
  border: 1.5px solid var(--hairline-strong); background: var(--surface);
  display: flex; align-items: center; justify-content: center; color: transparent;
}
:is(.dv-row, .os-row).is-on :is(.box, .os-box) { background: var(--accent); border-color: var(--accent); color: var(--surface); }
:is(.dv-row, .os-row) :is(.dv-main, .os-main) { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
:is(.dv-row, .os-row) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.dv-row, .os-row) :is(.meta, .os-meta) { font-size: var(--text-xs); color: var(--muted); line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.dv-row, .os-row) :is(.pr, .os-pr) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--ink); white-space: nowrap; flex-shrink: 0; }
:is(.dv-row, .os-row).is-on :is(.pr, .os-pr) { color: var(--accent); }
/* qty stepper (replaces price on selected rows) */
:is(.dv-step, .os-step) { display: inline-flex; align-items: center; border: 1px solid var(--hairline); border-radius: var(--radius-sm); background: var(--surface); overflow: hidden; flex-shrink: 0; }
:is(.dv-step, .os-step) button { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; border: 0; background: transparent; color: var(--gray-700); cursor: pointer; }
:is(.dv-step, .os-step) button:hover { background: var(--surface-alt); color: var(--ink); }
:is(.dv-step, .os-step) button:disabled { color: var(--muted-2); cursor: default; background: transparent; }
:is(.dv-step, .os-step) :is(.v, .os-v) { min-width: 26px; text-align: center; font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; color: var(--ink); }
/* equipment: note + grouped chips */
:is(.dv-kitnote, .os-kitnote) {
  display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; margin-bottom: 16px;
  background: var(--accent-softer); border: 1px solid var(--accent-border); border-radius: var(--radius-sm);
  font-size: var(--text-sm); color: var(--gray-700); line-height: 1.5;
}
:is(.dv-kitnote, .os-kitnote) :is(.ico, .os-ico) { color: var(--accent); flex-shrink: 0; margin-top: 1px; }
:is(.dv-kitnote, .os-kitnote) b { color: var(--ink); font-weight: 600; }
:is(.dv-kitgroup, .os-kitgroup) { margin-bottom: 18px; }
:is(.dv-chips, .os-chips) { display: flex; flex-wrap: wrap; gap: 8px; }
:is(.dv-chip, .os-chip) {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 13px;
  font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--gray-700);
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-pill);
  cursor: pointer; transition: border-color var(--t-fast) ease, background var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.dv-chip, .os-chip):hover { border-color: var(--accent-border); }
:is(.dv-chip, .os-chip) :is(.tk, .os-tk) {
  width: 15px; height: 15px; border-radius: var(--radius-pill); flex-shrink: 0;
  border: 1.5px solid var(--hairline-strong); display: flex; align-items: center; justify-content: center; color: transparent;
}
/* .qr-form (storefront quote request): the checked input lights the chip, no JS. */
:is(.dv-chip, .os-chip).is-on, .qr-form .os-chip:has(> input:checked) { color: var(--accent); background: var(--accent-soft); border-color: var(--accent); font-weight: 600; }
:is(.dv-chip, .os-chip).is-on :is(.tk, .os-tk), .qr-form .os-chip:has(> input:checked) :is(.tk, .os-tk) { background: var(--accent); border-color: var(--accent); color: var(--surface); }
/* gear CATEGORY builder (#224) — billing-free gear lines with an internal
   cost/margin estimate. Picker row + a stacked list of .dv-gearline rows. */
:is(.dv-gearpick, .os-gearpick) {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 16px;
}
:is(.dv-gearpick__select, .os-gearpick__select), :is(.dv-gearpick__qty, .os-gearpick__qty) {
  font: inherit; font-size: var(--text-sm); color: var(--ink);
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-sm);
  padding: 7px 10px; height: 34px;
}
:is(.dv-gearpick__select, .os-gearpick__select) { min-width: 180px; }
:is(.dv-gearpick__qty, .os-gearpick__qty) { width: 68px; }
:is(.dv-gearpick__select, .os-gearpick__select):focus-visible, :is(.dv-gearpick__qty, .os-gearpick__qty):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
:is(.dv-gearlist, .os-gearlist) { display: flex; flex-direction: column; gap: 6px; }
:is(.dv-gearline__est, .os-gearline__est) { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; flex-shrink: 0; margin-left: auto; }
/* empty / no-results */
:is(.dv-empty, .os-empty) { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 56px 20px; text-align: center; }
:is(.dv-empty, .os-empty) :is(.t, .os-t) { font-size: var(--text-sm); font-weight: 600; color: var(--gray-700); }
:is(.dv-empty, .os-empty) :is(.s, .os-s) { font-size: var(--text-sm); color: var(--muted); }
/* ─── 10. Read-only published view (packages#show) ─────────────────────
   Spec: read-only-view/pb-view.jsx + pb.css. Single-scroll detail page with a
   CSS-gradient ocean hero, bento stats, blocks, and a sticky section nav.
   Token-only; ocean blues via --sky-*, sheen via white/black alpha. */
:is(.pkb-view, .os-pkb-view) {
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 0 48px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 188px;
  gap: 40px;
  align-items: start;
}
@media (max-width: 1000px) { :is(.pkb-view, .os-pkb-view) { grid-template-columns: 1fr; } :is(.pkb-minnav, .os-pkb-minnav) { display: none; } }
:is(.pkb-view-main, .os-pkb-view-main) { min-width: 0; display: flex; flex-direction: column; gap: 28px; }
/* Breadcrumb on the package show header uses the canonical
   .hero-show__breadcrumb component (shared/patterns/_breadcrumb); give it the
   header's spacing below the trail. */
:is(.pkb-view-header-inner, .os-pkb-view-header-inner) :is(.hero-show__breadcrumb, .os-hero-show__breadcrumb) { margin-bottom: 16px; }
/* full-width header band — white surface, hairline divider below. The
   background bleeds to the content-pane edges (same calc as .dv-page-band —
   keep in sync); the inner content re-caps to the 1180 column, which is
   centered in the pane exactly like .pkb-view below, so they line up. */
:is(.pkb-view-header, .os-pkb-view-header) {
  background: var(--surface); border-bottom: 1px solid var(--hairline);
  margin-top: -40px; /* bleed up through .diveos-content's 40px top padding */
  /* #493 — bleed with the shell's canonical full-bleed vars (the same calc as
     .os-page-band): the band spans exactly the content pane and its inner
     re-pads to the gutter. The old hardcoded ±48px / 50vw calc assumed a 48px
     gutter and the full window, so wherever the gutter is narrower (phones,
     tablets, 1024–1300 desktops) the band overshot the pane → horizontal
     scroll (+32px at 370/768, +6–14px at 1100–1280). At 1440 it lands on the
     same pixels as before. */
  width: var(--bleed-w, auto);
  margin-left: var(--bleed-mx, 0);
  margin-right: var(--bleed-mx, 0);
  padding-left: var(--bleed-pad, 0);
  padding-right: var(--bleed-pad, 0);
}
@media (max-width: 1023px) {
  /* #493 — clear the fixed shell nav toggle like .os-page-band does (the
     breadcrumb sat under the hamburger once the band stopped overshooting). */
  :is(.pkb-view-header, .os-pkb-view-header) { margin-top: -56px; padding-top: var(--dv-nav-gutter-top, 0); }
}
/* #493 — phones: title block and actions stack (the actions no longer squeeze
   the title into a one-word-per-line column). */
@media (max-width: 640px) {
  :is(.pkb-view-headrow, .os-pkb-view-headrow) { flex-wrap: wrap; row-gap: 12px; }
}
:is(.pkb-view-header-inner, .os-pkb-view-header-inner) { max-width: 1180px; margin: 0 auto; padding: 18px 0 22px; }
:is(.pkb-view-headrow, .os-pkb-view-headrow) {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 28px;
}
:is(.pkb-view-header, .os-pkb-view-header) :is(.hd-l, .os-hd-l) { min-width: 0; }
:is(.pkb-view-header, .os-pkb-view-header) :is(.hd-title, .os-hd-title) { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
:is(.pkb-view-header, .os-pkb-view-header) :is(.hd-title, .os-hd-title) h1 {
  margin: 0; font-family: var(--font-display); font-weight: 600; font-size: var(--text-3xl);
  line-height: 1.1; letter-spacing: -0.02em; color: var(--ink);
}
:is(.pkb-view-header, .os-pkb-view-header) :is(.hd-sub, .os-hd-sub) { margin: 9px 0 0; font-size: var(--text-sm); color: var(--muted); max-width: 68ch; }
:is(.pkb-view-actions, .os-pkb-view-actions) { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
/* SelectableStatusPill — DS StatusPill + chevron trigger + popover menu */
:is(.pkb-statussel, .os-pkb-statussel) { position: relative; }
/* A menu trigger on the xs control rung (22): border-box so the status pill's
   border sits inside the height instead of pushing it to 23 (#609 R3). */
:is(.pkb-statuspill-sel, .os-pkb-statuspill-sel) { box-sizing: border-box; height: var(--control-h-xs); cursor: pointer; padding-right: 8px; transition: background 120ms ease, border-color 120ms ease; }
:is(.pkb-statuspill-sel, .os-pkb-statuspill-sel) :is(.chev, .os-chev) { margin-left: 1px; opacity: 0.7; }
:is(.pkb-statuspill-sel, .os-pkb-statuspill-sel):hover { filter: brightness(0.98); }
:is(.pkb-statuspill-sel, .os-pkb-statuspill-sel):focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.pkb-statusmenu, .os-pkb-statusmenu) {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; min-width: 152px; margin: 0;
  padding: 5px; background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); box-shadow: var(--shadow-md);
  display: none; flex-direction: column; gap: 2px;
}
:is(.pkb-statussel, .os-pkb-statussel).is-open :is(.pkb-statusmenu, .os-pkb-statusmenu) { display: flex; }
:is(.pkb-statusopt, .os-pkb-statusopt) {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  padding: 6px 8px; background: none; border: 0; border-radius: var(--radius-sm);
  font: inherit; cursor: pointer; text-align: left;
}
:is(.pkb-statusopt, .os-pkb-statusopt):hover { background: var(--surface-alt); }
:is(.pkb-statusopt, .os-pkb-statusopt):is(.on, .os-on) { background: var(--accent-soft); }
:is(.pkb-statusopt, .os-pkb-statusopt) :is(.ck, .os-ck) { color: var(--accent); flex-shrink: 0; }
:is(.pkb-view-foot, .os-pkb-view-foot) {
  display: flex; align-items: center; gap: 20px;
  margin-top: 8px; padding-top: 22px; border-top: 1px solid var(--hairline);
}
/* link-style buttons */
:is(.pkb-linkbtn, .os-pkb-linkbtn) {
  display: inline-flex; align-items: center; gap: 6px; padding: 0;
  font: inherit; font-size: var(--text-sm); font-weight: 500; background: none; border: 0;
  color: var(--muted); cursor: pointer; text-decoration: none;
  transition: color var(--t-fast) ease;
}
:is(.pkb-linkbtn, .os-pkb-linkbtn):is(.neutral, .os-neutral):hover { color: var(--ink); }
:is(.pkb-linkbtn, .os-pkb-linkbtn):is(.danger, .os-danger) { color: var(--cancelled); }
:is(.pkb-linkbtn, .os-pkb-linkbtn):is(.danger, .os-danger):hover { color: var(--cancelled); text-decoration: underline; }
/* sticky section mini-nav */
:is(.pkb-minnav, .os-pkb-minnav) { position: sticky; top: 24px; display: flex; flex-direction: column; gap: 2px; }
:is(.pkb-minnav, .os-pkb-minnav) a {
  padding: 7px 12px; font-size: var(--text-sm); font-weight: 500; color: var(--muted);
  text-decoration: none; border-left: 2px solid var(--hairline);
  transition: color var(--t-fast) ease, border-color var(--t-fast) ease;
}
:is(.pkb-minnav, .os-pkb-minnav) a:hover { color: var(--ink); border-left-color: var(--hairline-strong); }
:is(.pkb-minnav, .os-pkb-minnav) a:is(.on, .os-on) { color: var(--accent); border-left-color: var(--accent); font-weight: 600; }
/* ocean hero — pure CSS gradient, no image */
:is(.pkb-hero, .os-pkb-hero) {
  position: relative; aspect-ratio: 16 / 6.6; border-radius: var(--radius-lg);
  overflow: hidden; border: 1px solid var(--hairline);
}
:is(.pkb-ocean, .os-pkb-ocean) {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 70% 0%, rgba(255, 255, 255, 0.28), transparent 55%),
    linear-gradient(180deg, var(--sky-600) 0%, var(--sky-800) 38%, var(--sky-950) 100%);
}
:is(.pkb-ocean, .os-pkb-ocean)::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(60% 40% at 22% 14%, rgba(255, 255, 255, 0.18), transparent 60%),
    radial-gradient(40% 30% at 85% 80%, rgba(0, 0, 0, 0.35), transparent 70%);
}
/* cover image — fills the hero, sits above the gradient; if the src is broken
   the controller-free onerror removes it and the ocean placeholder shows. */
:is(.pkb-hero-img, .os-pkb-hero-img) { position: absolute; inset: 0; width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; }
/* bento stat grid */
:is(.pkb-bento, .os-pkb-bento) { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 12px; }
@media (max-width: 720px) { :is(.pkb-bento, .os-pkb-bento) { grid-template-columns: 1fr 1fr; } }
/* (.pkb-bento-cell retired by #493 — the cells render .os-stat-card.)
   The lead cell (price per person) keeps its 42px hero figure: os-ds has no
   hero/large stat-card value variant yet, so this is a page-scoped interim
   until one lands upstream (muf decision pending: 42px vs the card's 20px). */
:is(.pkb-bento, .os-pkb-bento) > .os-stat-card:first-child .os-stat-card-value { font-size: 42px; line-height: 1.1; }
/* blocks + cards — titles live INSIDE the card as the first row (initialism),
   separated from the body by a hairline. The card owns no padding; the head row
   and each section's body wrapper manage their own. */
:is(.pkb-prose, .os-pkb-prose) { font-size: var(--text-md); line-height: 1.65; color: var(--gray-700); max-width: 70ch; }
/* Card shell mirrors the DiveOS booking-detail card (.bk-detail .card, #67):
   radius-lg, border-only (no shadow), an icon + uppercase eyebrow head with NO
   hairline divider (padding 22/24/0), body padding 22/24. Package-scoped so the
   generic `.card` class stays owned by booking detail. */
:is(.pkb-card, .os-pkb-card) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); overflow: hidden; padding: 0; }
:is(.pkb-cardhead, .os-pkb-cardhead) {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 22px 24px 0;
}
:is(.pkb-cardhead, .os-pkb-cardhead) :is(.t, .os-t) {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink);
}
:is(.pkb-cardhead, .os-pkb-cardhead) :is(.t, .os-t) svg { flex-shrink: 0; color: var(--muted-2); }
:is(.pkb-cardhead, .os-pkb-cardhead) :is(.ct, .os-ct) {
  font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500;
  color: var(--muted-2); white-space: nowrap;
}
/* per-section body wrappers — head has no bottom padding, so bodies own the
   gap below the eyebrow (DS card body = 22/24). */
:is(.pkb-cardbody--pad, .os-pkb-cardbody--pad) { padding: 18px 24px 22px; }
/* highlights */
:is(.pkb-cardbody--acc, .os-pkb-cardbody--acc) { padding: 6px 24px 14px; }
/* accommodation */
:is(.pkb-cardrows, .os-pkb-cardrows) { padding-top: 12px; }
/* items / extras row lists (rows own their inset) */
/* in-card empty state — clean muted row */
:is(.pkb-cardempty, .os-pkb-cardempty) { display: flex; align-items: center; gap: 10px; padding: 18px 24px 22px; font-size: var(--text-sm); color: var(--muted); }
:is(.pkb-cardempty, .os-pkb-cardempty) :is(.ic, .os-ic) { color: var(--muted-2); display: flex; flex-shrink: 0; }
/* highlights */
:is(.pkb-vhls, .os-pkb-vhls) { -moz-columns: 2; columns: 2; -moz-column-gap: 32px; column-gap: 32px; }
@media (max-width: 720px) { :is(.pkb-vhls, .os-pkb-vhls) { -moz-columns: 1; columns: 1; } }
:is(.pkb-vhl, .os-pkb-vhl) { display: flex; align-items: flex-start; gap: 10px; padding: 7px 0; font-size: var(--text-sm); color: var(--gray-700); line-height: 1.4; -moz-column-break-inside: avoid; break-inside: avoid; }
:is(.pkb-vhl, .os-pkb-vhl) :is(.ic, .os-ic) { color: var(--accent); flex-shrink: 0; margin-top: 1px; display: flex; }
/* item rows */
:is(.pkb-itemrow, .os-pkb-itemrow) { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-top: 1px solid var(--hairline-2); }
:is(.pkb-itemrow, .os-pkb-itemrow):first-child { border-top: 0; }
:is(.pkb-itemrow, .os-pkb-itemrow) :is(.kind, .os-kind) { width: 36px; height: 36px; border-radius: var(--radius-pill); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
:is(.pkb-itemrow, .os-pkb-itemrow) :is(.kind, .os-kind):is(.dive, .os-dive) { background: var(--sky-50); color: var(--sky-700); }
:is(.pkb-itemrow, .os-pkb-itemrow) :is(.kind, .os-kind):is(.equip, .os-equip) { background: var(--gray-100); color: var(--gray-600); }
:is(.pkb-itemrow, .os-pkb-itemrow) :is(.nm, .os-nm) { flex: 1; font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.pkb-itemrow, .os-pkb-itemrow) :is(.qty, .os-qty) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--muted); }
:is(.pkb-itemrow, .os-pkb-itemrow) :is(.type, .os-type) { font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
/* pricing viz */
:is(.pkb-pviz, .os-pkb-pviz) { padding: 24px 26px; }
:is(.pkb-pviz, .os-pkb-pviz) :is(.sell, .os-sell) { display: flex; align-items: baseline; gap: 12px; }
:is(.pkb-pviz, .os-pkb-pviz) :is(.sell, .os-sell) :is(.amt, .os-amt) { font-family: var(--font-display); font-weight: 600; font-size: 38px; letter-spacing: -0.02em; color: var(--ink); }
:is(.pkb-pviz, .os-pkb-pviz) :is(.sell, .os-sell) :is(.per, .os-per) { font-size: var(--text-sm); color: var(--muted); }
:is(.pkb-pviz-bar, .os-pkb-pviz-bar) { position: relative; height: 8px; border-radius: var(--radius-pill); background: var(--gray-100); margin: 28px 0 8px; }
:is(.pkb-pviz-bar, .os-pkb-pviz-bar):is(.live, .os-live) { background: linear-gradient(90deg, var(--cancelled-bg), var(--confirmed-bg) 50%, var(--briefing-bg)); }
:is(.pkb-pviz-bar, .os-pkb-pviz-bar) :is(.pos, .os-pos) { position: absolute; top: -5px; width: 18px; height: 18px; border-radius: var(--radius-pill); background: var(--surface); border: 2.5px solid var(--accent); transform: translateX(-50%); box-shadow: var(--shadow-sm); }
:is(.pkb-pviz-bar, .os-pkb-pviz-bar) :is(.pos, .os-pos)::after { content: ""; position: absolute; inset: 3.5px; border-radius: var(--radius-pill); background: var(--accent); }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale) { display: flex; justify-content: space-between; font-size: var(--text-xs); }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale) :is(.s, .os-s) { display: flex; flex-direction: column; gap: 2px; }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale) :is(.s, .os-s):is(.mid, .os-mid) { align-items: center; }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale) :is(.s, .os-s):is(.end, .os-end) { align-items: flex-end; }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale) :is(.lbl, .os-lbl) { font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted-2); }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale) :is(.val, .os-val) { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--ink); }
:is(.pkb-pviz-scale, .os-pkb-pviz-scale):is(.muted, .os-muted) :is(.val, .os-val) { color: var(--muted-2); }
/* accommodation */
:is(.pkb-acc-head, .os-pkb-acc-head) { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
:is(.pkb-acc-head, .os-pkb-acc-head) :is(.ic, .os-ic) { color: var(--accent); display: flex; }
:is(.pkb-acc-head, .os-pkb-acc-head) :is(.nm, .os-nm) { font-size: var(--text-md); font-weight: 600; color: var(--ink); }
:is(.pkb-acc-head, .os-pkb-acc-head) :is(.meta, .os-meta) { margin-left: auto; font-size: var(--text-xs); color: var(--muted); }
:is(.pkb-acc-rate, .os-pkb-acc-rate) { display: grid; gap: 0; padding: 4px 0; }
:is(.pkb-acc-line, .os-pkb-acc-line) { display: flex; align-items: baseline; justify-content: space-between; padding: 10px 0; border-top: 1px solid var(--hairline-2); }
:is(.pkb-acc-line, .os-pkb-acc-line):first-child { border-top: 0; }
:is(.pkb-acc-line, .os-pkb-acc-line) :is(.k, .os-k) { font-size: var(--text-sm); color: var(--gray-700); }
:is(.pkb-acc-line, .os-pkb-acc-line) :is(.v, .os-v) { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-sm); color: var(--ink); }
/* extras tiles */
:is(.pkb-pmstile, .os-pkb-pmstile) { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-top: 1px solid var(--hairline-2); }
:is(.pkb-pmstile, .os-pkb-pmstile):first-child { border-top: 0; }
:is(.pkb-pmstile, .os-pkb-pmstile) :is(.q, .os-q) { width: 34px; height: 34px; border-radius: var(--radius-pill); background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700; flex-shrink: 0; }
:is(.pkb-pmstile, .os-pkb-pmstile) :is(.nm, .os-nm) { flex: 1; font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.pkb-pmstile, .os-pkb-pmstile) :is(.amt, .os-amt) { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-sm); color: var(--ink); white-space: nowrap; }
:is(.pkb-pmstile, .os-pkb-pmstile) :is(.amt, .os-amt) :is(.each, .os-each) { font-size: var(--text-xs); color: var(--muted-2); }
/* ============================================================
   11 · STORY step (story-step.md) — st-form
   Diver-facing marketing copy: short desc, long desc (Trix,
   restyled into .st-editor), cover image, highlights list.
   Lives inside the data-wide centered column (720px, left form).
   ============================================================ */
:is(.st-form, .os-st-form) { text-align: left; display: flex; flex-direction: column; gap: 30px; margin-top: 36px; }
:is(.st-block, .os-st-block) { display: flex; flex-direction: column; gap: 9px; }
:is(.st-blockhead, .os-st-blockhead) { display: flex; justify-content: space-between; align-items: baseline; }
:is(.st-label, .os-st-label) { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
:is(.st-counter, .os-st-counter) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); }
:is(.st-counter, .os-st-counter):is(.over, .os-over) { color: var(--error); }
:is(.st-hint, .os-st-hint) { margin: 0; font-size: var(--text-xs); line-height: 1.5; color: var(--muted-2); }
/* shared input recipe (short desc + add-a-highlight) */
:is(.st-input, .os-st-input), :is(.st-hladd, .os-st-hladd) input {
  height: 40px; padding: 0 13px; box-sizing: border-box;
  font-family: var(--font-sans); font-size: var(--text-sm); color: var(--ink);
  background: var(--surface); border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
:is(.st-input, .os-st-input) { width: 100%; }
:is(.st-input, .os-st-input)::-moz-placeholder, :is(.st-hladd, .os-st-hladd) input::-moz-placeholder { color: var(--muted-2); }
:is(.st-input, .os-st-input)::placeholder, :is(.st-hladd, .os-st-hladd) input::placeholder { color: var(--muted-2); }
:is(.st-input, .os-st-input):focus, :is(.st-hladd, .os-st-hladd) input:focus {
  outline: none; border-color: var(--input-border-focus);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
/* long description — .st-editor wraps the Trix editor; its native toolbar is
   hidden in favor of the .st-toolbar chrome wired in story_controller. */
:is(.st-editor, .os-st-editor) {
  border: 1px solid var(--input-border); border-radius: var(--radius-sm);
  background: var(--surface); overflow: hidden;
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
:is(.st-editor, .os-st-editor):focus-within { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.st-toolbar, .os-st-toolbar) { display: flex; align-items: center; gap: 2px; padding: 6px 8px; background: var(--surface-alt); border-bottom: 1px solid var(--hairline); }
:is(.st-tbtn, .os-st-tbtn) {
  width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease, border-color var(--t-fast) ease;
}
:is(.st-tbtn, .os-st-tbtn):hover { background: var(--surface); border-color: var(--hairline); color: var(--ink); }
:is(.st-tdiv, .os-st-tdiv) { width: 1px; height: 18px; background: var(--hairline); margin: 0 5px; }
/* Trix editor styled as the textarea; native toolbar suppressed */
:is(.st-editor, .os-st-editor) trix-toolbar { display: none; }
:is(.st-editor, .os-st-editor) trix-editor {
  display: block; min-height: 132px; padding: 13px 14px; box-sizing: border-box;
  font-family: var(--font-sans); font-size: var(--text-sm); line-height: 1.6; color: var(--ink);
  border: 0; outline: none; resize: vertical; overflow: auto;
}
:is(.st-editor, .os-st-editor) trix-editor:empty:not(:focus)::before { color: var(--muted-2); }
/* cover image — single container drives both states via :has() on the preview */
:is(.st-cover, .os-st-cover) {
  position: relative; width: 100%; cursor: pointer;
  background: var(--surface-alt); border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius);
  transition: border-color var(--t-fast) ease, background var(--t-fast) ease;
}
:is(.st-cover, .os-st-cover).is-dragover { border-color: var(--accent); background: var(--accent-softer); }
:is(.st-cover, .os-st-cover).is-invalid { border-color: var(--cancelled-border); background: var(--cancelled-bg); }
:is(.st-cover, .os-st-cover):hover { border-color: var(--accent); background: var(--accent-softer); }
:is(.st-cover__input, .os-st-cover__input) { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
:is(.st-cover__empty, .os-st-cover__empty) {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  padding: 30px 24px; text-align: center; pointer-events: none;
}
:is(.st-cover__empty, .os-st-cover__empty) :is(.ic, .os-ic) { color: var(--muted-2); transition: color var(--t-fast) ease; }
:is(.st-cover, .os-st-cover):hover :is(.st-cover__empty, .os-st-cover__empty) :is(.ic, .os-ic) { color: var(--accent); }
:is(.st-cover__empty, .os-st-cover__empty) :is(.t, .os-t) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.st-cover__empty, .os-st-cover__empty) :is(.s, .os-s) { font-size: var(--text-xs); color: var(--muted-2); max-width: 40ch; line-height: 1.45; }
:is(.st-cover__img, .os-st-cover__img) { display: none; width: 100%; height: 200px; -o-object-fit: cover; object-fit: cover; border-radius: var(--radius); }
:is(.st-cover-edit, .os-st-cover-edit) { display: none; }
/* filled state: a preview image is present (not .hidden) */
:is(.st-cover, .os-st-cover):has(:is(.st-cover__img, .os-st-cover__img):not(.hidden)) {
  border-style: solid; border-color: var(--hairline); background: transparent; overflow: hidden; height: 200px;
}
:is(.st-cover, .os-st-cover):has(:is(.st-cover__img, .os-st-cover__img):not(.hidden)):hover { border-color: var(--hairline); background: transparent; }
:is(.st-cover, .os-st-cover):has(:is(.st-cover__img, .os-st-cover__img):not(.hidden)) :is(.st-cover__img, .os-st-cover__img) { display: block; }
:is(.st-cover, .os-st-cover):has(:is(.st-cover__img, .os-st-cover__img):not(.hidden)) :is(.st-cover-edit, .os-st-cover-edit) {
  position: absolute; right: 12px; bottom: 12px; pointer-events: none;
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  font-size: var(--text-xs); font-weight: 600; color: var(--ink);
  background: color-mix(in srgb, var(--surface) 92%, transparent); backdrop-filter: blur(6px);
  border: 1px solid var(--hairline); border-radius: var(--radius-pill); box-shadow: var(--shadow-sm);
}
/* highlights list */
:is(.st-hls, .os-st-hls) { display: flex; flex-direction: column; gap: 0; border: 1px solid var(--hairline); border-radius: var(--radius-sm); overflow: hidden; }
:is(.st-hls, .os-st-hls):empty { display: none; }
:is(.st-hl, .os-st-hl) { display: flex; align-items: center; gap: 11px; padding: 11px 14px; border-top: 1px solid var(--hairline-2); font-size: var(--text-sm); color: var(--ink); }
:is(.st-hl, .os-st-hl):first-child { border-top: 0; }
:is(.st-hl, .os-st-hl) :is(.ic, .os-ic) { color: var(--accent); flex-shrink: 0; display: flex; }
:is(.st-hl, .os-st-hl) :is(.tx, .os-tx) { flex: 1; min-width: 0; }
:is(.st-hl, .os-st-hl) :is(.rm, .os-rm) {
  width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 5px; background: transparent; color: var(--muted-2); cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.st-hl, .os-st-hl) :is(.rm, .os-rm):hover { background: var(--surface-alt); color: var(--error); }
/* add-a-highlight row */
:is(.st-hladd, .os-st-hladd) { display: flex; gap: 8px; }
:is(.st-hladd, .os-st-hladd) input { flex: 1; }
:is(.st-hladd, .os-st-hladd) button {
  display: inline-flex; align-items: center; gap: 6px; padding: 0 16px;
  font-size: var(--text-sm); font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border: 1px solid var(--accent-border); border-radius: var(--radius-sm); cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
:is(.st-hladd, .os-st-hladd) button:hover:not(:disabled) { background: var(--accent); color: var(--surface); }
:is(.st-hladd, .os-st-hladd) button:disabled { opacity: 0.5; cursor: default; }
/* packages-v2 DR-14 — Stay step guesthouse rows: stacked, hairline-divided,
   the offered row tinted with the accent (never a card grid). */
.pkb-partner-rows {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 0.5rem);
  background: var(--surface);
}
.pkb-partner-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--hairline);
}
.pkb-partner-row:first-child { border-top: 0; }
.pkb-partner-row:has(.pkb-partner-row__main input[type="checkbox"]:checked) {
  background: var(--accent-soft);
  box-shadow: inset 2px 0 0 var(--accent-border);
}
.pkb-partner-row__main {
  display: flex;
  flex: 1;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  cursor: pointer;
}
.pkb-partner-row__text {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}
.pkb-partner-row__name {
  font-weight: 600;
  color: var(--ink);
}
.pkb-partner-row__differ {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
  cursor: pointer;
}
/* The room types offered at a house: a full-width list under its row,
   indented past the house checkbox. */
.pkb-partner-rooms {
  display: flex;
  flex-basis: 100%;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0 0 0 var(--space-6);
  list-style: none;
}
.pkb-partner-room {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
/* packages-v2 DR-1 — a guesthouse's own price grid on the Price step. */
.pkb-partner-grid {
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-4);
}
.pkb-partner-grid > summary { cursor: pointer; }
/* Confirm dialog — styled replacement for native confirm(), wired via
   Turbo.setConfirmMethod (support/confirm_dialog.js). DS component. */
/* ─────────────────────────────────────────────────────────────────────
   Confirm dialog — DiveOS design-system component (promoted 2026-06-20).

   The single styled replacement for the browser's native confirm() popup.
   Wired globally via Turbo.setConfirmMethod (support/confirm_dialog.js), so
   every `data-turbo-confirm="…"` across the app renders this dialog instead
   of the OS chrome. Built on the native <dialog> element (top-layer + free
   backdrop + Escape handling), mirroring the .arena-modal pattern in modal.css.

   Token-only. The OK button inherits destructive styling when the triggering
   control is destructive (see the JS); otherwise it is the primary accent.
   ───────────────────────────────────────────────────────────────────── */
/* Do NOT set `display` on the base — the UA `dialog:not([open]){display:none}`
   must stay in effect so the closed dialog never blocks page interaction. */
dialog.os-confirm {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: none;
  max-height: none;
  overflow: visible;
}
dialog.os-confirm[open] {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
dialog.os-confirm::backdrop {
  background-color: rgb(15 23 42 / 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.os-confirm__panel {
  width: 100%;
  max-width: 420px;
  margin: 16px;
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.os-confirm__title {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: -0.01em;
  color: var(--ink);
}
.os-confirm__msg {
  margin: 0 0 22px;
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--muted);
}
.os-confirm__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}
/* dv-select — custom DS dropdown, progressive enhancement of native <select>
   (dv_select_controller.js). Replaces Select2 for non-ajax selects. */
/* ── dv-select ─────────────────────────────────────────────────────────────
   Custom design-system dropdown. Progressive enhancement of a native <select>:
   the native element stays in the DOM (source of truth for submit/validation)
   and is visually hidden; this UI is layered on top and kept in sync.
   Ported from tmp/form-elements-preview.html (.dv-field / .dv-pop / .dv-opt /
   .dv-search). Token-only.
   ────────────────────────────────────────────────────────────────────────── */
/* Visually-hidden native select — stays focusable + submittable (NOT display:none) */
.os-select__native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.os-select { position: relative; }
/* ── Touch / coarse-pointer fallback ──────────────────────────────────────
   On touch devices the controller (dv_select_controller connect()) skips the
   custom .dv-pop popup and keeps the native <select> interactive so a tap opens
   the OS picker. The native select is layered transparently OVER the styled
   .dv-field trigger (which is visual-only here), so the field shows the design-
   system look while the tap target is the real native control. */
/* v1.41.0: overlaid IN FLOW, not absolutely. The old `.os-select--native >
   select` (absolute, inset 0) only matched a select that was a direct child of
   the controller element; a form-builder select sits inside its field wrapper
   (label + select), so the rule missed and touch screens showed the select
   twice. Now the select takes the trigger's height and pulls the trigger
   (always its next sibling) up under itself with a matching negative margin —
   nested or direct, the transparent native select covers exactly the trigger. */
.os-select--native { --os-select-h: max(var(--control-h), var(--control-h-field)); }
.os-select--native.os-select--sm { --os-select-h: 36px; }
/* Trigger and overlay share one height so they line up exactly. The trigger is
   one nowrap line, so pinning it is safe. Base = its min-height; --sm = its
   natural height (6px padding + 22px line + 1px borders) over its 34px floor. */
.os-select--native select + .os-select-field { height: var(--os-select-h); }
/* Doubled class: outranks the 46px field-control height (forms.css, 0,3,1)
   so select and trigger always share --os-select-h. width 0 + min-width 100%:
   fills the container without its longest option widening it. */
.os-select--native.os-select--native select:not([hidden], .hidden):has(+ .os-select-field) {
  position: relative;
  z-index: 1;
  display: block;
  width: 0;
  min-width: 100%;
  height: var(--os-select-h);
  min-height: 0;
  margin: 0 0 calc(-1 * var(--os-select-h));
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}
/* The focused control is the transparent select; show its focus on the trigger. */
.os-select--native select:focus-visible + .os-select-field {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
/* Trigger */
.os-select-field {
  width: 100%;
  /* A select is a FIELD control: its floor is the 46px field baseline, never
     the 36px button base. So it takes the LARGER of the surface density and
     that floor — 46px at base/compact/comfortable density (unchanged from the
     literal it replaces), 48px inside .os-density--touch. Expressed as max()
     rather than a pinned token because "never shorter than a field, but grow
     with the surface" is the actual rule, and a pinned value could not grow.
     Was a bare 46px literal, one of four independent copies of that number. */
  min-height: max(var(--control-h), var(--control-h-field));
  padding: 10px 12px;
  font-family: inherit;
  font-size: var(--text-sm);
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.os-select-field:hover { border-color: var(--accent); }
.os-select-field.is-open, .os-select-field:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
  outline: none;
}
.os-select-field__val { flex: 1; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.os-select-field__val.is-placeholder { color: var(--text-muted); }
.os-select-field__icon { color: var(--text-muted); flex-shrink: 0; display: inline-flex; }
/* Compact size — inline selects in dense contexts (e.g. the Today to-schedule
   card headers), smaller than the 46px filter-row default. A real component
   variant, not a per-surface height hack. */
.os-select--sm .os-select-field {
  /* 34px is OFF the control scale — it sits between --sm (32) and base (36)
     and matches nothing else in the system. It is the drift this contract
     exists to stop, kept at its shipped value here because correcting it
     would move a live control. A future minor should land it on 32px. */
  min-height: 34px;
  padding: 6px 10px;
  font-size: var(--text-xs);
}
.os-select--sm .os-select-field__icon svg { width: 14px; height: 14px; }
/* Menu — the searchable custom-select dropdown built by dv_select_controller.js.
   NOTE: this class was historically named `.os-pop`, which COLLIDED with the
   separate multiselect/filter popover in popover.css (also `.os-pop`) at equal
   specificity. In the flattened os_ds.css bundle popover.css is emitted later,
   so its `overflow: hidden` won and this menu lost its scroll (long option lists
   overflowed the viewport uncut). Renamed to the `.os-select__menu` family so the
   two components no longer fight. Do NOT rename back to `.os-pop`. */
.os-select__menu {
  position: absolute;
  z-index: 30;
  margin-top: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .10);
  padding: 6px;
  /* Never narrower than a legible floor: a compact (--sm) or otherwise narrow
     trigger must still open a menu wide enough that short labels ("No grouping",
     "All statuses") don't wrap. Capped so a genuinely long label wraps
     gracefully instead of forcing a huge menu. */
  min-width: max(100%, 12rem);
  max-width: min(24rem, 92vw);
  max-height: 320px;
  overflow-y: auto;
}
/* Rich two-line rows (diver→session picker) need room so site/guide don't
   truncate to "H · G.." — widen the popup past the (often narrow) trigger. */
.os-select__menu:has(.os-opt--rich) {
  min-width: min(340px, 92vw);
}
/* While open, the controller relocates the menu onto <body> (position:fixed)
   to escape clipping ancestors. There, the inline 30 sat BELOW every overlay a
   select can live in — os-sheet / filter sheet (70), mobile wizard (60), and
   app drawers — so the menu opened behind its own panel and read as "the
   dropdown doesn't work". A relocated menu exists only while open and is
   anchored to its trigger, so it stacks above all of them. Inline menus keep
   30. (A <dialog> host is the top layer and needs no z-index.) */
body > .os-select__menu { z-index: 90; }
/* Option */
.os-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-primary);
}
.os-opt:hover, .os-opt.is-active { background: var(--surface-alt); }
.os-opt[aria-selected="true"] {
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-weight: 500;
}
.os-opt__check { margin-left: auto; color: var(--accent); opacity: 0; display: inline-flex; flex-shrink: 0; }
.os-opt[aria-selected="true"] .os-opt__check { opacity: 1; }
.os-opt.is-disabled { color: var(--text-muted); cursor: not-allowed; opacity: .6; }
/* Rich two-line rows (diver → dive-session picker, #199). The row markup is
   supplied via <option data-rich-html> and rendered inside .dv-opt__rich.
   Used by both the crew/roster picker and the Today "to schedule" diver
   card's trip picker (ToScheduleHelper#trip_option_html) — one mechanism,
   not two: this superseded diver-card-only .dv-opt__main/.dv-opt__sub 2-line
   variant, which duplicated the same "which session?" disambiguation. */
.os-opt--rich { align-items: flex-start; padding: 9px 10px; }
.os-opt__rich { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.os-opt__rich .os-opt-line {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.os-opt__rich .os-opt-line--head { justify-content: space-between; }
.os-opt__rich .os-opt-title { display: flex; align-items: center; gap: 6px; min-width: 0; }
.os-opt__rich .os-opt-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--text-muted);
}
.os-opt__rich .os-opt-meta :is(.truncate, .os-truncate), .os-opt__rich .os-opt-title :is(.truncate, .os-truncate) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.os-opt__rich [data-lucide], .os-opt__rich svg { width: 13px; height: 13px; flex-shrink: 0; }
.os-opt--rich .os-opt__check { align-self: center; }
/* Search header (component-scoped element).
   Named `.dv-select__search` (not the generic `.dv-search`, which is a separate
   search field owned by package_builder.css) so the two don't collide — that
   collision previously stacked package_builder's focus ring on this dropdown. */
.os-select__search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  margin-bottom: 4px;
  border: 1px solid transparent;
  border-bottom-color: var(--border);
  border-radius: var(--radius-sm);
  transition: border-color .12s, box-shadow .12s;
}
/* ONE focus indicator: a single ring around the whole search box. */
.os-select__search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.os-select__search svg { color: var(--text-muted); flex-shrink: 0; }
/* padding/line-height are reset for the same @tailwindcss/forms reason as the
   :focus rule below: the plugin pads a bare type="text" 8px 12px at a 24px
   line-height, which made the search row 54px tall with a 20px icon gap. */
.os-select__search input {
  padding: 0;
  line-height: 1.25rem;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: var(--text-sm);
  width: 100%;
  color: var(--text-primary);
  background: transparent;
}
/* The <input> is a bare type="text", so @tailwindcss/forms (Bullet Train
   default) paints its own border + ring on :focus. The container already shows
   focus, so suppress the input's ring — one clean indicator, not the BT box. */
.os-select__search input:focus, .os-select__search input:focus-visible {
  border: 0;
  outline: none;
  box-shadow: none;
  --tw-ring-shadow: 0 0 transparent;
  --tw-ring-offset-shadow: 0 0 transparent;
}
/* Empty state for search */
.os-select__menu-empty {
  padding: 10px;
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-align: center;
}
/* ─── Description list (.dv-desclist) ────────────────────────────────────
   Formalized key/value description-list component. Promotes the earlier
   `.dv-kv` pattern into a proper <dl> with named variants. Default is the
   STACKED multi-column grid (muted label on TOP, ink value BELOW) the
   info_card bodies rely on — the eye scans straight down, no full-width
   eye travel, no per-row dividers. Token-driven, light-only.

   API
     .dv-desclist                      the <dl>: responsive auto-fill grid
     .dv-desclist__row                 a <div> wrapping one dt + dd
     .dv-desclist__term                the <dt> (label: 12px, muted)
     .dv-desclist__desc                the <dd> (value: 14px, ink)
   Variants (on .dv-desclist)
     --inline      term left / desc right on one line (settings layout)
     --striped     alternating row tints + hairline dividers
   Modifier (on .dv-desclist__row)
     --full        row spans all grid columns (long values)

   Supersedes the retired `.dv-kv` pattern — Waiver show now renders this
   component; `.dv-kv*` and the `kv_row` partial no longer exist. */
.os-desclist {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 18px 28px;
  margin: 0;
}
.os-desclist__row {
  min-width: 0;
}
.os-desclist__row--full {
  grid-column: 1 / -1;
}
.os-desclist__term {
  display: block;
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: 1.4;
  margin-bottom: 3px;
}
.os-desclist__desc {
  display: block;
  color: var(--ink);
  font-weight: 500;
  font-size: var(--text-sm);
  line-height: 1.45;
  margin: 0;
  word-break: break-word;
}
.os-desclist__desc a {
  color: var(--accent);
}
/* ── --inline: term left, desc right, one line per row (settings layout) ── */
.os-desclist--inline {
  display: block;
}
.os-desclist--inline .os-desclist__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 0;
}
.os-desclist--inline .os-desclist__row--full {
  grid-column: auto;
}
.os-desclist--inline .os-desclist__term {
  margin-bottom: 0;
  flex: 0 0 auto;
}
.os-desclist--inline .os-desclist__desc {
  text-align: right;
  flex: 1 1 auto;
  min-width: 0;
}
/* ── --striped: alternating tints + hairline dividers (best with --inline) ── */
.os-desclist--striped {
  display: block;
}
.os-desclist--striped .os-desclist__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
}
.os-desclist--striped .os-desclist__row:first-child {
  border-top: 1px solid var(--hairline);
}
.os-desclist--striped .os-desclist__row:nth-child(odd) {
  background: var(--surface-alt);
}
.os-desclist--striped .os-desclist__row--full {
  grid-column: auto;
}
.os-desclist--striped .os-desclist__term {
  margin-bottom: 0;
  flex: 0 0 auto;
}
.os-desclist--striped .os-desclist__desc {
  text-align: right;
  flex: 1 1 auto;
  min-width: 0;
}
/* ═══ v1.4.0 additions — read-only summary variants ═══════════════════════
   Promoted with the guest-arrival set. --mono for figure/code values, --panel
   for the tinted read-only block used by the summary rail (A1) and the
   full-width summary banner (A2). Both compose with --inline / --striped. */
/* ── --mono: figures/codes in monospace with tabular alignment ── */
.os-desclist--mono .os-desclist__desc {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
/* ── --panel: tinted read-only block with hairline row dividers ── */
/* USAGE: --panel IS the surface. Put it directly in the card (or standalone) —
    do NOT nest it inside `.os-card__body`, whose padding makes every row read as
    a chip floating in a card instead of one passive block. Reported from the
    arrival-wizard rail, where exactly that inversion shipped. */
.os-desclist--panel {
  background: var(--surface-alt);
  border-radius: var(--radius-lg);
  gap: 0;
  overflow: hidden;
}
.os-desclist--panel .os-desclist__row {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--hairline);
}
/* First row of each grid column has no rule above it. */
.os-desclist--panel .os-desclist__row:first-child {
  border-top: none;
}
/* dive-chip — one dive-type slice of a diver's unrostered seats on the Today
   panel To-schedule list (ToScheduleQuery::DiveChip). Diver grouping fix. */
/* Today panel · "To schedule" list — diver grouping (Concept B).
   One card per diver; each dive-type slice is a pill ("chip"). Duplicate dive
   types collapse into one chip with a ×N count, so a guest with several dives
   shows once, not once per dive (ToScheduleQuery::DiverGroup / DiveChip).
   Layout mirrors the approved mockup: clean cards on canvas, no colored band. */
/* ── Section + date-group rhythm ─────────────────────────────────── */
:is(.to-schedule__head, .os-to-schedule__head) {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}
:is(.date-block, .os-date-block) + :is(.date-block, .os-date-block) {
  margin-top: 28px;
}
:is(.date-header, .os-date-header) {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
:is(.date-header__spacer, .os-date-header__spacer) {
  flex: 1;
}
/* Accordion trigger — the date row is a button that collapses its diver cards.
   Chevron on the left is the disclosure affordance; hover tints the hit area. */
:is(.date-toggle, .os-date-toggle) {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  margin-left: -8px;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-align: left;
}
:is(.date-toggle, .os-date-toggle):hover {
  background: var(--surface-alt);
}
:is(.date-toggle, .os-date-toggle):focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
:is(.date-toggle__icon, .os-date-toggle__icon) {
  display: inline-flex;
  color: var(--muted-2);
  transition: transform 200ms ease;
}
:is(.diver-cards, .os-diver-cards) {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* dive_chip.css is imported after Tailwind, so .diver-cards{display:flex} would
   beat the utility .hidden{display:none} and the accordion couldn't collapse.
   This compound selector (0,2,0) lets the accordion's .hidden win. */
:is(.diver-cards, .os-diver-cards).hidden {
  display: none;
}
/* ── Diver card ──────────────────────────────────────────────────── */
/* Compound selector (.dv-card.diver-card) so these win over card.css's
   .dv-card regardless of @import order: our own 14/16 padding (the card ships
   padding:0 + __head/__body) and overflow:visible so a chip's popover isn't
   clipped by the card's rounded-corner overflow:hidden. */
:is(.dv-card, .os-card):is(.diver-card, .os-diver-card) {
  padding: 14px 16px;
  overflow: visible;
}
:is(.diver-card__actions, .os-diver-card__actions) {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Trip picker — the DS dv-select (compact --sm variant), fixed width so every
   card's control is the same size regardless of trip-name length; the native
   select is width:auto and would otherwise size to its longest option, giving
   each card a different width. "Place all" is .dv-btn--sm to match the ~34px
   compact field. */
:is(.diver-card__trip, .os-diver-card__trip) {
  width: 168px;
  flex-shrink: 0;
}
:is(.diver-card__head, .os-diver-card__head) {
  display: flex;
  align-items: center;
  gap: 10px;
}
:is(.diver-card__name, .os-diver-card__name) {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
:is(.diver-card__title, .os-diver-card__title) {
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
}
/* #287 — the name is a drawer link into the guest's booking; keep it reading
   as the card title, reveal it's interactive on hover. */
a:is(.diver-card__title, .os-diver-card__title) {
  text-decoration: none;
}
a:is(.diver-card__title, .os-diver-card__title):hover {
  color: var(--accent);
  text-decoration: underline;
}
:is(.diver-card__spacer, .os-diver-card__spacer) {
  flex: 1;
}
:is(.diver-card__actions, .os-diver-card__actions) {
  display: flex;
  align-items: center;
  gap: 8px;
}
:is(.diver-avatar, .os-diver-avatar) {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
/* ── Chip row ────────────────────────────────────────────────────── */
:is(.chip-row, .os-chip-row) {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline-2);
}
/* The pill itself. Holds an optional select-checkbox + a disclosure trigger,
   so clicking the checkbox selects (no popover) while clicking the label/caret
   opens the trip picker — the two never fight over one click target. */
:is(.dive-chip, .os-dive-chip) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  font-size: var(--text-xs);
  color: var(--ink);
  position: relative;
}
/* Plain (no-trip) pills carry no controls, so keep symmetric padding. */
:is(.dive-chip, .os-dive-chip):not(:has(:is(.chip-check, .os-chip-check))) {
  padding: 4px 10px;
}
:is(.dive-chip, .os-dive-chip):has(:is(.diveos-check__input, .os-field-check__input):checked), :is(.dive-chip, .os-dive-chip):has(:is(.dive-chip-menu, .os-dive-chip-menu)[open]) {
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
/* The canonical .diveos-check sits inside the pill as the select control —
   no text label, so drop its label gap and center the 18px box in the pill. */
:is(.dive-chip__check, .os-dive-chip__check) {
  gap: 0;
  align-items: center;
}
:is(.dive-chip__check, .os-dive-chip__check) :is(.diveos-check__box, .os-field-check__box) {
  margin-top: 0;
}
:is(.dive-chip__qty, .os-dive-chip__qty) {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}
/* The disclosure trigger inside the pill — label + qty + caret. */
:is(.dive-chip-menu, .os-dive-chip-menu) {
  display: inline-flex;
  align-items: center;
}
:is(.dive-chip__trigger, .os-dive-chip__trigger) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  list-style: none;
}
:is(.dive-chip__trigger, .os-dive-chip__trigger)::-webkit-details-marker, :is(.dive-chip__trigger, .os-dive-chip__trigger)::marker {
  display: none;
  content: "";
}
:is(.dive-chip__caret, .os-dive-chip__caret) {
  color: var(--muted-2);
  transition: transform 120ms ease;
}
:is(.dive-chip-menu, .os-dive-chip-menu)[open] :is(.dive-chip__caret, .os-dive-chip__caret) {
  transform: rotate(180deg);
}
/* ── Per-chip trip picker popover ────────────────────────────────── */
:is(.chip-popover, .os-chip-popover) {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 30;
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-hover);
  padding: 4px;
}
:is(.chip-popover__label, .os-chip-popover__label) {
  padding: 6px 8px 4px;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted-2);
}
:is(.chip-popover__opt, .os-chip-popover__opt) {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  text-align: left;
  padding: 7px 8px;
  border-radius: 6px;
  font-size: var(--text-sm);
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-sans);
}
:is(.chip-popover__opt, .os-chip-popover__opt):hover:not(:disabled) {
  background: var(--surface-alt);
}
:is(.chip-popover__opt, .os-chip-popover__opt):disabled {
  color: var(--muted-2);
  cursor: default;
}
/* dive-kind badge — os-badge tints (Fun Dive / Try Dive / Course) for a
   booking card, rendered by shared/patterns/_dive_kind_badges. Loaded after
   trip_workflow.css (owns the base .os-badge) so the tint/sentence-case
   overrides win. */
/* dive_kind_badge.css — dive-KIND chips (Fun Dive / Try Dive / Course).
   Imported by application.css (see the css_import_gate). Rendered by
   shared/patterns/_dive_kind_badges; sits on a booking card next to the
   payment status-pill.

   These are os-badge VARIANTS, not a new component — they extend the badge
   family (.os-badge, defined in trip_workflow.css) with three dive-kind
   tints + two structural modifiers. Kept in their own file so the family is
   discoverable and the tints live beside the tokens that feed them.

   Design intent — a dive-kind chip must NEVER be mistaken for a booking
   status. The status palette (confirmed/briefing/inwater/pending/cancelled)
   is a SATURATED soft-COLOUR fill + a 10px UPPERCASE tracked micro-label.
   The dive-kind chip is the opposite treatment: a NEUTRAL (surface-alt) fill,
   NO border, a 12px SENTENCE-CASE tag, and a single gently-COLOURED icon +
   matching label. Same-shape pill, deliberately different weight/case/fill —
   so the payment status stays the card's primary signal and the dive kinds
   read as a quiet secondary tag. The gentle colour also lifts the icon clear
   of the muted-2 meta-row glyphs (which are neutral grey), so the kind is not
   colour-only-vs-nothing — it's a distinct, legible hue.

   Light-only, token-only (var() — no naked hex, per the raw-hex CSS gate). */
/* Dive-kind semantic tokens. No dedicated dive-kind ramp exists in the os-ds
   token layer (the gem), and the status palette already consumes every colour
   ramp, so these alias existing -700 primitives at the app level. -700 clears
   AA (>=4.5:1) on the surface-alt fill for both the label text and the icon.
   var()-only, so this stays inside the naked-hex gate. Hues are chosen to read
   as the dive kind, NOT a status: water (sky), the orange of a life-buoy
   (amber), and a learning/achievement green. */
:root {
  --dive-fun-fg:    var(--sky-700);    /* waves — water */
  --dive-try-fg:    var(--amber-700);  /* life-buoy — safety orange */
  --dive-course-fg: var(--green-700);  /* graduation-cap — learning */
}
/* Shared dive-kind treatment: quiet, sentence-case tag on a neutral fill.
   Overrides the base .os-badge's uppercase/tracked 10px status-label look. */
:is(.dv-badge--dive, .os-badge--dive) {
  gap: 5px;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  background: var(--surface-alt);
  border-color: transparent;
}
/* Icon inherits the chip colour (Lucide stroke=currentColor). Optical size is
   set by the icon helper; this only guards flex behaviour. */
:is(.dv-badge--dive, .os-badge--dive) :is(.lucide, svg) {
  flex-shrink: 0;
}
/* Compact (dense 300px kanban card): icon-only. Square padding + pill radius
   => a small round tinted glyph; the label is dropped (title + aria-label on
   the span carry the meaning — see the partial). */
:is(.dv-badge--dive-compact, .os-badge--dive-compact) {
  gap: 0;
  padding: 4px;
}
/* The three tints. Colour lands on the whole chip so label AND icon
   (currentColor) share the hue. */
:is(.dv-badge--dive-fun, .os-badge--dive-fun)       { color: var(--dive-fun-fg); }
:is(.dv-badge--dive-try, .os-badge--dive-try)       { color: var(--dive-try-fg); }
:is(.dv-badge--dive-course, .os-badge--dive-course) { color: var(--dive-course-fg); }
/* dv-datepicker — custom DS date picker, vanilla-JS two-month calendar
   (controllers/fields/date_controller.js). Replaces daterangepicker/jQuery. */
/* ── dv-datepicker ─────────────────────────────────────────────────────────
   Custom design-system date picker. Vanilla-JS calendar replacing the
   daterangepicker (jQuery) vendor lib for `fields--date` fields. Progressive
   enhancement: the gem's `.date-input` markup stays (hidden field = submit
   source of truth + display field), and this UI is layered on the display
   field's wrapper. Token-only.

   Ported from tmp/form-elements-preview.html (.cal / .cals / .cal__*). The
   .dv-field / .dv-pop trigger + popover shells are shared with dv_select.css;
   only datepicker-specific rules live here.
   ──────────────────────────────────────────────────────────────────────── */
/* Wrapper turns relative so the popover can anchor to the trigger. */
.os-datepicker { position: relative; }
/* The native gem inputs (display + hidden) stay in the DOM but are visually
   hidden. The display input remains the value source the controller writes to;
   we mirror its value into .dv-field__val. */
.os-datepicker__native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Trigger — reuses .dv-field look from dv_select.css. The calendar icon sits
   on the LEFT of the value (matches approved preview row). */
.os-datepicker .os-select-field { justify-content: flex-start; }
.os-datepicker .os-select-field__val.is-placeholder { color: var(--text-muted); }
/* ── Calendar popover body ── */
/* #291 — components/popover.css (the Trip v4 roster port) is @imported AFTER
   this file and sets a generic `.dv-pop { width: 320px; overflow: hidden }`,
   which at equal specificity would win and force the two-month calendar (2×260px
   = 540px) to wrap + clip. Qualify with `.dv-pop` so this variant's width wins
   regardless of import order, and keep overflow visible so nothing is clipped. */
.os-pop.os-pop--cal {
  padding: 12px;
  width: -moz-max-content;
  width: max-content;
  min-width: auto;
  /* dv_select.css `.dv-pop` also caps max-width at min(24rem,92vw)=384px and
     max-height at 320px; both bleed onto this shared class. 384px is narrower
     than the two months (540px), so with flex nowrap they'd shrink to ~half
     size — the "cramped / design gone" look. Clear both caps. */
  max-width: none;
  max-height: none;
  overflow: visible;
}
/* Scoped to the popover — `.cal` / `.cals` are generic enough to collide with
   unrelated markup (e.g. the booking ticketband's `<span class="cal">`), so they
   must never leak as bare global selectors. */
/* #291 — nowrap so the two months always sit side by side. With flex-wrap:wrap
   a wrapping flex container resolves `width:max-content` to ~one month wide, so
   the second month wrapped below and overflowed the popover. nowrap makes
   max-content sum both months, and the wizard is wide enough to show them. */
.os-pop--cal :is(.cals, .os-cals) { display: flex; gap: 20px; flex-wrap: nowrap; }
.os-pop--cal :is(.cal, .os-cal) { width: 260px; padding: 6px; }
:is(.cal__head, .os-cal__head) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 6px 10px;
}
:is(.cal__title, .os-cal__title) { font-size: var(--text-sm); font-weight: 600; color: var(--text-primary); }
:is(.cal__nav, .os-cal__nav) {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  border: none;
  background: transparent;
}
:is(.cal__nav, .os-cal__nav):hover { background: var(--surface-alt); color: var(--text-primary); }
:is(.cal__nav, .os-cal__nav):disabled, :is(.cal__nav, .os-cal__nav).is-hidden { visibility: hidden; }
:is(.cal__grid, .os-cal__grid) { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
:is(.cal__dow, .os-cal__dow) {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  text-align: center;
  padding: 4px 0;
}
:is(.cal__day, .os-cal__day) {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-primary);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
:is(.cal__day, .os-cal__day).is-empty { cursor: default; }
:is(.cal__day, .os-cal__day):not(.is-empty):hover { background: var(--surface-alt); }
:is(.cal__day, .os-cal__day).is-muted { color: var(--border-strong); }
/* before today — lighter, but STILL selectable (not disabled) */
:is(.cal__day, .os-cal__day).is-past { color: #9CA3AF; }
:is(.cal__day, .os-cal__day).is-today { font-weight: 700; color: var(--accent); }
:is(.cal__day, .os-cal__day).is-sel { background: var(--accent); color: #fff; font-weight: 600; }
:is(.cal__day, .os-cal__day).is-range { background: var(--accent-light); color: var(--accent-strong); border-radius: 0; }
:is(.cal__day, .os-cal__day).is-range:is(.r-start, .os-r-start) { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
:is(.cal__day, .os-cal__day).is-range:is(.r-end, .os-r-end) { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
/* keyboard focus cursor */
:is(.cal__day, .os-cal__day).is-focus { box-shadow: inset 0 0 0 2px var(--accent); }
/* keyboard focus cursor on the selected day shouldn't double up the ring */
:is(.cal__day, .os-cal__day).is-sel.is-focus { box-shadow: inset 0 0 0 2px #fff; }
/* ── Time row (only for include-time fields) ──
   Ported from tmp/form-elements-preview.html (.dv-time / .dv-seg / .dv-ampm).
   Reused standalone by fields--time (dv_timepicker via @import of this file). */
:is(.cal__time, .os-cal__time) {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 6px 2px;
  margin-top: 8px;
  border-top: 1px solid var(--border);
}
:is(.cal__time-label, .os-cal__time-label) { font-size: var(--text-xs); font-weight: 600; color: var(--text-muted); }
/* ── .dv-time component (HH:MM segment + AM/PM toggle) ──
   Sizing knobs, settable on any ancestor: --os-time-h (control height,
   default 38px; set it to your text fields' height so the picker lines up)
   and --os-time-box-w (each HH / MM box, default 32px). On phones the
   control lifts to the 48px touch target whatever the knobs say. */
.os-time { display: inline-flex; align-items: center; gap: 10px; width: -moz-max-content; width: max-content; }
.os-seg {
  flex: 0 0 auto;        /* don't stretch/shrink inside a form flex/grid cell */
  display: inline-flex;
  align-items: center;
  width: -moz-max-content;
  width: max-content;
  height: var(--os-time-h, 38px);
  padding: 0 6px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  transition: border-color .12s, box-shadow .12s;
}
.os-seg:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.os-seg input {
  flex: 0 0 auto;        /* never collapse below content width */
  width: var(--os-time-box-w, 32px);
  min-width: var(--os-time-box-w, 32px);
  box-sizing: content-box;
  padding: 0;
  text-align: center;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: var(--text-md);
  height: 100%;
  color: var(--text-primary);
  background: transparent;
  -moz-appearance: textfield;
}
.os-seg input::-webkit-outer-spin-button, .os-seg input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.os-seg__c { color: var(--text-muted); font-size: var(--text-md); }
.os-ampm {
  display: inline-flex;
  height: var(--os-time-h, 38px);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.os-ampm button {
  border: none;
  background: var(--surface);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  padding: 0 16px;
  cursor: pointer;
  color: var(--text-muted);
  transition: background .12s, color .12s;
}
.os-ampm button + button { border-left: 1px solid var(--border-strong); }
.os-ampm button:is(.on, .os-on) { background: var(--accent); color: #fff; }
.os-ampm button:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--focus-ring);
}
@media (max-width: 640px) {
  :is(.os-seg, .os-ampm) { height: max(var(--os-time-h, 38px), 48px); }
  .os-seg input { width: max(var(--os-time-box-w, 32px), 40px); min-width: max(var(--os-time-box-w, 32px), 40px); }
  .os-seg input, .os-seg__c { font-size: var(--text-lg); }
  .os-ampm button { padding: 0 20px; }
}
/* Hidden native time input — stays the submission source of truth. */
.os-time__native {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* ── Footer (clear) ── */
:is(.cal__foot, .os-cal__foot) {
  display: flex;
  justify-content: flex-end;
  padding: 8px 6px 2px;
  margin-top: 8px;
  border-top: 1px solid var(--border);
}
:is(.cal__clear, .os-cal__clear) {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
}
:is(.cal__clear, .os-cal__clear):hover { background: var(--surface-alt); color: var(--text-primary); }
/* dv-fileupload — custom DS file upload, drop zone + file rows
   (controllers/fields/file_field_controller.js). Re-skins native file input. */
/* ── dv-fileupload ──────────────────────────────────────────────────────────
   Custom design-system file upload. Progressive enhancement of a native
   <input type="file">: the native input stays in the DOM (source of truth for
   submit / direct-upload) and is visually hidden; this drop zone + file rows
   are layered on top and kept in sync by the fields--file-field controller.
   Ported from tmp/form-elements-preview.html (.dv-upload / .dv-file). Token-only.
   ────────────────────────────────────────────────────────────────────────── */
/* Drop zone — click target + drag-and-drop surface. Default size is centered;
   --sm / --md modifiers are left-aligned, horizontal, and progressively
   smaller for use in tighter form layouts. */
.os-upload {
  position: relative;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--canvas);
  min-height: 104px;
  padding: 18px;
  cursor: pointer;
  transition: border-color .12s, background .12s;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 8px;
}
.os-upload:hover, .os-upload.is-dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.os-upload:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.os-upload__icon {
  color: var(--accent);
  background: var(--accent-light);
  border-radius: var(--radius-sm);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.os-upload__icon :is(.lucide, .os-lucide) { display: block; }
.os-upload__t {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-primary);
}
.os-upload__t b { color: var(--accent); font-weight: 600; }
.os-upload__h {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}
/* --md — horizontal, left-aligned, no hint growth beyond the row height. */
.os-upload--md {
  min-height: 68px;
  padding: 12px 16px;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  text-align: left;
  gap: 12px;
}
.os-upload--md .os-upload__icon {
  width: 38px;
  height: 38px;
}
.os-upload--md .os-upload__h { margin-top: 2px; }
/* --sm — compact single row, icon + inline label, no hint line. */
.os-upload--sm {
  min-height: 44px;
  padding: 0 14px;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  text-align: left;
  gap: 8px;
}
.os-upload--sm .os-upload__icon {
  width: 26px;
  height: 26px;
}
.os-upload--sm .os-upload__t {
  font-size: var(--text-xs);
}
.os-upload--sm .os-upload__h {
  display: none;
}
/* Uploaded / to-upload file row. */
.os-file {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.os-file__ic { color: var(--accent); display: flex; flex-shrink: 0; }
.os-file__ic :is(.lucide, .os-lucide) { display: block; }
/* Image preview thumbnail — shown in place of the generic file icon when the
   picked/persisted file is an image, so the diver can confirm the right photo
   is selected (not just its filename). */
.os-file__thumb {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  -o-object-fit: cover;
     object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-alt);
  display: block;
}
.os-file__nm {
  font-size: var(--text-sm);
  flex: 1;
  min-width: 0;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.os-file__sz {
  font-size: var(--text-xs);
  color: var(--text-muted);
  flex-shrink: 0;
}
/* Action affordances on a row (download link, remove/cancel buttons). */
.os-file__act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  flex-shrink: 0;
  border: none;
  background: transparent;
  transition: color .12s, background .12s;
}
.os-file__act:hover {
  color: var(--accent-strong);
  background: var(--surface-alt);
}
.os-file__act :is(.lucide, .os-lucide) { display: block; }
/* When a persisted file is flagged for removal, dim the row. */
.os-file.is-removing {
  opacity: .55;
}
.os-file.is-removing .os-file__nm {
  text-decoration: line-through;
}
/* Upload progress bar (preserved from the gem markup). */
.os-upload-progress {
  margin-top: 8px;
  overflow: hidden;
  font-size: var(--text-xs);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  position: relative;
}
.os-upload-progress__bar {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  white-space: nowrap;
  overflow: hidden;
  background: var(--accent);
  border-radius: var(--radius-sm);
}
.os-upload-progress__label {
  position: relative;
  text-align: center;
  color: var(--text-secondary);
  padding: 2px 0;
}
/* New Booking wizard (v2) promoted components: WizardBars + WizardFooter,
   the cool blue-gray Summary Card, and the day-itinerary band + add-date
   control. Token-driven; scoped-var exceptions documented in each file.
   The gem's wizard-footer.css loads first, for its viewport-pinned variant
   (`.os-wz-foot--pinned`, the public waiver); its base bar rules sit BEFORE
   wizard.css + wizard-mobile.css so the staff pane wizard's ≤640px footer
   overrides still win. */
/* ─────────────────────────────────────────────────────────────────────
   wizard-footer.css — .os-wz-foot : the canonical WIZARD FOOTER, a sticky
   three-zone action bar (start · center · end) for a multi-step flow.

   Zones: START (Back + a destructive Discard/exit), CENTER (hint), END
   (running total + primary/secondary actions). Buttons are the gem's
   `.os-btn` family; this component owns the bar chrome + the total + the
   quiet destructive text-link. Pairs with `shared/patterns/_wizard_footer`.

   Token-driven; sits at the bottom of a scrolling wizard body (e.g. inside
   `.os-wz-couple`). No prefix but `.os-*`.
   ───────────────────────────────────────────────────────────────────── */
.os-wz-foot {
  position: sticky; bottom: 0; z-index: 20; background: var(--surface);
  border-top: 1px solid var(--hairline); box-shadow: 0 -1px 2px rgba(17, 24, 39, 0.03);
}
/* Full-width action row — the zones sit at the pane edges (with the band
   inset); a 1fr/auto/1fr grid keeps CENTER centred regardless of side widths. */
.os-wz-foot-inner {
  margin: 0 auto; padding: 14px 40px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
}
.os-wz-foot .os-grp { display: flex; align-items: center; gap: 10px; }
.os-wz-foot .os-grp.os-start { justify-self: start; }
.os-wz-foot .os-grp.os-center { justify-self: center; }
.os-wz-foot .os-grp.os-end { justify-self: end; }
/* Hairline divider between Back and the destructive Discard link. */
.os-wz-foot-sep {
  display: inline-block; width: 1px; align-self: stretch; min-height: 20px;
  margin: 0 2px; background: var(--hairline-strong);
}
/* Quiet, never-filled destructive text-link (the Discard/exit). Reuses the
   `.os-btn--ghost` transparent base and only recolours it. */
.os-btn-destructive { color: var(--cancelled); }
.os-btn-destructive:hover { color: var(--cancelled); }
.os-btn--ghost.os-btn-destructive:hover { background: var(--cancelled-bg); }
/* Optional hint (keyboard shortcut / requirement / autosave note). The
   partial's `hint:` puts it in the START zone, after Back. */
.os-wz-foot-hint { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }
.os-wz-foot-hint .os-kbd { font-family: var(--font-mono); font-size: var(--text-xs); padding: 2px 6px; background: var(--gray-100); border: 1px solid var(--hairline); border-radius: 4px; color: var(--muted); }
.os-wz-foot .os-grp.os-start .os-wz-foot-hint { margin-left: var(--space-2); }
.os-wz-foot .os-grp.os-start .os-wz-foot-hint:first-child { margin-left: 0; }
.os-wz-foot-hint .os-req { display: inline-flex; align-items: center; gap: 6px; color: var(--briefing); font-weight: 600; }
/* Running total in the END zone. */
.os-wz-foot .os-total { display: flex; align-items: baseline; gap: 9px; margin-right: 4px; }
.os-wz-foot .os-total .os-k { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.os-wz-foot .os-total .os-v { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: 500; color: var(--ink); letter-spacing: -0.01em; }
/* ── Pinned variant: `.os-wz-foot--pinned` (partial local `pin: :viewport`) ──
   For a wizard that lives on an ordinary SCROLLING PAGE (no full-height
   `.os-wz-couple` shell), e.g. a public waiver. The action bar is fixed to the
   viewport's bottom edge on every step, short or long, at every width, and
   stays there to the very end of the page (it covers the site footer — the
   form's actions matter more). It stays put on phones too, where the pane
   wizard's wizard-mobile.css turns a plain footer static.

   - Full-bleed band, constrained contents: the white band + top hairline run
     edge to edge; the buttons sit inside `--os-wz-foot-max` (the page's shell
     width, default: no cap), centred, never closer than `--os-wz-foot-gutter`
     (default 16px) to the viewport edge.
   - `.os-wz-foot` itself stays in the flow as a placeholder exactly the bar's
     height (same variables as the bar), so the last field scrolls clear of it.
   - Focus and scroll-into-view stop short of the bar (WCAG 2.4.11).
   - Safe-area inset under the bar on phones. */
.os-wz-foot.os-wz-foot--pinned {
  position: static; z-index: auto;
  background: transparent; border-top: 0; box-shadow: none;
  height: calc(var(--control-h) + 29px + env(safe-area-inset-bottom));
}
.os-wz-foot.os-wz-foot--pinned .os-wz-foot-inner {
  position: fixed; inset: auto 0 0 0; z-index: var(--z-tooltip); margin: 0;
  padding: 14px max(var(--os-wz-foot-gutter, 16px), (100% - var(--os-wz-foot-max, 100%)) / 2)
           calc(14px + env(safe-area-inset-bottom));
  background: var(--surface); border-top: 1px solid var(--hairline);
  box-shadow: 0 -1px 2px rgba(17, 24, 39, 0.03);
}
html:has(.os-wz-foot--pinned) {
  scroll-padding-bottom: calc(var(--control-h-touch) + var(--space-12) + env(safe-area-inset-bottom));
}
/* Compact controls (`compact: true` on `back:` or an action): at phone width
   the button goes icon-only, a square touch target; its text stays in the DOM
   as the accessible name (visually hidden) and as the `title` tooltip. */
.os-wz-foot-label { display: contents; }
.os-wz-foot-short { display: none; }
/* `amount:` — the running total folded into the primary (phone, pinned). */
.os-wz-foot-amt { display: none; }
.os-wz-foot .os-wz-foot-compact { position: relative; }
.os-wz-foot .os-btn { position: relative; }
@media (max-width: 640px) {
  /* One row: Back on the left, the primary hugging its label on the right, and
     the secondary/tertiary actions centred in the free space between them, so
     neither edge button has a neighbour to mis-tap (the gaps either side are
     equal). Targets keep a 12px gap. The hint becomes a minimal left-aligned
     caption line across the top of the bar (the start zone dissolves so the hint can
     take its own row). */
  .os-wz-foot.os-wz-foot--pinned {
    height: calc(var(--control-h-touch) + 23px + env(safe-area-inset-bottom));
  }
  .os-wz-foot.os-wz-foot--pinned .os-wz-foot-inner {
    display: flex; flex-wrap: nowrap; align-items: center; gap: var(--space-3);
    padding: 10px var(--os-wz-foot-gutter, 16px) calc(12px + env(safe-area-inset-bottom));
    box-shadow: 0 -4px 16px -8px rgba(2, 6, 23, 0.12);
  }
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-center { display: none; }
  /* Only a hint wraps the row (it takes its own line on top). Back and the
     end zone always share ONE row: the end zone's 0 basis means it never
     pushes itself onto a second line; it then grows into the room Back leaves
     and the primary's label truncates (below) instead of wrapping. */
  .os-wz-foot.os-wz-foot--pinned:has(.os-wz-foot-hint) .os-wz-foot-inner { flex-wrap: wrap; row-gap: var(--space-2); }
  .os-wz-foot.os-wz-foot--pinned .os-wz-foot-inner > .os-grp.os-start { display: contents; }
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-start .os-wz-foot-hint {
    order: -1; flex: 0 0 100%; justify-content: flex-start; margin: 0; line-height: 16px;
  }
  .os-wz-foot.os-wz-foot--pinned:has(.os-wz-foot-hint) {
    height: calc(var(--control-h-touch) + 23px + 16px + var(--space-2) + env(safe-area-inset-bottom));
  }
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-end { flex: 1 1 0%; min-width: 0; gap: var(--space-3); align-items: center; }
  /* Selectors carry the extra `:is(.os-start, .os-end)` / `.os-btn` weight to
     beat the pane wizard's ≤640 footer rules (wizard-mobile.css). */
  .os-wz-foot.os-wz-foot--pinned .os-grp:is(.os-start, .os-end) .os-btn {
    flex: 0 0 auto; width: auto; height: var(--control-h-touch); font-size: var(--text-sm);
  }
  /* Hugs its label, but shrinks rather than run over Back when a long label +
     folded total outgrow the row: the label (`.os-wz-foot-text`, or the
     short_label text) ellipsizes; the icon and the amount keep their size. */
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-end .os-btn.os-btn--primary {
    flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap;
    margin-left: auto; padding-inline: var(--space-5); justify-content: center; font-size: var(--text-md);
  }
  .os-wz-foot.os-wz-foot--pinned .os-btn--primary > * { flex: none; }
  .os-wz-foot.os-wz-foot--pinned .os-btn--primary > :is(.os-wz-foot-text, .os-wz-foot-short) {
    flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-end > .os-btn:not(.os-btn--primary):first-child { margin-left: auto; }
  .os-wz-foot.os-wz-foot--pinned .os-wz-foot-amt:not(:empty) {
    display: inline; margin-left: var(--space-2); padding-left: var(--space-2);
    border-left: 1px solid currentColor; font-family: var(--font-mono); font-weight: 600; font-size: var(--text-sm);
  }
  /* Back stays an outlined button (the pane wizard flattens it to a text link). */
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-start .os-btn.os-btn--secondary {
    background: var(--surface); border: 1px solid var(--interactive-border); color: var(--interactive); padding-inline: var(--space-3);
  }
  /* Secondary/tertiary text actions shed their trailing icon and tighten, so
     four controls fit a 370px phone with the primary keeping its arrow. */
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-end :is(.os-btn--secondary, .os-btn--ghost):not(.os-wz-foot-compact) { padding-inline: var(--space-3); }
  .os-wz-foot.os-wz-foot--pinned .os-grp.os-end :is(.os-btn--secondary, .os-btn--ghost):not(.os-wz-foot-compact) svg { display: none; }

  .os-wz-foot .os-grp:is(.os-start, .os-end) .os-btn.os-btn.os-wz-foot-compact {
    flex: 0 0 var(--control-h-touch); width: var(--control-h-touch); min-width: var(--control-h-touch);
    height: var(--control-h-touch); padding: 0; gap: 0; justify-content: center;
  }
  .os-wz-foot .os-wz-foot-compact .os-wz-foot-label {
    display: block; position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
}
/* `short_label:` — the full label fits from ~420px (Back + Skip + "Save &
   Exit" + the primary, with the centring gaps); on narrower phones the short
   text shows and the full label stays the accessible name. */
@media (max-width: 419px) {
  .os-wz-foot .os-wz-foot-short { display: inline; }
  .os-wz-foot .os-btn .os-wz-foot-label--long {
    display: block; position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
}
/* Typing on a phone: while a text field has focus the on-screen keyboard is
   up, and a fixed bar would sit behind it (iOS) or ride on top of it eating
   the view (Android). The bar steps aside until the field blurs; its
   placeholder keeps the layout still. Touch phones only (a narrow desktop
   window keeps the bar). */
@media (max-width: 640px) and (pointer: coarse) {
  html:has(:is(input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"], [type="reset"], [type="file"], [type="range"], [type="color"], [type="hidden"]), textarea, [contenteditable="true"]):focus) .os-wz-foot.os-wz-foot--pinned .os-wz-foot-inner {
    visibility: hidden;
  }
}
/* ============================================================
   wizard.css — the ONE DiveOS wizard pattern stylesheet.
   Self-contained on the bound DS tokens (_ds/styles.css). Ports the
   canonical Dive Plan / Trip Run chrome — white header band → stepper
   → gray body → ledger-first lists → readiness gate → sticky footer —
   so the Booking wizard is a literal visual sibling of those screens.
   The DS React components (Button, Input, Select, Avatar, …) sit INSIDE
   this chrome; this file only styles the wizard skeleton + booking rows.
   ============================================================ */
/* ── Wizard chrome scope ─────────────────────────────────────
   The prototype's global html/body/input resets are intentionally DROPPED:
   the booking wizard mounts INSIDE the DiveOS app layout, which already owns
   body typography, color, and smoothing. We only style the wizard's own
   chrome (scoped to .wz-shell) so nothing leaks to the rest of the app. */
:root {
  --wz-copy-ico: var(--muted-2); --wz-del-ico: var(--muted-2);
  /* near-white row/footer hover + diver-card head — no ramp token is this warm */
  --wz-tint: #FCFCFB;
  --wz-tint-2: #FBFCFD;
}
:is(.wz-shell, .os-wz-shell), :is(.wz-main, .os-wz-main), :is(.wz-shell, .os-wz-shell) input, :is(.wz-shell, .os-wz-shell) textarea, :is(.wz-shell, .os-wz-shell) select, :is(.wz-shell, .os-wz-shell) button {
  font-family: var(--font-sans);
  font-feature-settings: var(--font-features, normal);
}
:is(.wz-shell, .os-wz-shell) { display: flex; flex-direction: column; min-width: 0; background: var(--canvas); }
:is(.wz-main, .os-wz-main) { flex: 1; min-width: 0; display: flex; flex-direction: column; background: var(--canvas); }
/* Inside the full-bleed shell the wizard is a fixed-height flex column:
   stepper (fixed) → .wz-body (scrolls) → footer (pinned at the bottom).
   The <form> wraps the body + footers, so it must be display:contents for
   them to participate as flex children of .wz-flow. */
:is(.wz-flow, .os-wz-flow) { display: flex; flex-direction: column; flex: 1; min-height: 0; }
:is(.wz-flow, .os-wz-flow) > form { display: contents; }
/* ── Stepper (horizontal, connected) — lifted from .dp-stepper ── */
:is(.wz-stepper, .os-wz-stepper) { width: 100%; }
:is(.wz-steps, .os-wz-steps) { display: flex; max-width: var(--content-max); margin: 0 auto; }
:is(.wz-step, .os-wz-step) { flex: 1; position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 11px; cursor: pointer; background: none; border: 0; font: inherit; padding: 2px 0 2px; }
:is(.wz-step, .os-wz-step)::before { content: ''; position: absolute; top: 20px; right: calc(50% + 30px);
  width: calc(100% - 60px); height: 2px; background: var(--hairline); z-index: 0; }
:is(.wz-step, .os-wz-step):first-child::before { display: none; }
:is(.wz-step, .os-wz-step):is(.done, .os-done)::before, :is(.wz-step, .os-wz-step):is(.active, .os-active)::before { background: var(--accent); }
:is(.wz-dot, .os-wz-dot) { position: relative; z-index: 1; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-family: var(--font-mono);
  font-weight: 600; font-size: var(--text-sm); border: 2px solid var(--hairline); color: var(--muted-2);
  background: var(--surface); transition: all .15s ease; }
:is(.wz-step, .os-wz-step):is(.done, .os-done) :is(.wz-dot, .os-wz-dot) { background: var(--accent); border-color: var(--accent); color: var(--surface); }
:is(.wz-step, .os-wz-step):is(.active, .os-active) :is(.wz-dot, .os-wz-dot) { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
:is(.wz-step, .os-wz-step):not(:is(.reach, .os-reach)):hover :is(.wz-dot, .os-wz-dot) { }
:is(.wz-step, .os-wz-step):is(.reach, .os-reach):hover :is(.wz-dot, .os-wz-dot) { border-color: var(--accent); }
:is(.wz-step-label, .os-wz-step-label) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-2); }
:is(.wz-step, .os-wz-step):is(.done, .os-done) :is(.wz-step-label, .os-wz-step-label) { color: var(--muted); }
:is(.wz-step, .os-wz-step):is(.active, .os-active) :is(.wz-step-label, .os-wz-step-label) { color: var(--accent); }
:is(.wz-step, .os-wz-step)[disabled] { cursor: default; }
/* ── Vertical spine stepper — lifted from .dp-spine ──────────── */
:is(.wz-spine-grid, .os-wz-spine-grid) { display: grid; grid-template-columns: 232px minmax(0,1fr); gap: 32px; align-items: start; }
@media (max-width: 1080px) { :is(.wz-spine-grid, .os-wz-spine-grid) { grid-template-columns: 1fr; } }
:is(.wz-spine, .os-wz-spine) { position: sticky; top: 24px; }
:is(.wz-vsteps, .os-wz-vsteps) { display: flex; flex-direction: column; }
:is(.wz-vstep, .os-wz-vstep) { display: flex; align-items: flex-start; gap: 14px; padding: 0 0 26px; position: relative;
  cursor: pointer; background: none; border: 0; font: inherit; text-align: left; width: 100%; }
:is(.wz-vstep, .os-wz-vstep):last-child { padding-bottom: 0; }
:is(.wz-vstep, .os-wz-vstep)::before { content: ''; position: absolute; left: 16px; top: 34px; bottom: 2px; width: 2px; background: var(--hairline); }
:is(.wz-vstep, .os-wz-vstep):last-child::before { display: none; }
:is(.wz-vstep, .os-wz-vstep):is(.done, .os-done)::before, :is(.wz-vstep, .os-wz-vstep):is(.active, .os-active)::before { background: var(--accent); }
:is(.wz-vstep, .os-wz-vstep) :is(.wz-dot, .os-wz-dot) { width: 34px; }
:is(.wz-vstep-body, .os-wz-vstep-body) { display: flex; flex-direction: column; gap: 2px; padding-top: 5px; }
:is(.wz-vstep-label, .os-wz-vstep-label) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted-2); }
:is(.wz-vstep, .os-wz-vstep):is(.done, .os-done) :is(.wz-vstep-label, .os-wz-vstep-label) { color: var(--muted); }
:is(.wz-vstep, .os-wz-vstep):is(.active, .os-active) :is(.wz-vstep-label, .os-wz-vstep-label) { color: var(--accent); }
:is(.wz-vstep-sub, .os-wz-vstep-sub) { font-size: var(--text-xs); color: var(--muted-2); }
:is(.wz-vstep, .os-wz-vstep)[disabled] { cursor: default; }
/* ── Sleek segmented bar stepper (layout="bars") ───────────── */
:is(.wz-bars, .os-wz-bars) { width: 100%; max-width: var(--content-max); margin-inline: auto; }
:is(.wz-bars-inner, .os-wz-bars-inner) { display: flex; gap: 10px; max-width: var(--content-max); margin: 0 auto; }
:is(.wz-seg, .os-wz-seg) { flex: 1; display: flex; flex-direction: column; gap: 9px; min-width: 0; background: none; border: 0; padding: 0; cursor: default; font: inherit; }
:is(.wz-seg, .os-wz-seg) :is(.bar, .os-bar) { height: 4px; border-radius: 4px; background: var(--hairline); transition: background .25s cubic-bezier(.22,1,.36,1), height .15s ease, box-shadow .15s ease; }
:is(.wz-seg, .os-wz-seg):is(.done, .os-done) :is(.bar, .os-bar), :is(.wz-seg, .os-wz-seg):is(.on, .os-on) :is(.bar, .os-bar) { background: var(--accent); }
:is(.wz-seg, .os-wz-seg):is(.on, .os-on) :is(.bar, .os-bar) { height: 6px; box-shadow: 0 0 0 3px var(--accent-softer); }
:is(.wz-seg, .os-wz-seg) :is(.lbrow, .os-lbrow) { display: flex; align-items: center; gap: 5px; min-width: 0; }
:is(.wz-seg, .os-wz-seg) :is(.lb, .os-lb) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color .12s ease; }
:is(.wz-seg, .os-wz-seg):is(.done, .os-done) :is(.lb, .os-lb) { color: var(--muted); }
:is(.wz-seg, .os-wz-seg):is(.on, .os-on) :is(.lb, .os-lb) { color: var(--accent); font-weight: 700; }
/* The check pip is always in the markup (the Stimulus controller only toggles
   state classes, never rebuilds the segment) — show it ONLY on completed steps. */
:is(.wz-seg, .os-wz-seg) :is(.tk, .os-tk) { display: none; align-items: center; justify-content: center; width: 13px; height: 13px; border-radius: 50%; background: var(--accent); color: var(--surface); flex-shrink: 0; }
:is(.wz-seg, .os-wz-seg):is(.done, .os-done) :is(.tk, .os-tk) { display: inline-flex; }
:is(.wz-seg, .os-wz-seg):is(.on, .os-on) :is(.lbrow, .os-lbrow)::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
:is(.wz-seg, .os-wz-seg):is(.nav, .os-nav) { cursor: pointer; }
:is(.wz-seg, .os-wz-seg):is(.nav, .os-nav):hover :is(.bar, .os-bar) { background: var(--accent); }
:is(.wz-seg, .os-wz-seg):is(.done, .os-done):is(.nav, .os-nav):hover :is(.bar, .os-bar) { background: var(--accent-strong); }
:is(.wz-seg, .os-wz-seg):is(.nav, .os-nav):hover :is(.lb, .os-lb) { color: var(--ink); }
:is(.wz-seg, .os-wz-seg):is(.done, .os-done):is(.nav, .os-nav):hover :is(.lb, .os-lb) { color: var(--accent); }
/* Keyboard focus ring — the segments are real <button>s now (#85); match the
   wizard's house focus idiom rather than the bare UA outline. */
:is(.wz-seg, .os-wz-seg):focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); border-radius: 6px; }
/* ── Header ↔ wizard coupling variants (the `coupling` prop) ── */
/* width:100% so that inside the flex-column .wz-flow the auto side-margins
   don't override align-items:stretch and shrink-wrap the stepper. */
/* The couple is a full-width header BAND (like .wz-foot) so its bottom separator
   spans the whole pane edge-to-edge; the stepper CONTENT self-centers at the
   reading width via .wz-bars / .wz-bars-inner. Capping the couple at
   --content-max clipped the separator to 768px and centred it, leaving dead
   gutters. (full-bleed separator fix) */
:is(.wz-couple, .os-wz-couple) { width: 100%; margin: 0 auto; padding: 0 40px; }
:is(.wz-couple-detached, .os-wz-couple-detached) { padding-top: 22px; padding-bottom: 4px; }
:is(.wz-pills, .os-wz-pills) { display: flex; align-items: center; gap: 4px; max-width: 720px; margin: 0 auto;
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-pill);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); padding: 7px 10px; }
:is(.wz-pill, .os-wz-pill) { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 34px;
  font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--muted); background: none; border: 0; border-radius: var(--radius-pill); cursor: default; white-space: nowrap; }
:is(.wz-pill, .os-wz-pill) :is(.num, .os-num) { width: 19px; height: 19px; border-radius: 50%; display: grid; place-items: center; font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; background: var(--gray-200); color: var(--muted); }
:is(.wz-pill, .os-wz-pill):is(.done, .os-done) { color: var(--gray-700); }
:is(.wz-pill, .os-wz-pill):is(.done, .os-done) :is(.num, .os-num) { background: var(--accent); color: var(--surface); }
:is(.wz-pill, .os-wz-pill):is(.on, .os-on) { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
:is(.wz-pill, .os-wz-pill):is(.on, .os-on) :is(.num, .os-num) { background: var(--accent); color: var(--surface); }
:is(.wz-pill, .os-wz-pill):is(.nav, .os-nav) { cursor: pointer; }
:is(.wz-pill, .os-wz-pill):is(.nav, .os-nav):hover { background: var(--surface-alt); }
:is(.wz-pillsep, .os-wz-pillsep) { width: 14px; height: 1px; background: var(--hairline); flex-shrink: 0; }
/* card (V4) — stepper in a card atop the content */
:is(.wz-couple-card, .os-wz-couple-card) { padding-top: 40px; padding-bottom: 6px; }
:is(.wz-couple-card, .os-wz-couple-card) > :is(.wz-bars, .os-wz-bars) { max-width: 720px; margin: 0 auto; background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-lg); box-shadow: 0 1px 2px rgba(17,24,39,.04); padding: 16px 24px; box-sizing: border-box; }
:is(.wz-couple-card, .os-wz-couple-card):is(.bare, .os-bare) > :is(.wz-bars, .os-wz-bars) { background: transparent; border: 0; box-shadow: none; padding: 4px 0; }
/* Breathing room above the stepper at rest. The stepper is a fixed flex-child
   above the scrolling .wz-body, so once the body scrolls we collapse the margin
   to keep the stepper flush at the top. pos-wizard toggles .is-scrolled from a
   scroll listener on .wz-body. Scoped to .wz-flow so the showcase stepper is
   unaffected. */
:is(.wz-flow, .os-wz-flow) > :is(.wz-couple, .os-wz-couple) { margin-top: 2rem; transition: margin-top .2s ease;
  /* The page separator is semantically the sticky stepper's bottom edge — it
     belongs to the fixed header region, not the scrolling body. The gap below
     the stepper is carried here as padding-bottom (1.25rem, matching the theme
     space-y margin we strip off .wz-body), so the hairline lands AFTER that gap,
     just above the body content rather than hugging the stepper. Always on. (#129) */
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--hairline); }
:is(.wz-flow, .os-wz-flow) > :is(.wz-couple, .os-wz-couple).is-scrolled { margin-top: 0; }
/* header-right tracker (V3) */
:is(.wz-hr-cluster, .os-wz-hr-cluster) { display: flex; flex-direction: column; align-items: flex-end; gap: 14px; }
:is(.wz-track, .os-wz-track) { display: flex; align-items: center; gap: 0; }
:is(.wz-tstep, .os-wz-tstep) { display: flex; flex-direction: column; align-items: center; gap: 6px; background: none; border: 0; padding: 0; cursor: default; font: inherit; }
:is(.wz-tstep, .os-wz-tstep):is(.nav, .os-nav) { cursor: pointer; }
:is(.wz-tnum, .os-wz-tnum) { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; border: 1.5px solid var(--hairline); color: var(--muted-2); background: var(--surface); }
:is(.wz-tstep, .os-wz-tstep):is(.done, .os-done) :is(.wz-tnum, .os-wz-tnum) { background: var(--accent); border-color: var(--accent); color: var(--surface); }
:is(.wz-tstep, .os-wz-tstep):is(.on, .os-on) :is(.wz-tnum, .os-wz-tnum) { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 0 3px var(--accent-softer); }
:is(.wz-tlbl, .os-wz-tlbl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-2); }
:is(.wz-tstep, .os-wz-tstep):is(.on, .os-on) :is(.wz-tlbl, .os-wz-tlbl) { color: var(--accent); }
:is(.wz-tstep, .os-wz-tstep):is(.done, .os-done) :is(.wz-tlbl, .os-wz-tlbl) { color: var(--muted); }
:is(.wz-tconn, .os-wz-tconn) { width: 28px; height: 1.5px; background: var(--hairline); margin: 0 2px 18px; }
:is(.wz-tconn, .os-wz-tconn):is(.done, .os-done) { background: var(--accent); }
/* ── Gray body + centered inner column — lifted from .dp-body ── */
/* scrollbar-gutter: stable reserves the scrollbar track always, so the body
   width doesn't reflow when the vertical scrollbar appears/disappears — the
   other axis of the #129 stepper bounce. */
:is(.wz-body, .os-wz-body) { flex: 1; min-height: 0; overflow-y: auto; scrollbar-gutter: stable; background: var(--canvas); }
/* Strip the theme's form-divide utility (form.form > :not([hidden]) ~
   :not([hidden])) off .wz-body — form_with's hidden CSRF/method inputs make
   .wz-body a subsequent sibling, so it otherwise inherits BOTH a border-top and
   a 1.25rem margin-top. The separator + that gap now live on the sticky stepper
   (see .wz-flow > .wz-couple: padding-bottom + border-bottom). !important defeats
   that higher-specificity compiled vendor rule. (#129) */
:is(.wz-flow, .os-wz-flow) form:is(.form, .os-form) > :is(.wz-body, .os-wz-body) { margin-top: 0 !important; border-top: 0 !important; }
:is(.wz-inner, .os-wz-inner) { max-width: var(--content-max); margin: 0 auto; padding: 30px 40px 40px; }
:is(.wz-inner, .os-wz-inner):is(.narrow, .os-narrow) { max-width: 880px; }
/* ── Header eyebrow — mono "Bookings / New" breadcrumb ───────── */
:is(.wz-eyebrow, .os-wz-eyebrow) { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono);
  font-size: var(--text-xs); letter-spacing: 0.01em; margin-bottom: 6px; }
:is(.wz-eyebrow-crumb, .os-wz-eyebrow-crumb) { color: var(--muted); text-decoration: none; }
:is(.wz-eyebrow-crumb, .os-wz-eyebrow-crumb):hover { color: var(--ink); }
:is(.wz-eyebrow-sep, .os-wz-eyebrow-sep) { color: var(--muted-2); }
:is(.wz-eyebrow-cur, .os-wz-eyebrow-cur) { color: var(--accent); font-weight: 500; }
/* ── Stage intro ──────────────────────────────────────────── */
:is(.wz-stage-head, .os-wz-stage-head) { margin-bottom: 22px; }
:is(.wz-stage-head, .os-wz-stage-head) h2 { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl);
  letter-spacing: -0.015em; color: var(--ink); }
:is(.wz-stage-head, .os-wz-stage-head) p { margin: 7px 0 0; font-size: var(--text-sm); color: var(--muted); line-height: 1.5; max-width: 64ch; }
/* ── Section head (label ABOVE the ledger — no card-in-card) ── */
:is(.wz-sec-head, .os-wz-sec-head) { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
:is(.wz-sec-title, .os-wz-sec-title) { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
:is(.wz-sec-title, .os-wz-sec-title) :is(.t, .os-t) { font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); white-space: nowrap; }
:is(.wz-sec-title, .os-wz-sec-title) :is(.c, .os-c) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }
:is(.wz-sec-head, .os-wz-sec-head) :is(.a, .os-a) { font-size: var(--text-sm); font-weight: 500; color: var(--accent); cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; font-family: inherit; padding: 0; }
:is(.wz-sec-head, .os-wz-sec-head) :is(.a, .os-a):hover { color: var(--accent-strong); }
/* ── Ledger (single bordered frame for any list) — from .dp-ledger ── */
:is(.wz-ledger, .os-wz-ledger) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.wz-row, .os-wz-row) { display: grid; align-items: center; gap: 18px; padding: 16px 20px; position: relative;
  border-top: 1px solid var(--hairline-2); transition: background .12s ease; }
:is(.wz-row, .os-wz-row):first-child { border-top: 0; }
:is(.wz-row, .os-wz-row):is(.link, .os-link) { cursor: pointer; }
:is(.wz-row, .os-wz-row):is(.link, .os-link):hover { background: var(--wz-tint); }
:is(.wz-row, .os-wz-row)::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: transparent; }
:is(.wz-row, .os-wz-row):is(.rail-accent, .os-rail-accent)::before { background: var(--accent); }
/* ledger sub-head (group divider band inside a ledger) */
:is(.wz-grouphead, .os-wz-grouphead) { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 20px; background: var(--sky-50); border-top: 1px solid var(--hairline-2); }
:is(.wz-grouphead, .os-wz-grouphead):first-child { border-top: 0; }
:is(.wz-grouphead, .os-wz-grouphead) :is(.nm, .os-nm) { display: inline-flex; align-items: center; gap: 10px; font-size: var(--text-xs); font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); min-width: 0; }
:is(.wz-grouphead, .os-wz-grouphead) :is(.dts, .os-dts) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); font-weight: 400; letter-spacing: 0; text-transform: none; white-space: nowrap; }
:is(.wz-grouphead, .os-wz-grouphead) :is(.sub, .os-sub) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.wz-grouphead, .os-wz-grouphead):is(.warm, .os-warm) { background: var(--briefing-bg); }
:is(.wz-grouphead, .os-wz-grouphead):is(.warm, .os-warm) :is(.nm, .os-nm) { color: var(--briefing); }
/* ── Key/value block — from .dp-kv ──────────────────────────── */
/* stat strip — lifted from the DiveOS booking-detail .statstrip:
   General Sans 600 values, 10px tracked labels, hairline-2 dividers */
:is(.wz-kv, .os-wz-kv) { display: grid; grid-template-columns: 1fr 1fr 1fr; background: var(--surface);
  border: 1px solid var(--hairline); border-radius: var(--radius-lg); box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.wz-kv, .os-wz-kv) :is(.cell, .os-cell) { padding: 18px 22px; border-left: 1px solid var(--hairline-2); }
:is(.wz-kv, .os-wz-kv):is(.cols-3, .os-cols-3) :is(.cell, .os-cell):nth-child(3n+1) { border-left: 0; }
:is(.wz-kv, .os-wz-kv) :is(.k, .os-k) { display: flex; align-items: center; gap: 7px; font-size: var(--text-2xs); font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.wz-kv, .os-wz-kv) :is(.k, .os-k) :is(.ico, .os-ico) { color: var(--muted-2); }
:is(.wz-kv, .os-wz-kv) :is(.v, .os-v) { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.01em; line-height: 1.1; color: var(--ink); margin-top: 11px; }
:is(.wz-kv, .os-wz-kv) :is(.v, .os-v):is(.mono, .os-mono) { font-family: var(--font-mono); font-weight: 500; letter-spacing: -0.01em; }
:is(.wz-kv, .os-wz-kv) :is(.v, .os-v):is(.dash, .os-dash) { color: var(--muted-2); font-weight: 500; }
:is(.wz-kv, .os-wz-kv) :is(.v, .os-v):is(.nowrap, .os-nowrap) { white-space: nowrap; }
:is(.wz-kv, .os-wz-kv) :is(.sub, .os-sub) { font-family: var(--font-sans); font-size: var(--text-xs); color: var(--muted); font-weight: 400; margin-top: 7px; letter-spacing: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ── Readiness gate — from .dp-gate / .dp-req (Review + Payment) ── */
:is(.wz-gate, .os-wz-gate) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.wz-gate-head, .os-wz-gate-head) { display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 18px 22px; border-bottom: 1px solid var(--hairline); }
:is(.wz-gate-head, .os-wz-gate-head) :is(.t, .os-t) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink); }
:is(.wz-gate-head, .os-wz-gate-head) :is(.s, .os-s) { font-size: var(--text-sm); color: var(--muted); margin-top: 3px; }
:is(.wz-gate-head, .os-wz-gate-head) :is(.tot, .os-tot) { text-align: right; }
:is(.wz-gate-head, .os-wz-gate-head) :is(.tot, .os-tot) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.wz-gate-head, .os-wz-gate-head) :is(.tot, .os-tot) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-2xl); font-weight: 500; letter-spacing: -0.02em; color: var(--accent); margin-top: 2px; }
:is(.wz-req, .os-wz-req) { display: flex; align-items: center; gap: 12px; padding: 14px 22px; border-top: 1px solid var(--hairline-2); font-size: var(--text-sm); }
:is(.wz-req, .os-wz-req):first-of-type { border-top: 0; }
:is(.wz-req, .os-wz-req) :is(.tick, .os-tick) { width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
:is(.wz-req, .os-wz-req):is(.ok, .os-ok) :is(.tick, .os-tick) { background: var(--confirmed-bg); color: var(--confirmed); }
:is(.wz-req, .os-wz-req):is(.no, .os-no) :is(.tick, .os-tick) { background: var(--briefing-bg); color: var(--briefing); }
:is(.wz-req, .os-wz-req) :is(.rtxt, .os-rtxt) { color: var(--ink); }
:is(.wz-req, .os-wz-req) :is(.rtxt, .os-rtxt) b { font-weight: 600; }
:is(.wz-req, .os-wz-req) :is(.rstate, .os-rstate) { margin-left: auto; font-size: var(--text-xs); font-weight: 600; white-space: nowrap; font-family: var(--font-mono); }
:is(.wz-req, .os-wz-req):is(.ok, .os-ok) :is(.rstate, .os-rstate) { color: var(--confirmed); }
:is(.wz-req, .os-wz-req):is(.no, .os-no) :is(.rstate, .os-rstate) { color: var(--briefing); }
:is(.wz-gate-foot, .os-wz-gate-foot) { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 16px 22px; border-top: 1px solid var(--hairline); background: var(--wz-tint); }
/* ── Sticky footer (standardized Back / hint / Next) ─────────── */
:is(.wz-foot, .os-wz-foot) { position: sticky; bottom: 0; z-index: 20; background: var(--surface);
  border-top: 1px solid var(--hairline); box-shadow: 0 -1px 2px rgba(17,24,39,.03); }
/* Full-width button row so the actions sit at the pane edges (with the 40px
   band inset), matching the full-width footer band. Capping at --content-max
   pulled Back/Discard and Next toward the middle. (full-bleed footer fix) */
:is(.wz-foot-inner, .os-wz-foot-inner) { margin: 0 auto; padding: 14px 40px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px; }
:is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp) { display: flex; align-items: center; gap: 10px; }
:is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.start, .os-start) { justify-self: start; }
:is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.center, .os-center) { justify-self: center; }
:is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.end, .os-end) { justify-self: end; }
/* Hairline divider between Back and the destructive Discard link. */
:is(.wz-foot-sep, .os-wz-foot-sep) { display: inline-block; width: 1px; align-self: stretch; min-height: 20px;
  margin: 0 2px; background: var(--hairline-strong); }
/* Quiet, never-filled destructive text-link (Discard exit). The ghost
   variant supplies the transparent base; this only recolours it rose. */
:is(.dv-btn--ghost, .os-btn--ghost) { background: transparent; border-color: transparent; box-shadow: none; }
:is(.dv-btn--ghost, .os-btn--ghost):hover { background: var(--cancelled-bg); }
:is(.btn-destructive, .os-btn-destructive) { color: var(--cancelled); }
:is(.btn-destructive, .os-btn-destructive):hover { color: var(--cancelled); }
:is(.wz-foot-hint, .os-wz-foot-hint) { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }
:is(.wz-foot-hint, .os-wz-foot-hint) :is(.kbd, .os-kbd) { font-family: var(--font-mono); font-size: var(--text-xs); padding: 2px 6px; background: var(--gray-100); border: 1px solid var(--hairline); border-radius: 4px; color: var(--muted); }
:is(.wz-foot-hint, .os-wz-foot-hint) :is(.req, .os-req) { display: inline-flex; align-items: center; gap: 6px; color: var(--briefing); font-weight: 600; }
:is(.wz-foot, .os-wz-foot) :is(.total, .os-total) { display: flex; align-items: baseline; gap: 9px; margin-right: 4px; }
:is(.wz-foot, .os-wz-foot) :is(.total, .os-total) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.wz-foot, .os-wz-foot) :is(.total, .os-total) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: 500; color: var(--ink); letter-spacing: -0.01em; }
/* ════════════════════════════════════════════════════════════
   Booking-specific rows (still ledger-first; just column templates)
   ════════════════════════════════════════════════════════════ */
/* ── Guest result row ─────────────────────────────────────── */
:is(.wz-guest, .os-wz-guest) { grid-template-columns: auto minmax(0,1fr) auto; gap: 14px; }
:is(.wz-guest, .os-wz-guest) :is(.id, .os-id) { display: flex; align-items: center; gap: 9px; }
:is(.wz-guest, .os-wz-guest) :is(.nm, .os-nm) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink); }
:is(.wz-guest, .os-wz-guest) :is(.sub, .os-sub) { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: var(--text-xs); color: var(--muted); margin-top: 3px; }
:is(.wz-guest, .os-wz-guest) :is(.sub, .os-sub) :is(.mono, .os-mono) { font-family: var(--font-mono); white-space: nowrap; }
:is(.wz-guest, .os-wz-guest):is(.sel, .os-sel) { background: var(--accent-softer); }
:is(.wz-pick, .os-wz-pick) { font-size: var(--text-xs); font-weight: 600; color: var(--accent); white-space: nowrap; }
/* outline tag badge (Hotel guest / Walk-in / Diver …) */
:is(.wz-tagbadge, .os-wz-tagbadge) { flex-shrink: 0; display: inline-flex; align-items: center; padding: 1px 8px; font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.02em; color: var(--muted); background: var(--surface); border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill); white-space: nowrap; }
:is(.wz-changelink, .os-wz-changelink) { display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; padding: 0;
  font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--accent); cursor: pointer; margin-top: 14px; }
:is(.wz-changelink, .os-wz-changelink):hover { color: var(--accent-strong); }
/* guest search field (44px, search icon room at left) */
:is(.wz-guest-search, .os-wz-guest-search) { width: 100%; box-sizing: border-box; height: 44px; padding: 0 14px 0 42px;
  font-family: var(--font-sans); font-size: var(--text-sm); color: var(--ink); background: var(--surface);
  border: 1px solid var(--input-border); border-radius: var(--radius-sm); outline: none; }
:is(.wz-guest-search, .os-wz-guest-search):focus { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.wz-guest-results, .os-wz-guest-results) { margin-top: 14px; }
/* Resting/empty search state — bordered (no fill) so it reads as a panel, not floating. */
:is(.wz-guest-empty, .os-wz-guest-empty) { display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 44px 24px; color: var(--muted); background: transparent;
  border: 1px solid var(--hairline); border-radius: var(--radius-lg); }
:is(.wz-guest-empty, .os-wz-guest-empty) :is(.ico, .os-ico) { color: var(--muted-2); margin-bottom: 12px; display: flex; }
:is(.wz-guest-empty, .os-wz-guest-empty) :is(.t, .os-t) { font-size: var(--text-md); font-weight: 600; color: var(--ink); }
:is(.wz-guest-empty, .os-wz-guest-empty) :is(.s, .os-s) { margin: 6px 0 0; font-size: var(--text-sm); }
/* setting row (email toggle) — tinted accent-softer when ON */
:is(.wz-setrow, .os-wz-setrow) { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); padding: 16px 20px; margin-top: 20px; cursor: pointer; transition: background .12s ease, border-color .12s ease; }
:is(.wz-setrow, .os-wz-setrow):is(.on, .os-on) { background: var(--accent-softer); border-color: var(--accent-border); }
/* DS ToggleSwitch (checkbox-backed) */
:is(.wz-toggle, .os-wz-toggle) { position: relative; display: inline-flex; flex-shrink: 0; }
:is(.wz-toggle, .os-wz-toggle) input { position: absolute; opacity: 0; width: 0; height: 0; }
:is(.wz-toggle-track, .os-wz-toggle-track) { display: inline-flex; align-items: center; width: 42px; height: 24px; padding: 2px;
  background: var(--gray-300); border-radius: 999px; transition: background .15s ease; }
:is(.wz-toggle-thumb, .os-wz-toggle-thumb) { width: 20px; height: 20px; background: var(--surface); border-radius: 50%;
  box-shadow: 0 1px 2px rgba(17,24,39,.18); transition: transform .15s cubic-bezier(.22,1,.36,1); }
:is(.wz-toggle, .os-wz-toggle) input:checked + :is(.wz-toggle-track, .os-wz-toggle-track) { background: var(--accent); }
:is(.wz-toggle, .os-wz-toggle) input:checked + :is(.wz-toggle-track, .os-wz-toggle-track) :is(.wz-toggle-thumb, .os-wz-toggle-thumb) { transform: translateX(18px); }
:is(.wz-toggle, .os-wz-toggle) input:focus-visible + :is(.wz-toggle-track, .os-wz-toggle-track) { box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.wz-setrow, .os-wz-setrow) :is(.lead, .os-lead) { display: flex; gap: 13px; align-items: flex-start; }
:is(.wz-setrow, .os-wz-setrow) :is(.ico, .os-ico) { color: var(--muted-2); margin-top: 1px; }
:is(.wz-setrow, .os-wz-setrow) :is(.t, .os-t) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.wz-setrow, .os-wz-setrow) :is(.s, .os-s) { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
:is(.wz-setrow, .os-wz-setrow) :is(.s, .os-s) b { color: var(--ink); font-weight: 600; }
/* ── Diver block: section head + ledger ───────────────────── */
:is(.wz-diver, .os-wz-diver) { margin-bottom: 26px; }
:is(.wz-diver-head, .os-wz-diver-head) { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 11px; }
:is(.wz-diver-id, .os-wz-diver-id) { display: flex; align-items: center; gap: 11px; min-width: 0; }
:is(.wz-diver-id, .os-wz-diver-id) :is(.nm, .os-nm) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink); }
:is(.wz-name-input, .os-wz-name-input) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px dashed var(--input-border); padding: 2px 0; outline: none; min-width: 200px; }
:is(.wz-name-input, .os-wz-name-input):focus { border-bottom-color: var(--accent); }
:is(.wz-diver-meta, .os-wz-diver-meta) { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
:is(.wz-diver-tot, .os-wz-diver-tot) { font-family: var(--font-mono); font-size: var(--text-md); font-weight: 500; color: var(--ink); }
:is(.wz-diver-tot, .os-wz-diver-tot):is(.zero, .os-zero) { color: var(--muted-2); }
:is(.wz-iconbtn, .os-wz-iconbtn) { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-iconbtn, .os-wz-iconbtn):hover { background: var(--gray-100); color: var(--cancelled); }
/* date chips */
:is(.wz-dates, .os-wz-dates) { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
:is(.wz-dates, .os-wz-dates) :is(.cap, .os-cap) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-2); margin-right: 2px; }
:is(.wz-chip, .os-wz-chip) { display: inline-flex; align-items: center; gap: 6px; padding: 3px 6px 3px 11px; font-family: var(--font-mono);
  font-size: var(--text-xs); font-weight: 500; color: var(--accent); background: var(--accent-softer);
  border: 1px solid var(--accent-border); border-radius: 999px; white-space: nowrap; }
:is(.wz-chip, .os-wz-chip) button { display: inline-flex; padding: 0; border: 0; background: none; color: var(--accent); opacity: .6; cursor: pointer; }
:is(.wz-chip, .os-wz-chip) button:hover { opacity: 1; }
:is(.wz-adddate, .os-wz-adddate) { position: relative; display: inline-flex; }
:is(.wz-adddate-btn, .os-wz-adddate-btn) { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px; font: inherit; font-size: var(--text-xs);
  font-weight: 500; color: var(--accent); background: transparent; border: 1px dashed var(--accent-border); border-radius: 999px; cursor: pointer; }
:is(.wz-adddate-btn, .os-wz-adddate-btn):hover { background: var(--accent-softer); }
:is(.wz-menu, .os-wz-menu) { position: absolute; top: 100%; left: 0; margin-top: 6px; min-width: 210px; background: var(--surface);
  border: 1px solid var(--hairline); border-radius: var(--radius); box-shadow: var(--shadow-panel); padding: 6px; z-index: 30; }
:is(.wz-menu, .os-wz-menu) button { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; font: inherit; font-size: var(--text-sm);
  color: var(--ink); background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer; text-align: left; }
:is(.wz-menu, .os-wz-menu) button:hover { background: var(--gray-50); }
:is(.wz-menu, .os-wz-menu) :is(.ico, .os-ico) { color: var(--muted-2); }
:is(.wz-menu, .os-wz-menu) :is(.empty, .os-empty) { padding: 8px 10px; font-size: var(--text-xs); color: var(--muted-2); }
/* date sub-section inside a diver card */
:is(.wz-datesec, .os-wz-datesec) { border-top: 1px solid var(--hairline); }
:is(.wz-datesec, .os-wz-datesec):first-child { border-top: 0; }
/* date as a real section title */
:is(.wz-dsec-title, .os-wz-dsec-title) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 20px 8px; }
:is(.wz-dsec-title, .os-wz-dsec-title) :is(.lhs, .os-lhs) { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
:is(.wz-dsec-title, .os-wz-dsec-title) :is(.cal, .os-cal) { color: var(--accent); display: inline-flex; flex-shrink: 0; }
:is(.wz-dsec-title, .os-wz-dsec-title) :is(.d, .os-d) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-sm); letter-spacing: -0.01em; color: var(--ink); }
:is(.wz-dsec-x, .os-wz-dsec-x) { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 0;
  background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); cursor: pointer; opacity: 0.55; transition: opacity .12s, background .12s, color .12s; }
:is(.wz-datesec, .os-wz-datesec):hover :is(.wz-dsec-x, .os-wz-dsec-x) { opacity: 1; }
:is(.wz-dsec-x, .os-wz-dsec-x):hover { background: var(--gray-100); color: var(--ink); }
/* placeholder add row at the bottom of each date section */
:is(.wz-dsec-add, .os-wz-dsec-add) { display: flex; gap: 8px; padding: 8px 20px 16px; }
:is(.wz-addph, .os-wz-addph) { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; font: inherit; font-size: var(--text-xs); font-weight: 500;
  color: var(--accent); background: transparent; border: 1px dashed var(--accent-border); border-radius: var(--radius-pill); cursor: pointer; }
:is(.wz-addph, .os-wz-addph):hover { background: var(--accent-softer); }
:is(.wz-addph, .os-wz-addph):is(.add, .os-add) { color: var(--confirmed); border-color: var(--confirmed-border); }
:is(.wz-addph, .os-wz-addph):is(.add, .os-add):hover { background: var(--confirmed-bg); }
/* add-date placeholder pinned at the bottom of the card */
:is(.wz-adddate-row, .os-wz-adddate-row) { padding: 12px 20px 14px; border-top: 1px solid var(--hairline); }
:is(.wz-adddate, .os-wz-adddate):is(.block, .os-block) { display: block; }
:is(.wz-adddate, .os-wz-adddate):is(.block, .os-block) :is(.wz-adddate-btn, .os-wz-adddate-btn) { width: 100%; justify-content: center; height: 42px; border-radius: var(--radius-sm); font-size: var(--text-sm); }
:is(.wz-adddate, .os-wz-adddate):is(.block, .os-block) :is(.wz-menu, .os-wz-menu) { width: 100%; }
/* line item row — editable price + per-item actions */
:is(.wz-li, .os-wz-li) { display: grid; grid-template-columns: 22px minmax(0,1fr) 104px 98px 92px 56px; align-items: center; gap: 12px; padding: 8px 20px; }
:is(.wz-li, .os-wz-li) :is(.kind, .os-kind) { display: inline-flex; justify-content: center; }
/* micro column header — printed once on the first item of each date section */
:is(.wz-li-head, .os-wz-li-head) { display: grid; grid-template-columns: 22px minmax(0,1fr) 104px 98px 92px 56px; gap: 12px; padding: 4px 20px 2px; }
:is(.wz-li-head, .os-wz-li-head) span { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted-2); }
:is(.wz-li-head, .os-wz-li-head) :is(.h-qty, .os-h-qty) { text-align: center; }
:is(.wz-li-head, .os-wz-li-head) :is(.h-unit, .os-h-unit), :is(.wz-li-head, .os-wz-li-head) :is(.h-total, .os-h-total) { text-align: right; }
:is(.wz-li, .os-wz-li) :is(.kind, .os-kind):is(.pkg, .os-pkg) { color: var(--accent); }
:is(.wz-li, .os-wz-li) :is(.kind, .os-kind):is(.add, .os-add) { color: var(--confirmed); }
:is(.wz-li, .os-wz-li) :is(.qtywrap, .os-qtywrap) { display: flex; justify-content: center; }
:is(.wz-li, .os-wz-li) :is(.amt, .os-amt) { text-align: right; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.wz-li-acts, .os-wz-li-acts) { display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; }
:is(.wz-li-acts, .os-wz-li-acts) :is(.wz-iconbtn, .os-wz-iconbtn) { opacity: 0.5; transition: opacity .12s ease, background .12s ease, color .12s ease; }
:is(.wz-li, .os-wz-li):hover :is(.wz-li-acts, .os-wz-li-acts) :is(.wz-iconbtn, .os-wz-iconbtn), :is(.wz-li, .os-wz-li):focus-within :is(.wz-li-acts, .os-wz-li-acts) :is(.wz-iconbtn, .os-wz-iconbtn) { opacity: 1; }
:is(.wz-iconbtn, .os-wz-iconbtn):is(.apply, .os-apply):hover { background: var(--accent-soft); color: var(--accent); }
/* tweakable row-action icon colors (copy / delete) — set the stroke directly
   (these are stroke icons; overrides their stroke="currentColor"). :root default = muted. */
:is(.wz-li, .os-wz-li) :is(.wz-iconbtn, .os-wz-iconbtn):is(.apply, .os-apply) svg { stroke: var(--wz-copy-ico); }
:is(.wz-li, .os-wz-li) :is(.wz-iconbtn, .os-wz-iconbtn):is(.del, .os-del) svg { stroke: var(--wz-del-ico); }
:is(.wz-li, .os-wz-li) :is(.wz-iconbtn, .os-wz-iconbtn):is(.apply, .os-apply):hover { background: var(--accent-soft); }
:is(.wz-li, .os-wz-li) :is(.wz-iconbtn, .os-wz-iconbtn):is(.del, .os-del):hover { background: var(--cancelled-bg); }
:is(.wz-li-empty, .os-wz-li-empty) { padding: 9px 20px 13px; font-size: var(--text-sm); font-style: italic; color: var(--muted-2); }
/* Single diver card (accordion) — identity, dates and items in ONE frame */
:is(.wz-dcard, .os-wz-dcard) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; margin-bottom: 14px; }
:is(.wz-dcard-head, .os-wz-dcard-head) { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 13px 20px; background: var(--wz-tint-2); border-bottom: 1px solid var(--hairline); }
:is(.wz-dcard-head, .os-wz-dcard-head) :is(.wz-diver-id, .os-wz-diver-id) { gap: 11px; }
/* high-stakes diver removal — distinct from the line/chip × ; needs confirm */
:is(.wz-dremove, .os-wz-dremove) { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-dremove, .os-wz-dremove):hover { background: var(--cancelled-bg); color: var(--cancelled); }
:is(.wz-dconfirm, .os-wz-dconfirm) { display: inline-flex; align-items: center; gap: 8px; padding: 4px 4px 4px 12px;
  background: var(--cancelled-bg); border: 1px solid var(--cancelled-border); border-radius: var(--radius-pill); }
:is(.wz-dconfirm, .os-wz-dconfirm) :is(.q, .os-q) { font-size: var(--text-xs); font-weight: 500; color: var(--cancelled); white-space: nowrap; }
:is(.wz-dconfirm, .os-wz-dconfirm) :is(.yes, .os-yes) { height: 28px; padding: 0 12px; font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--surface);
  background: var(--cancelled); border: 0; border-radius: var(--radius-pill); cursor: pointer; }
:is(.wz-dconfirm, .os-wz-dconfirm) :is(.no, .os-no) { height: 28px; padding: 0 10px; font: inherit; font-size: var(--text-xs); font-weight: 500; color: var(--muted);
  background: transparent; border: 0; border-radius: var(--radius-pill); cursor: pointer; }
:is(.wz-dconfirm, .os-wz-dconfirm) :is(.no, .os-no):hover { color: var(--ink); }
:is(.wz-dcard-dates, .os-wz-dcard-dates) { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px 20px;
  border-bottom: 1px solid var(--hairline-2); }
:is(.wz-dcard-dates, .os-wz-dcard-dates) :is(.cap, .os-cap) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-2); margin-right: 2px; }
:is(.wz-dcard-body, .os-wz-dcard-body) { padding: 2px 0 8px; }
:is(.wz-dcard-body, .os-wz-dcard-body) :is(.wz-datesec, .os-wz-datesec):first-child { border-top: 0; }
/* catalogue select shell */
:is(.wz-sel, .os-wz-sel) { position: relative; min-width: 0; }
:is(.wz-sel, .os-wz-sel) select { -moz-appearance: none; appearance: none; -webkit-appearance: none; width: 100%; height: 34px; padding: 0 30px 0 11px;
  font: inherit; font-size: var(--text-sm); color: var(--ink); background: var(--surface); border: 1px solid var(--input-border);
  border-radius: var(--radius-sm); cursor: pointer; text-overflow: ellipsis;
  /* Suppress the @tailwindcss/forms select chevron — the .wz-sel .chev Lucide
     caret is the affordance here; appearance:none doesn't remove that bg image. */
  background-image: none; }
:is(.wz-sel, .os-wz-sel) select:focus { outline: none; border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.wz-sel, .os-wz-sel) :is(.chev, .os-chev) { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--muted-2); }
/* qty stepper — POS-sized touch targets (>=36px) */
:is(.wz-qty, .os-wz-qty) { display: inline-flex; align-items: center; border: 1px solid var(--input-border); border-radius: var(--radius-sm); background: var(--surface); overflow: hidden; }
:is(.wz-qty, .os-wz-qty) button { width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border: 0; background: transparent; color: var(--muted); cursor: pointer; }
:is(.wz-qty, .os-wz-qty) button:hover { background: var(--gray-100); color: var(--ink); }
:is(.wz-qty, .os-wz-qty) button:active { background: var(--gray-200); }
:is(.wz-qty, .os-wz-qty) :is(.n, .os-n) { min-width: 26px; text-align: center; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
/* editable price field — persistent field affordance so it reads as editable at rest */
:is(.wz-price, .os-wz-price) { display: inline-flex; align-items: center; height: 36px; border: 1px solid var(--input-border);
  border-radius: var(--radius-sm); background: var(--gray-50); padding: 0 8px 0 9px; gap: 1px; transition: border-color .12s, box-shadow .12s, background .12s; cursor: text; }
:is(.wz-price, .os-wz-price):hover { border-color: var(--gray-300); background: var(--surface); }
:is(.wz-price, .os-wz-price):focus-within { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); background: var(--surface); }
:is(.wz-price, .os-wz-price) :is(.cur, .os-cur) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); }
:is(.wz-price, .os-wz-price) input { width: 56px; border: 0; background: transparent; outline: none; font-family: var(--font-mono);
  font-size: var(--text-sm); color: var(--ink); text-align: right; padding: 0; -moz-appearance: textfield; }
:is(.wz-price, .os-wz-price) input::-webkit-outer-spin-button, :is(.wz-price, .os-wz-price) input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* add-diver dashed button */
:is(.wz-add-diver, .os-wz-add-diver) { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 15px; width: 100%;
  font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--accent); background: transparent;
  border: 1.5px dashed var(--accent-border); border-radius: var(--radius-lg); cursor: pointer; }
:is(.wz-add-diver, .os-wz-add-diver):hover { background: var(--accent-softer); }
:is(.wz-copy, .os-wz-copy) { display: flex; align-items: center; gap: 6px; padding: 11px 20px; background: var(--wz-tint);
  border-top: 1px solid var(--hairline-2); font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--accent); border: 0; cursor: pointer; width: 100%; }
:is(.wz-copy, .os-wz-copy):hover { color: var(--accent-strong); }
/* ── Order summary rail (Step 2) ──────────────────────────── */
:is(.wz-2col, .os-wz-2col) { display: grid; grid-template-columns: minmax(0,1fr) 332px; gap: 30px; align-items: start; }
@media (max-width: 1080px) { :is(.wz-2col, .os-wz-2col) { grid-template-columns: 1fr; } :is(.wz-sum, .os-wz-sum) { position: static; } }
:is(.wz-sum, .os-wz-sum) { position: sticky; top: 24px; display: flex; flex-direction: column; gap: 16px; }
:is(.wz-sum-card, .os-wz-sum-card) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.wz-sum-head, .os-wz-sum-head) { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--hairline); }
:is(.wz-sum-head, .os-wz-sum-head) :is(.t, .os-t) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
:is(.wz-sum-scroll, .os-wz-sum-scroll) { max-height: 44vh; overflow-y: auto; padding: 4px 18px; }
:is(.wz-sum-grp, .os-wz-sum-grp) { padding: 12px 0; border-top: 1px solid var(--hairline-2); }
:is(.wz-sum-grp, .os-wz-sum-grp):first-child { border-top: 0; }
:is(.wz-sum-grp, .os-wz-sum-grp) :is(.gh, .os-gh) { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
:is(.wz-sum-grp, .os-wz-sum-grp) :is(.gh, .os-gh) :is(.nm, .os-nm) { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); }
:is(.wz-sum-grp, .os-wz-sum-grp) :is(.gh, .os-gh) :is(.nm, .os-nm):is(.unset, .os-unset) { color: var(--muted-2); }
:is(.wz-sum-grp, .os-wz-sum-grp) :is(.gh, .os-gh) :is(.nm, .os-nm):is(.warm, .os-warm) { color: var(--gray-700); }
:is(.wz-sum-grp, .os-wz-sum-grp) :is(.gh, .os-gh) :is(.tt, .os-tt) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.wz-sum-line, .os-wz-sum-line) { display: flex; justify-content: space-between; gap: 8px; font-size: var(--text-xs); padding: 2px 0; }
:is(.wz-sum-line, .os-wz-sum-line) :is(.nm, .os-nm) { color: var(--gray-700); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.wz-sum-line, .os-wz-sum-line) :is(.dt, .os-dt) { color: var(--muted-2); font-family: var(--font-mono); }
:is(.wz-sum-line, .os-wz-sum-line) :is(.amt, .os-amt) { font-family: var(--font-mono); color: var(--muted); flex-shrink: 0; }
:is(.wz-sum-line, .os-wz-sum-line):is(.empty, .os-empty) { font-style: italic; color: var(--muted-2); }
:is(.wz-sum-total, .os-wz-sum-total) { display: flex; align-items: baseline; justify-content: space-between; padding: 14px 18px; border-top: 1px solid var(--hairline); background: var(--wz-tint); }
:is(.wz-sum-total, .os-wz-sum-total) :is(.k, .os-k) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
:is(.wz-sum-total, .os-wz-sum-total) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 500; letter-spacing: -0.02em; color: var(--accent); }
/* Static Order summary panel — distinct cool slate hue vs the white editable cards */
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) { background: var(--slate-100); border-color: var(--slate-300); }
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) :is(.wz-sum-head, .os-wz-sum-head) { border-bottom-color: var(--slate-200); }
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) :is(.wz-sum-head, .os-wz-sum-head) :is(.t, .os-t) { color: var(--slate-500); }
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) :is(.wz-sum-grp, .os-wz-sum-grp) { border-top-color: var(--slate-200); }
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) :is(.wz-sum-line, .os-wz-sum-line) :is(.amt, .os-amt) { color: var(--slate-500); }
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) :is(.wz-sum-total, .os-wz-sum-total) { background: var(--slate-200); border-top-color: var(--slate-300); }
/* ── Review line rows ─────────────────────────────────────── */
:is(.wz-rev-li, .os-wz-rev-li) { display: grid; grid-template-columns: 22px minmax(0,1fr) 56px 92px; align-items: center; gap: 16px;
  padding: 13px 20px; border-top: 1px solid var(--hairline-2); }
:is(.wz-rev-li, .os-wz-rev-li) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); display: block; }
:is(.wz-rev-li, .os-wz-rev-li) :is(.dt, .os-dt) { display: block; font-size: var(--text-xs); color: var(--muted-2); margin-top: 2px; }
:is(.wz-rev-li, .os-wz-rev-li) :is(.qty, .os-qty) { text-align: center; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--gray-700); }
:is(.wz-rev-li, .os-wz-rev-li) :is(.amt, .os-amt) { text-align: right; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.wz-rev-total, .os-wz-rev-total) { display: flex; align-items: baseline; justify-content: space-between; padding: 16px 20px; border-top: 1px solid var(--hairline); background: var(--wz-tint); }
:is(.wz-rev-total, .os-wz-rev-total) :is(.k, .os-k) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.wz-rev-total, .os-wz-rev-total) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 500; color: var(--ink); }
/* ── Payment ──────────────────────────────────────────────── */
:is(.wz-addpay, .os-wz-addpay) { display: flex; flex-wrap: wrap; gap: 8px; }
:is(.wz-pm, .os-wz-pm) { display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px; font: inherit; font-size: var(--text-sm);
  font-weight: 500; color: var(--ink); background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-sm); cursor: pointer; transition: all .12s ease; }
:is(.wz-pm, .os-wz-pm):hover { border-color: var(--accent-border); color: var(--accent); background: var(--accent-softer); }
:is(.wz-pm, .os-wz-pm) :is(.ico, .os-ico) { color: var(--muted); }
:is(.wz-pm, .os-wz-pm):hover :is(.ico, .os-ico) { color: var(--accent); }
:is(.wz-payrow, .os-wz-payrow) { display: grid; grid-template-columns: 168px 1fr 1fr 30px; gap: 16px; align-items: start; padding: 16px 20px; border-top: 1px solid var(--hairline-2); }
/* unified payment card sections */
:is(.wz-pay-add, .os-wz-pay-add) { padding: 16px 20px; }
/* title row inside a card */
:is(.wz-cardtitle, .os-wz-cardtitle) { display: flex; align-items: baseline; gap: 8px; padding: 15px 20px; border-bottom: 1px solid var(--hairline); }
:is(.wz-cardtitle, .os-wz-cardtitle) :is(.t, .os-t) { font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); }
:is(.wz-cardtitle, .os-wz-cardtitle) :is(.c, .os-c) { font-size: var(--text-xs); color: var(--muted-2); }
:is(.wz-paysec-head, .os-wz-paysec-head) { display: flex; align-items: baseline; gap: 8px; padding: 16px 20px 4px; border-top: 1px solid var(--hairline); }
:is(.wz-paysec-head, .os-wz-paysec-head) :is(.t, .os-t) { font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); }
:is(.wz-paysec-head, .os-wz-paysec-head) :is(.c, .os-c) { font-size: var(--text-xs); color: var(--muted-2); }
/* attribution — selectable staff chips + compact commission */
:is(.wz-attr, .os-wz-attr) { padding: 4px 20px 18px; display: flex; flex-direction: column; gap: 16px; }
:is(.wz-attr-search, .os-wz-attr-search) { position: relative; margin-bottom: 10px; max-width: 320px; }
:is(.wz-attr-search, .os-wz-attr-search) :is(.ico, .os-ico) { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--muted-2); pointer-events: none; display: flex; }
:is(.wz-attr-search, .os-wz-attr-search) input { width: 100%; box-sizing: border-box; height: 36px; padding: 0 12px 0 34px; font: inherit; font-size: var(--text-sm); color: var(--ink); background: var(--input-bg); border: 1px solid var(--input-border); border-radius: var(--radius-sm); outline: none; }
:is(.wz-attr-search, .os-wz-attr-search) input:focus { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.wz-attr-empty, .os-wz-attr-empty) { font-size: var(--text-sm); color: var(--muted); font-style: italic; padding: 4px 2px; }
/* Selected agent/staff card (when picked via search rather than a chip). */
:is(.wz-attr-selected, .os-wz-attr-selected) { display: inline-flex; align-items: center; gap: 10px; padding: 7px 10px 7px 12px; background: var(--accent-softer); border: 1px solid var(--accent-border); border-radius: var(--radius-pill); }
:is(.wz-attr-selected, .os-wz-attr-selected) :is(.badge, .os-badge) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }
:is(.wz-attr-selected, .os-wz-attr-selected) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.wz-attr-selected, .os-wz-attr-selected) :is(.rm, .os-rm) { display: inline-flex; color: var(--muted-2); background: none; border: 0; cursor: pointer; padding: 2px; }
:is(.wz-attr-selected, .os-wz-attr-selected) :is(.rm, .os-rm):hover { color: var(--cancelled); }
:is(.wz-attr-chips, .os-wz-attr-chips) { display: flex; flex-wrap: wrap; gap: 8px; }
:is(.wz-attr-chip, .os-wz-attr-chip) { display: inline-flex; align-items: center; gap: 9px; padding: 6px 12px 6px 7px; border: 1px solid var(--hairline); border-radius: var(--radius-pill); background: var(--surface); cursor: pointer; transition: border-color .12s, background .12s; }
:is(.wz-attr-chip, .os-wz-attr-chip):hover { border-color: var(--accent-border); background: var(--accent-softer); }
:is(.wz-attr-chip, .os-wz-attr-chip):is(.on, .os-on) { border-color: var(--accent); background: var(--accent-softer); }
:is(.wz-attr-chip, .os-wz-attr-chip) :is(.who, .os-who) { display: flex; flex-direction: column; line-height: 1.25; text-align: left; }
:is(.wz-attr-chip, .os-wz-attr-chip) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.wz-attr-chip, .os-wz-attr-chip) :is(.role, .os-role) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-2); }
:is(.wz-attr-chip, .os-wz-attr-chip):is(.on, .os-on) :is(.role, .os-role) { color: var(--accent); }
:is(.wz-attr-chip, .os-wz-attr-chip) :is(.tick, .os-tick) { display: inline-flex; color: var(--accent); margin-left: 2px; }
:is(.wz-attr-comm, .os-wz-attr-comm) { max-width: 280px; }
:is(.wz-attr-commrow, .os-wz-attr-commrow) { display: flex; align-items: center; gap: 12px; }
:is(.wz-attr-default, .os-wz-attr-default) { font-size: var(--text-xs); color: var(--muted); }
:is(.wz-attr-default, .os-wz-attr-default) button { background: none; border: 0; color: var(--accent); font: inherit; font-size: var(--text-xs); cursor: pointer; padding: 0; margin-left: 6px; }
:is(.wz-attr-default, .os-wz-attr-default) button:hover { color: var(--accent-strong); }
:is(.wz-payrow, .os-wz-payrow) > div { min-width: 0; }
:is(.wz-fl, .os-wz-fl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; display: flex; align-items: center; min-height: 14px; }
:is(.wz-payrow, .os-wz-payrow) :is(.wz-rm, .os-wz-rm) { align-self: start; margin-top: 20px; }
:is(.wz-payrow, .os-wz-payrow):first-child { border-top: 0; }
:is(.wz-fl, .os-wz-fl) :is(.req, .os-req) { color: var(--error); }
:is(.wz-mi, .os-wz-mi) { width: 100%; box-sizing: border-box; height: 36px; padding: 0 11px; font: inherit; font-size: var(--text-sm); color: var(--ink);
  background: var(--input-bg); border: 1px solid var(--input-border); border-radius: var(--radius-sm); outline: none; }
:is(.wz-mi, .os-wz-mi):is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.wz-mi, .os-wz-mi):focus { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.wz-paysub, .os-wz-paysub) { font-size: var(--text-xs); color: var(--muted); margin-top: 6px; }
:is(.wz-paysub, .os-wz-paysub):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.wz-pay-readonly, .os-wz-pay-readonly) { height: 36px; display: flex; align-items: center; font-size: var(--text-sm); color: var(--muted-2); }
/* ── Done ─────────────────────────────────────────────────── */
:is(.wz-done, .os-wz-done) { max-width: 620px; margin: 12px auto 0; }
:is(.wz-done-hero, .os-wz-done-hero) { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 8px 0 26px; }
:is(.wz-done-ring, .os-wz-done-ring) { width: 60px; height: 60px; border-radius: 50%; background: var(--confirmed-bg); display: flex; align-items: center; justify-content: center; color: var(--confirmed); margin-bottom: 18px; }
:is(.wz-done-hero, .os-wz-done-hero) h2 { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: var(--text-2xl); letter-spacing: -0.02em; color: var(--ink); }
:is(.wz-done-hero, .os-wz-done-hero) p { margin: 8px 0 0; font-size: var(--text-sm); color: var(--muted); max-width: 46ch; }
:is(.wz-done-hero, .os-wz-done-hero) :is(.ref, .os-ref) { font-family: var(--font-mono); font-weight: 600; color: var(--gray-700); }
/* ── Compact density ──────────────────────────────────────── */
:is(.wz-compact, .os-wz-compact) :is(.wz-inner, .os-wz-inner) { padding-top: 22px; }
:is(.wz-compact, .os-wz-compact) :is(.wz-row, .os-wz-row), :is(.wz-compact, .os-wz-compact) :is(.wz-li, .os-wz-li), :is(.wz-compact, .os-wz-compact) :is(.wz-rev-li, .os-wz-rev-li) { padding-top: 6px; padding-bottom: 6px; }
:is(.wz-compact, .os-wz-compact) :is(.wz-req, .os-wz-req) { padding-top: 11px; padding-bottom: 11px; }
:is(.wz-compact, .os-wz-compact) :is(.wz-diver, .os-wz-diver) { margin-bottom: 20px; }
/* small helpers */
:is(.wz-flex, .os-wz-flex) { display: flex; align-items: center; }
:is(.wz-mono, .os-wz-mono) { font-family: var(--font-mono); }
/* ════════════════════════════════════════════════════════════
   Selected-guest card (Step 1) — unmistakably "chosen"
   ════════════════════════════════════════════════════════════ */
:is(.wz-selguest, .os-wz-selguest) { border: 1.5px solid var(--accent); background: var(--accent-softer); border-radius: var(--radius-lg);
  overflow: hidden; }
:is(.wz-selguest-bar, .os-wz-selguest-bar) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 18px;
  background: var(--accent); }
:is(.wz-selguest-bar, .os-wz-selguest-bar) :is(.lbl, .os-lbl) { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-2xs); font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--surface); }
:is(.wz-selguest-bar, .os-wz-selguest-bar) :is(.chk, .os-chk) { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-xs); font-weight: 600; color: var(--surface); }
:is(.wz-selguest-body, .os-wz-selguest-body) { display: flex; align-items: center; gap: 14px; padding: 16px 18px; }
:is(.wz-selguest-body, .os-wz-selguest-body) :is(.nm, .os-nm) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink); }
/* Additional guests on Step 1 (party beyond the primary) */
:is(.wz-party-sec, .os-wz-party-sec) { margin-top: 22px; }
:is(.wz-stay-sec, .os-wz-stay-sec) { margin-top: 22px; }
:is(.wz-party-lbl, .os-wz-party-lbl) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
:is(.wz-party-row, .os-wz-party-row) { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-top: 1px solid var(--hairline-2); }
:is(.wz-party-row, .os-wz-party-row):first-child { border-top: 0; }
:is(.wz-party-row, .os-wz-party-row) :is(.nm, .os-nm) { font-weight: 600; font-size: var(--text-sm); color: var(--ink); }
:is(.wz-party-row, .os-wz-party-row) :is(.sub, .os-sub) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; }
:is(.wz-party-row, .os-wz-party-row) :is(.sub, .os-sub) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.wz-addguest, .os-wz-addguest) { display: inline-flex; align-items: center; gap: 7px; margin-top: 14px; padding: 9px 14px; font: inherit;
  font-size: var(--text-sm); font-weight: 500; color: var(--accent); background: transparent;
  border: 1px solid var(--accent-border); border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-addguest, .os-wz-addguest):hover { background: var(--accent-softer); }
:is(.wz-addpanel, .os-wz-addpanel) { margin-top: 18px; padding: 16px; background: var(--gray-50); border: 1px solid var(--hairline); border-radius: var(--radius-lg); }
:is(.wz-addpanel, .os-wz-addpanel) :is(.wz-party-lbl, .os-wz-party-lbl) { margin-bottom: 10px; }
:is(.wz-addpanel, .os-wz-addpanel) :is(.wz-changelink, .os-wz-changelink) { margin-top: 12px; }
/* When the party card hosts the register form in place, drop its own card chrome
   so there's a single container (the form), not a card-within-a-card. */
:is(.wz-addpanel, .os-wz-addpanel).is-bare { padding: 0; background: transparent; border: 0; }
:is(.wz-addpanel, .os-wz-addpanel).is-bare :is(.wz-reg-panel, .os-wz-reg-panel) { margin-top: 0; }
/* The two party actions share one style: matching solid-stroke buttons. */
:is(.wz-party-actions, .os-wz-party-actions) { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 18px; }
:is(.wz-party-actions, .os-wz-party-actions) :is(.wz-addguest, .os-wz-addguest), :is(.wz-party-actions, .os-wz-party-actions) :is(.wz-reg-link, .os-wz-reg-link) { margin-top: 0; padding: 9px 14px; font-size: var(--text-sm); font-weight: 500;
  color: var(--accent); background: transparent; border: 1px solid var(--accent-border);
  border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-party-actions, .os-wz-party-actions) :is(.wz-addguest, .os-wz-addguest):hover, :is(.wz-party-actions, .os-wz-party-actions) :is(.wz-reg-link, .os-wz-reg-link):hover { background: var(--accent-softer); color: var(--accent); }
/* ════════════════════════════════════════════════════════════
   Inline register-a-diver (Step 1) — two entry points, one panel
   ════════════════════════════════════════════════════════════ */
/* (A) Persistent register button — same solid-stroke style as "Add another
   guest" so every register/add affordance looks consistent. */
:is(.wz-reg-link, .os-wz-reg-link) { display: inline-flex; align-items: center; gap: 7px; margin-top: 14px; padding: 9px 14px;
  font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--accent); background: transparent;
  border: 1px solid var(--accent-border); border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-reg-link, .os-wz-reg-link):hover { background: var(--accent-softer); color: var(--accent); }
/* (B) No-match empty state inside the results ledger */
:is(.wz-reg-empty, .os-wz-reg-empty) { display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 12px; padding: 28px 24px; }
:is(.wz-reg-empty-msg, .os-wz-reg-empty-msg) { font-size: var(--text-sm); color: var(--muted); }
:is(.wz-reg-empty-msg, .os-wz-reg-empty-msg) :is(.q, .os-q) { font-weight: 600; color: var(--ink); }
/* Secondary button — outline only, NO fill (register is a fallback here). */
:is(.wz-reg-empty-cta, .os-wz-reg-empty-cta) { display: inline-flex; align-items: center; gap: 8px; padding: 9px 16px;
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--accent); background: transparent;
  border: 1px solid var(--accent-border); border-radius: var(--radius-sm); cursor: pointer;
  transition: border-color .12s, color .12s; }
:is(.wz-reg-empty-cta, .os-wz-reg-empty-cta):hover { border-color: var(--accent); color: var(--accent-strong); }
/* Shared inline panel */
:is(.wz-reg-panel, .os-wz-reg-panel) { margin-top: 16px; padding: 18px; background: var(--gray-50);
  border: 1px solid var(--hairline); border-radius: var(--radius-lg); }
:is(.wz-reg-panel, .os-wz-reg-panel) :is(.wz-party-lbl, .os-wz-party-lbl) { margin-bottom: 14px; }
:is(.wz-reg-grid, .os-wz-reg-grid) { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
:is(.wz-reg-field, .os-wz-reg-field) { display: flex; flex-direction: column; }
:is(.wz-reg-actions, .os-wz-reg-actions) { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
:is(.wz-reg-cancel, .os-wz-reg-cancel) { padding: 9px 16px; font: inherit; font-size: var(--text-sm); font-weight: 500;
  color: var(--ink); background: var(--surface); border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-reg-cancel, .os-wz-reg-cancel):hover { background: var(--gray-50); }
:is(.wz-reg-submit, .os-wz-reg-submit) { display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px;
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--surface); background: var(--accent);
  border: 0; border-radius: var(--radius-sm); cursor: pointer; }
:is(.wz-reg-submit, .os-wz-reg-submit):hover { background: var(--accent-strong); }
:is(.wz-reg-errors, .os-wz-reg-errors) { margin-bottom: 14px; padding: 10px 12px; font-size: var(--text-sm); color: var(--error);
  background: var(--cancelled-bg); border: 1px solid var(--cancelled-border); border-radius: var(--radius-sm); }
:is(.wz-reg-errors, .os-wz-reg-errors) > div + div { margin-top: 4px; }
@media (max-width: 540px) { :is(.wz-reg-grid, .os-wz-reg-grid) { grid-template-columns: 1fr; } }
/* Review summary — on-system entity header + dividerless KPI row */
:is(.wz-rev-summary, .os-wz-rev-summary) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; margin-bottom: 24px; }
:is(.wz-rev-party, .os-wz-rev-party) { display: flex; align-items: center; gap: 14px; padding: 18px 22px; }
:is(.wz-rev-party, .os-wz-rev-party) :is(.who, .os-who) { min-width: 0; flex: 1; }
:is(.wz-rev-party, .os-wz-rev-party) :is(.nm, .os-nm) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-lg); letter-spacing: -0.01em; color: var(--ink); }
:is(.wz-rev-party, .os-wz-rev-party) :is(.sub, .os-sub) { font-size: var(--text-sm); color: var(--muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.wz-rev-party, .os-wz-rev-party) :is(.sub, .os-sub) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.wz-rev-stats, .os-wz-rev-stats) { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--hairline); }
:is(.wz-rev-stats, .os-wz-rev-stats) :is(.cell, .os-cell) { padding: 14px 22px; }
:is(.wz-rev-stats, .os-wz-rev-stats) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.wz-rev-stats, .os-wz-rev-stats) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 500; letter-spacing: -0.01em; color: var(--ink); margin-top: 6px; }
:is(.wz-rev-stats, .os-wz-rev-stats) :is(.v, .os-v):is(.accent, .os-accent) { color: var(--accent); }
/* ════════════════════════════════════════════════════════════
   ALT — Dives "Table" pattern (flat editable ledger)
   ════════════════════════════════════════════════════════════ */
:is(.wz-tbl, .os-wz-tbl) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.wz-tbl-head, .os-wz-tbl-head), :is(.wz-trow, .os-wz-trow) { display: grid; grid-template-columns: 168px 132px minmax(0,1fr) 96px 104px 96px 40px; gap: 14px; align-items: center; }
:is(.wz-tbl-head, .os-wz-tbl-head) { padding: 11px 20px; border-bottom: 1px solid var(--hairline); background: var(--wz-tint);
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }
:is(.wz-tbl-head, .os-wz-tbl-head) :is(.r, .os-r), :is(.wz-trow, .os-wz-trow) :is(.amt, .os-amt) { text-align: right; }
:is(.wz-trow, .os-wz-trow) { padding: 9px 20px; border-top: 1px solid var(--hairline-2); }
:is(.wz-trow, .os-wz-trow):first-of-type { border-top: 0; }
:is(.wz-trow, .os-wz-trow) :is(.amt, .os-amt) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.wz-trow, .os-wz-trow) :is(.diver-cell, .os-diver-cell) { display: flex; align-items: center; gap: 9px; min-width: 0; }
:is(.wz-trow, .os-wz-trow) :is(.diver-cell, .os-diver-cell) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.wz-trow, .os-wz-trow):is(.rowspan-start, .os-rowspan-start) { border-top: 1px solid var(--hairline); }
:is(.wz-tbl-foot, .os-wz-tbl-foot) { display: flex; align-items: center; justify-content: space-between; padding: 13px 20px; border-top: 1px solid var(--hairline); background: var(--wz-tint); }
:is(.wz-tbl-addrow, .os-wz-tbl-addrow) { display: flex; align-items: center; gap: 8px; padding: 11px 20px; border-top: 1px solid var(--hairline-2); }
:is(.wz-tbl-total, .os-wz-tbl-total) { font-family: var(--font-mono); font-size: var(--text-md); font-weight: 500; color: var(--accent); }
/* ════════════════════════════════════════════════════════════
   ALT — Review "Invoice" document pattern
   ════════════════════════════════════════════════════════════ */
:is(.wz-inv, .os-wz-inv) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card, 0 1px 2px rgba(17,24,39,.04)); overflow: hidden; }
:is(.wz-inv-head, .os-wz-inv-head) { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; padding: 28px 30px; border-bottom: 1px solid var(--hairline); }
:is(.wz-inv-head, .os-wz-inv-head) :is(.brand, .os-brand) { display: flex; align-items: center; gap: 11px; }
:is(.wz-inv-head, .os-wz-inv-head) :is(.brand, .os-brand) :is(.pname, .os-pname) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-lg); color: var(--ink); letter-spacing: -0.01em; }
:is(.wz-inv-head, .os-wz-inv-head) :is(.brand, .os-brand) :is(.tname, .os-tname) { font-family: var(--font-mono); font-size: var(--text-2xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-top: 2px; }
:is(.wz-inv-head, .os-wz-inv-head) :is(.meta, .os-meta) { text-align: right; }
:is(.wz-inv-head, .os-wz-inv-head) :is(.meta, .os-meta) :is(.doc, .os-doc) { font-size: var(--text-2xs); font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
:is(.wz-inv-head, .os-wz-inv-head) :is(.meta, .os-meta) :is(.ref, .os-ref) { font-family: var(--font-mono); font-size: var(--text-md); color: var(--ink); margin-top: 5px; }
:is(.wz-inv-head, .os-wz-inv-head) :is(.meta, .os-meta) :is(.dt, .os-dt) { font-size: var(--text-xs); color: var(--muted); margin-top: 4px; }
:is(.wz-inv-party, .os-wz-inv-party) { display: grid; grid-template-columns: 1fr 1fr; }
:is(.wz-inv-party, .os-wz-inv-party) :is(.cell, .os-cell) { padding: 18px 30px; border-right: 1px solid var(--hairline-2); }
:is(.wz-inv-party, .os-wz-inv-party) :is(.cell, .os-cell):last-child { border-right: 0; }
:is(.wz-inv-party, .os-wz-inv-party) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.wz-inv-party, .os-wz-inv-party) :is(.v, .os-v) { font-size: var(--text-sm); color: var(--ink); margin-top: 7px; font-weight: 500; }
:is(.wz-inv-party, .os-wz-inv-party) :is(.s, .os-s) { font-size: var(--text-xs); color: var(--muted); margin-top: 3px; }
:is(.wz-inv-tbl-head, .os-wz-inv-tbl-head) { display: grid; grid-template-columns: minmax(0,1fr) 120px 56px 100px; gap: 16px; padding: 11px 30px;
  border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); background: var(--wz-tint);
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }
:is(.wz-inv-tbl-head, .os-wz-inv-tbl-head) :is(.c, .os-c) { text-align: center; }
:is(.wz-inv-tbl-head, .os-wz-inv-tbl-head) :is(.r, .os-r) { text-align: right; }
:is(.wz-inv-grp, .os-wz-inv-grp) { padding: 13px 30px 5px; font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); }
:is(.wz-inv-grp, .os-wz-inv-grp):is(.warm, .os-warm) { color: var(--briefing); }
:is(.wz-inv-li, .os-wz-inv-li) { display: grid; grid-template-columns: minmax(0,1fr) 120px 56px 100px; gap: 16px; align-items: center; padding: 9px 30px; }
:is(.wz-inv-li, .os-wz-inv-li) :is(.nm, .os-nm) { font-size: var(--text-sm); color: var(--ink); }
:is(.wz-inv-li, .os-wz-inv-li) :is(.dt, .os-dt) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); }
:is(.wz-inv-li, .os-wz-inv-li) :is(.qty, .os-qty) { text-align: center; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--gray-700); }
:is(.wz-inv-li, .os-wz-inv-li) :is(.amt, .os-amt) { text-align: right; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.wz-inv-totals, .os-wz-inv-totals) { display: flex; justify-content: flex-end; padding: 18px 30px 26px; border-top: 1px solid var(--hairline); margin-top: 8px; }
:is(.wz-inv-totals, .os-wz-inv-totals) :is(.box, .os-box) { width: 300px; }
:is(.wz-inv-totals, .os-wz-inv-totals) :is(.line, .os-line) { display: flex; justify-content: space-between; padding: 6px 0; font-size: var(--text-sm); color: var(--muted); }
:is(.wz-inv-totals, .os-wz-inv-totals) :is(.line, .os-line) :is(.v, .os-v) { font-family: var(--font-mono); color: var(--ink); }
:is(.wz-inv-totals, .os-wz-inv-totals) :is(.grand, .os-grand) { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 0 0; margin-top: 6px; border-top: 1px solid var(--hairline); }
:is(.wz-inv-totals, .os-wz-inv-totals) :is(.grand, .os-grand) :is(.k, .os-k) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.wz-inv-totals, .os-wz-inv-totals) :is(.grand, .os-grand) :is(.v, .os-v) { font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 600; letter-spacing: -0.02em; color: var(--accent); }
/* ════════════════════════════════════════════════════════════
   ALT — Payment "Balance-led" pattern (booking-detail .bal)
   ════════════════════════════════════════════════════════════ */
:is(.wz-bal-grid, .os-wz-bal-grid) { display: grid; grid-template-columns: 320px minmax(0,1fr); gap: 24px; align-items: start; }
@media (max-width: 1020px) { :is(.wz-bal-grid, .os-wz-bal-grid) { grid-template-columns: 1fr; } }
:is(.wz-bal, .os-wz-bal) { position: sticky; top: 24px; background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); box-shadow: 0 1px 2px rgba(17,24,39,.04); padding: 22px 24px; }
:is(.wz-bal, .os-wz-bal) :is(.eyebrow, .os-eyebrow) { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
:is(.wz-bal-amt, .os-wz-bal-amt) { font-family: var(--font-display); font-weight: 600; font-size: 42px; letter-spacing: -0.02em; color: var(--ink); margin: 14px 0 4px; line-height: 1; }
:is(.wz-bal-amt, .os-wz-bal-amt) :is(.cents, .os-cents) { color: var(--muted-2); }
:is(.wz-bal-sub, .os-wz-bal-sub) { font-size: var(--text-xs); color: var(--muted); }
:is(.wz-bal-bar, .os-wz-bal-bar) { height: 6px; border-radius: 6px; background: var(--hairline); overflow: hidden; margin: 18px 0 12px; }
:is(.wz-bal-bar, .os-wz-bal-bar) > span { display: block; height: 100%; background: var(--accent); transition: width .25s cubic-bezier(0.32,0.72,0,1); }
:is(.wz-bal-foot, .os-wz-bal-foot) { display: flex; align-items: center; justify-content: space-between; font-size: var(--text-xs); }
:is(.wz-bal-foot, .os-wz-bal-foot) :is(.paid, .os-paid) { color: var(--accent); font-weight: 500; }
:is(.wz-bal-foot, .os-wz-bal-foot) :is(.total, .os-total) { color: var(--muted); }
:is(.wz-bal-state, .os-wz-bal-state) { display: flex; align-items: center; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--hairline-2); font-size: var(--text-sm); }
:is(.wz-bal-state, .os-wz-bal-state) :is(.tick, .os-tick) { width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
:is(.wz-bal-state, .os-wz-bal-state):is(.ok, .os-ok) :is(.tick, .os-tick) { background: var(--confirmed-bg); color: var(--confirmed); }
:is(.wz-bal-state, .os-wz-bal-state):is(.no, .os-no) :is(.tick, .os-tick) { background: var(--briefing-bg); color: var(--briefing); }
/* ════════════════════════════════════════════════════════════
   Order-summary visualization options (exploration canvas)
   ════════════════════════════════════════════════════════════ */
:is(.wz-sum-card, .os-wz-sum-card):is(.summary, .os-summary) :is(.so-meta, .os-so-meta) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--slate-500); white-space: nowrap; }
/* A · roll-up */
:is(.so-rollrow, .os-so-rollrow) { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid var(--slate-200); }
:is(.so-rollrow, .os-so-rollrow):first-child { border-top: 0; }
:is(.so-rollrow, .os-so-rollrow) :is(.so-ico, .os-so-ico) { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--gray-100); color: var(--gray-500); flex-shrink: 0; }
:is(.so-rollrow, .os-so-rollrow) :is(.who, .os-who) { flex: 1; min-width: 0; }
:is(.so-rollrow, .os-so-rollrow) :is(.who, .os-who) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.so-rollrow, .os-so-rollrow) :is(.who, .os-who) :is(.nm, .os-nm):is(.unset, .os-unset) { color: var(--muted-2); }
:is(.so-rollrow, .os-so-rollrow) :is(.who, .os-who) :is(.sub, .os-sub) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; }
:is(.so-rollrow, .os-so-rollrow) :is(.amt, .os-amt) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
/* A2 · roll-up header + nested itemized lines */
:is(.so-grp, .os-so-grp) { border-top: 1px solid var(--slate-200); }
:is(.so-grp, .os-so-grp):first-child { border-top: 0; }
:is(.so-grp, .os-so-grp) :is(.so-rollrow, .os-so-rollrow) { border-top: 0; padding: 12px 0 6px; }
:is(.so-items, .os-so-items) { display: flex; flex-direction: column; gap: 4px; padding: 0 0 13px 44px; }
:is(.so-item, .os-so-item) { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: var(--text-xs); }
:is(.so-item, .os-so-item) :is(.nm, .os-nm) { color: var(--gray-700); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.so-item, .os-so-item) :is(.dt, .os-dt) { color: var(--slate-400); font-family: var(--font-mono); }
:is(.so-item, .os-so-item) :is(.amt, .os-amt) { font-family: var(--font-mono); color: var(--slate-500); flex-shrink: 0; }
/* B · category */
:is(.so-catrow, .os-so-catrow) { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-top: 1px solid var(--slate-200); }
:is(.so-catrow, .os-so-catrow):first-child { border-top: 0; }
:is(.so-catico, .os-so-catico) { width: 34px; height: 34px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; background: var(--surface); border: 1px solid var(--hairline); flex-shrink: 0; }
:is(.so-catrow, .os-so-catrow) :is(.who, .os-who) { flex: 1; }
:is(.so-catrow, .os-so-catrow) :is(.who, .os-who) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.so-catrow, .os-so-catrow) :is(.who, .os-who) :is(.sub, .os-sub) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; }
:is(.so-catrow, .os-so-catrow) :is(.amt, .os-amt) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
/* C · share */
:is(.so-bigtotal, .os-so-bigtotal) { font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 600; letter-spacing: -0.02em; color: var(--ink); }
:is(.so-bigsub, .os-so-bigsub) { font-size: var(--text-xs); color: var(--muted); margin-top: 3px; }
:is(.so-bar, .os-so-bar) { display: flex; height: 12px; border-radius: var(--radius-pill); overflow: hidden; margin: 16px 0 16px; background: var(--gray-100); gap: 2px; }
:is(.so-bar, .os-so-bar) > span { display: block; height: 100%; min-width: 3px; }
:is(.so-bar, .os-so-bar) > span:first-child { border-radius: var(--radius-pill) 0 0 var(--radius-pill); }
:is(.so-bar, .os-so-bar) > span:last-child { border-radius: 0 var(--radius-pill) var(--radius-pill) 0; }
:is(.so-legend, .os-so-legend) { display: flex; flex-direction: column; gap: 2px; }
:is(.so-leg, .os-so-leg) { display: flex; align-items: center; gap: 9px; padding: 6px 0; border-top: 1px solid var(--slate-200); }
:is(.so-leg, .os-so-leg):first-child { border-top: 0; }
:is(.so-leg, .os-so-leg) :is(.dot, .os-dot) { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }
:is(.so-leg, .os-so-leg) :is(.nm, .os-nm) { flex: 1; font-size: var(--text-sm); color: var(--gray-700); }
:is(.so-leg, .os-so-leg) :is(.pct, .os-pct) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); min-width: 34px; text-align: right; }
:is(.so-leg, .os-so-leg) :is(.amt, .os-amt) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); min-width: 60px; text-align: right; }
/* ═══════════════════════════════════════════════════════════════════════
   DONE — redesigned terminal screen (receipt + console directions)
   Confirmation + key numbers + actions are primary; invoice detail is one
   tap away; waiver links are compact per-diver rows with a Show-QR expander.
   ═══════════════════════════════════════════════════════════════════════ */
:is(.dn, .os-dn) { margin: 0 auto 8px; padding-top: 30px; }
:is(.dn, .os-dn):is(.receipt, .os-receipt) { max-width: 660px; }
:is(.dn, .os-dn):is(.console, .os-console) { max-width: 1060px; }
@keyframes dn-pop { from { transform: scale(0.72); } to { transform: scale(1); } }
@keyframes dn-rise { from { transform: translateY(7px); } to { transform: translateY(0); } }
/* ── shared card shell ─────────────────────────────────────── */
:is(.dn-card, .os-dn-card) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.dn-card, .os-dn-card) + :is(.dn-card, .os-dn-card) { margin-top: 16px; }
/* Gap from the hero/actions region to the cards block (was an inline 24px). */
:is(.dn-cards, .os-dn-cards) { margin-top: 24px; }
:is(.dn-card-head, .os-dn-card-head) { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 15px 20px; }
:is(.dn-card-head, .os-dn-card-head) :is(.lbl, .os-lbl) { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-sans);
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
:is(.dn-card-head, .os-dn-card-head) :is(.lbl, .os-lbl) :is(.ico, .os-ico) { color: var(--muted-2); display: flex; }
:is(.dn-card-head, .os-dn-card-head) :is(.aside, .os-aside) { font-size: var(--text-xs); color: var(--muted); }
:is(.dn-card-head, .os-dn-card-head) :is(.aside, .os-aside):is(.mono, .os-mono) { font-family: var(--font-mono); color: var(--muted-2); letter-spacing: -0.01em; }
/* ── hero ──────────────────────────────────────────────────── */
:is(.dn-hero, .os-dn-hero) { text-align: center; padding: 6px 0 24px; }
:is(.dn-ring, .os-dn-ring) { width: 60px; height: 60px; border-radius: 50%; background: var(--confirmed-bg);
  display: inline-flex; align-items: center; justify-content: center; color: var(--confirmed);
  border: 1px solid var(--confirmed-border); margin-bottom: 16px; }
:is(.dn-ring, .os-dn-ring):is(.dn-ring--cancelled, .os-dn-ring--cancelled) { background: var(--cancelled-bg); color: var(--cancelled); border-color: var(--cancelled-border); }
:is(.dn-hero, .os-dn-hero) :is(h1, h2) { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: var(--text-3xl);
  letter-spacing: -0.025em; color: var(--ink); line-height: 1.05; }
:is(.dn-hero, .os-dn-hero) :is(.sub, .os-sub) { margin: 10px 0 0; display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
  justify-content: center; font-size: var(--text-sm); color: var(--muted); }
:is(.dn-hero, .os-dn-hero) :is(.sub, .os-sub) :is(.ref, .os-ref) { font-family: var(--font-mono); font-weight: 600; color: var(--gray-700); letter-spacing: -0.01em; white-space: nowrap; }
:is(.dn-hero, .os-dn-hero) :is(.sub, .os-sub) :is(.amt, .os-amt) { font-family: var(--font-mono); font-weight: 600; color: var(--ink); letter-spacing: -0.01em; white-space: nowrap; }
:is(.dn-hero, .os-dn-hero) :is(.sub, .os-sub) :is(.sep, .os-sep) { color: var(--hairline-strong, var(--muted-2)); }
:is(.dn-hero, .os-dn-hero) :is(.email, .os-email) { margin: 12px 0 0; font-size: var(--text-xs); color: var(--muted-2); display: flex; align-items: center; justify-content: center; gap: 6px; }
@media (prefers-reduced-motion: no-preference) {
  :is(.dn-ring, .os-dn-ring) { animation: dn-pop 0.42s cubic-bezier(0.32,0.72,0,1) both; }
}
/* console hero — left-aligned bar with inline actions */
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) { display: flex; align-items: center; gap: 16px; text-align: left; padding: 0 0 4px; }
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(.dn-ring, .os-dn-ring) { width: 46px; height: 46px; margin: 0; flex-shrink: 0; }
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(h1, h2) { font-size: var(--text-xl); }
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(.htxt, .os-htxt) { min-width: 0; }
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(.sub, .os-sub) { justify-content: flex-start; margin-top: 5px; }
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(.email, .os-email) { justify-content: flex-start; }
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(.htxt-grow, .os-htxt-grow) { flex: 1; }
/* ── action cluster ────────────────────────────────────────── */
:is(.dn-actions, .os-dn-actions) { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 22px 0 4px; }
:is(.dn-actions, .os-dn-actions):is(.console, .os-console) { justify-content: flex-end; margin: 0; flex-wrap: nowrap; }
/* Inline top (public confirmation): on desktop the actions anchor to the right
   of the hero instead of floating centred beneath it. Phones keep the stacked card. */
@media (min-width: 641px) {
  :is(.dn-top, .os-dn-top):is(.dn-top--inline, .os-dn-top--inline) { display: flex; align-items: center; justify-content: space-between; gap: var(--space-6); }
  :is(.dn-top--inline, .os-dn-top--inline) :is(.dn-hero, .os-dn-hero) { padding: 0; }
  :is(.dn-top--inline, .os-dn-top--inline) :is(.dn-actions, .os-dn-actions) { margin: 0; flex-shrink: 0; justify-content: flex-end; }
}
/* Public confirmation (canvas-approved 2026-10-09): two-line thank-you hero,
   booking ref anchors the record card head, roomier rhythm between blocks. */
:is(.dn, .os-dn):is(.dn--public, .os-dn--public) :is(.dn-hero, .os-dn-hero) :is(h1, h2) { line-height: 1.3; }
:is(.dn-card-head, .os-dn-card-head) :is(.dn-card-ref, .os-dn-card-ref) { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: 600; letter-spacing: -0.01em; color: var(--gray-700); white-space: nowrap; }
:is(.dn--public, .os-dn--public) :is(.dn-rec, .os-dn-rec) + :is(.dn-inv-body, .os-dn-inv-body) { padding-top: var(--space-4); }
/* Blocks in the public receipt stack with an even gap at every width; adjacent
   notices group tighter (proximity) so they read as one set of messages. */
:is(.dn--public, .os-dn--public) :is(.dn-cards, .os-dn-cards) > * + * { margin-top: var(--space-4); }
:is(.dn--public, .os-dn--public) :is(.dn-cards, .os-dn-cards) > .os-callout + .os-callout { margin-top: var(--space-3); }
/* View-booking divers: each diver is a dn-inv bar toggled by the os-ds accordion
   controller (it flips .is-open on the item). */
:is(.dn-inv-body--sums, .os-dn-inv-body--sums) > :is(.dn-inv-sums, .os-dn-inv-sums) { margin-top: 0; border-top: 0; }
:is(.dn-inv-body--sums, .os-dn-inv-body--sums) :is(.dn-inv-sums, .os-dn-inv-sums) > :is(.dn-sum-row, .os-dn-sum-row):first-child { margin-top: 0; padding-top: var(--space-1); border-top: 0; }
/* Borrow only the accordion's toggle hook — none of its boxed item chrome. */
:is(.dn-diver, .os-dn-diver).os-accordion__item { border: 0; border-radius: 0; box-shadow: none; background: none; margin: 0; }
@media (max-width: 640px) { :is(.dn-diver, .os-dn-diver) :is(.dn-inv-bar, .os-dn-inv-bar) :is(.id, .os-id) { display: none; } }
:is(.dn-diver, .os-dn-diver):not(.is-open) > :is(.dn-inv-body, .os-dn-inv-body) { display: none; }
:is(.dn-diver, .os-dn-diver).is-open > :is(.dn-inv-bar, .os-dn-inv-bar) :is(.chev, .os-chev) { transform: rotate(180deg); }
:is(.dn-diver, .os-dn-diver) :is(.dn-inv-bar, .os-dn-inv-bar) :is(.k, .os-k) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
@media (min-width: 641px) {
  :is(.dn, .os-dn):is(.dn--public, .os-dn--public) { padding-top: var(--receipt-top); }
  :is(.dn--public, .os-dn--public) :is(.dn-cards, .os-dn-cards) { margin-top: var(--space-8); }
  :is(.dn--public, .os-dn--public) :is(.dn-cards, .os-dn-cards) > :not(.os-callout) + *,
  :is(.dn--public, .os-dn--public) :is(.dn-cards, .os-dn-cards) > * + :not(.os-callout) { margin-top: var(--space-8); }
}
/* ── record summary card ───────────────────────────────────── */
:is(.dn-rec, .os-dn-rec) { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--hairline); }
:is(.dn-rec, .os-dn-rec):is(.dn-rec--3, .os-dn-rec--3) { grid-template-columns: repeat(3, 1fr); }
:is(.dn-rec, .os-dn-rec) :is(.cell, .os-cell) { padding: 14px 20px; border-left: 1px solid var(--hairline-2); min-width: 0; }
:is(.dn-rec, .os-dn-rec) :is(.cell, .os-cell):first-child { border-left: 0; }
:is(.dn-rec, .os-dn-rec) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.dn-rec, .os-dn-rec) :is(.v, .os-v) { margin-top: 7px; font-size: var(--text-sm); font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.dn-rec, .os-dn-rec) :is(.v, .os-v):is(.mono, .os-mono) { font-family: var(--font-mono); letter-spacing: -0.01em; }
:is(.dn-rec, .os-dn-rec) :is(.v, .os-v):is(.accent, .os-accent) { color: var(--accent); }
:is(.dn-rec-status, .os-dn-rec-status) { display: flex; align-items: center; gap: 8px; padding: 13px 20px; border-top: 1px solid var(--hairline-2);
  background: var(--slate-100); }
:is(.dn-rec-status, .os-dn-rec-status) :is(.spacer, .os-spacer) { flex: 1; }
:is(.dn-rec-status, .os-dn-rec-status) :is(.agent, .os-agent) { font-size: var(--text-xs); color: var(--muted); }
:is(.dn-rec-status, .os-dn-rec-status) :is(.agent, .os-agent) b { color: var(--accent); font-weight: 500; }
/* financial pill */
:is(.dn-fpill, .os-dn-fpill) { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; white-space: nowrap;
  border-radius: var(--radius-pill); font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase; border: 1px solid transparent; }
:is(.dn-fpill, .os-dn-fpill):is(.ok, .os-ok) { color: var(--confirmed); background: var(--confirmed-bg); border-color: var(--confirmed-border); }
:is(.dn-fpill, .os-dn-fpill):is(.due, .os-due) { color: var(--briefing); background: var(--briefing-bg); border-color: var(--briefing-border); }
/* ── invoice expander ──────────────────────────────────────── */
:is(.dn-inv-bar, .os-dn-inv-bar) { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 20px; border: 0; background: none;
  border-top: 1px solid var(--hairline); cursor: pointer; text-align: left; font-family: var(--font-sans);
  transition: background 150ms ease; }
:is(.dn-inv-bar, .os-dn-inv-bar):hover { background: var(--surface); }
:is(.dn-inv-bar, .os-dn-inv-bar) :is(.k, .os-k) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
:is(.dn-inv-bar, .os-dn-inv-bar) :is(.id, .os-id) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }
:is(.dn-inv-bar, .os-dn-inv-bar) :is(.grow, .os-grow) { flex: 1; }
:is(.dn-inv-bar, .os-dn-inv-bar) :is(.tot, .os-tot) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.dn-inv-bar, .os-dn-inv-bar) :is(.chev, .os-chev) { color: var(--muted-2); display: flex; transition: transform 200ms cubic-bezier(0.32,0.72,0,1); }
:is(.dn-inv-bar, .os-dn-inv-bar)[aria-expanded="true"] :is(.chev, .os-chev) { transform: rotate(180deg); }
:is(.dn-inv-body, .os-dn-inv-body) { padding: 4px 20px 18px; border-top: 1px solid var(--hairline-2); }
:is(.dn-inv-group, .os-dn-inv-group) { margin-top: 14px; }
:is(.dn-inv-date, .os-dn-inv-date) { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 6px; }
:is(.dn-inv-li, .os-dn-inv-li) { display: flex; align-items: baseline; gap: 12px; padding: 5px 0; }
:is(.dn-inv-li, .os-dn-inv-li) :is(.ico, .os-ico) { color: var(--muted-2); display: flex; align-self: center; }
:is(.dn-inv-li, .os-dn-inv-li) :is(.nm, .os-nm) { flex: 1; min-width: 0; font-size: var(--text-sm); color: var(--ink); }
:is(.dn-inv-li, .os-dn-inv-li) :is(.nm, .os-nm) :is(.q, .os-q) { display: block; font-size: var(--text-xs); color: var(--muted); font-family: var(--font-mono); margin-top: 1px; }
:is(.dn-inv-li, .os-dn-inv-li) :is(.amt, .os-amt) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.dn-inv-sums, .os-dn-inv-sums) { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline); }
:is(.dn-sum-row, .os-dn-sum-row) { display: flex; align-items: baseline; justify-content: space-between; padding: 4px 0; font-size: var(--text-sm); }
:is(.dn-sum-row, .os-dn-sum-row) :is(.l, .os-l) { color: var(--muted); }
:is(.dn-sum-row, .os-dn-sum-row) :is(.r, .os-r) { font-family: var(--font-mono); color: var(--gray-700); }
:is(.dn-sum-row, .os-dn-sum-row):is(.total, .os-total) { padding-top: 9px; margin-top: 5px; border-top: 1px solid var(--hairline-2); }
:is(.dn-sum-row, .os-dn-sum-row):is(.total, .os-total) :is(.l, .os-l) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink); text-transform: none; letter-spacing: 0; }
:is(.dn-sum-row, .os-dn-sum-row):is(.total, .os-total) :is(.r, .os-r) { font-size: var(--text-md); font-weight: 600; color: var(--confirmed); }
:is(.dn-pay, .os-dn-pay) { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--hairline); }
:is(.dn-pay, .os-dn-pay) :is(.hd, .os-hd) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
:is(.dn-pay-row, .os-dn-pay-row) { display: flex; align-items: baseline; justify-content: space-between; padding: 5px 0; font-size: var(--text-sm); }
:is(.dn-pay-row, .os-dn-pay-row) :is(.l, .os-l) { display: flex; align-items: center; gap: 9px; color: var(--ink); }
:is(.dn-pay-row, .os-dn-pay-row) :is(.l, .os-l) :is(.ico, .os-ico) { color: var(--muted-2); display: flex; }
:is(.dn-pay-row, .os-dn-pay-row) :is(.meta, .os-meta) { font-size: var(--text-xs); color: var(--muted-2); font-family: var(--font-mono); }
:is(.dn-pay-row, .os-dn-pay-row) :is(.r, .os-r) { font-family: var(--font-mono); color: var(--ink); }
/* ── waiver links ──────────────────────────────────────────── */
:is(.dn-wv-rows, .os-dn-wv-rows) { border-top: 1px solid var(--hairline); }
:is(.dn-wv-row, .os-dn-wv-row) { padding: 13px 20px; border-top: 1px solid var(--hairline-2); }
:is(.dn-wv-row, .os-dn-wv-row):first-child { border-top: 0; }
:is(.dn-wv-top, .os-dn-wv-top) { display: flex; align-items: center; gap: 12px; }
:is(.dn-wv-av, .os-dn-wv-av) { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent), var(--sky-900));
  display: flex; align-items: center; justify-content: center;
  font-size: var(--text-xs); font-weight: 700; color: #fff; }
:is(.dn-wv-id, .os-dn-wv-id) { flex: 1; min-width: 0; }
:is(.dn-wv-id, .os-dn-wv-id) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.dn-wv-id, .os-dn-wv-id) :is(.toggle, .os-toggle) { display: inline-flex; align-items: center; gap: 4px; margin-top: 3px; padding: 0; border: 0; background: none;
  cursor: pointer; font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 500; color: var(--accent); }
:is(.dn-wv-id, .os-dn-wv-id) :is(.toggle, .os-toggle) :is(.chev, .os-chev) { display: flex; transition: transform 200ms cubic-bezier(0.32,0.72,0,1); }
:is(.dn-wv-id, .os-dn-wv-id) :is(.toggle, .os-toggle)[aria-expanded="true"] :is(.chev, .os-chev) { transform: rotate(180deg); }
:is(.dn-wv-status, .os-dn-wv-status) { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: var(--radius-pill); white-space: nowrap;
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; border: 1px solid var(--hairline);
  color: var(--muted); background: var(--surface-alt); }
:is(.dn-wv-status, .os-dn-wv-status):is(.signed, .os-signed) { color: var(--confirmed); background: var(--confirmed-bg); border-color: var(--confirmed-border); }
:is(.dn-copy, .os-dn-copy) { display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--hairline); background: var(--surface); cursor: pointer; font-family: var(--font-sans);
  font-size: var(--text-sm); font-weight: 500; color: var(--gray-700); transition: background 150ms ease, border-color 150ms ease, color 150ms ease; }
:is(.dn-copy, .os-dn-copy):hover { background: var(--surface-alt); color: var(--ink); }
:is(.dn-copy, .os-dn-copy):is(.copied, .os-copied) { color: var(--confirmed); border-color: var(--confirmed-border); background: var(--confirmed-bg); }
:is(.dn-wv-expand, .os-dn-wv-expand) { margin-top: 13px; display: flex; gap: 16px; align-items: flex-start; padding: 14px;
  background: var(--surface-alt); border: 1px solid var(--hairline-2); border-radius: var(--radius); }
:is(.dn-wv-expand, .os-dn-wv-expand) :is(.qr, .os-qr) { flex-shrink: 0; width: 108px; height: 108px; background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-sm); padding: 8px; }
:is(.dn-wv-expand, .os-dn-wv-expand) :is(.qr, .os-qr) svg { display: block; width: 100%; height: 100%; }
:is(.dn-wv-expand, .os-dn-wv-expand) :is(.urlbox, .os-urlbox) { flex: 1; min-width: 0; }
:is(.dn-wv-expand, .os-dn-wv-expand) :is(.urlbox, .os-urlbox) :is(.cap, .os-cap) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
:is(.dn-wv-expand, .os-dn-wv-expand) :is(.urlbox, .os-urlbox) :is(.url, .os-url) { margin-top: 7px; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--gray-700);
  word-break: break-all; line-height: 1.5; }
:is(.dn-wv-foot, .os-dn-wv-foot) { display: flex; align-items: center; gap: 14px; padding: 12px 20px; border-top: 1px solid var(--hairline); background: var(--surface-alt); }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.live, .os-live) { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-xs); font-weight: 600; white-space: nowrap;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--confirmed); }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.live, .os-live) :is(.dot, .os-dot) { width: 7px; height: 7px; border-radius: 50%; background: var(--confirmed); }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.exp, .os-exp) { font-size: var(--text-xs); color: var(--muted); white-space: nowrap; }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.spacer, .os-spacer) { flex: 1; }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.lnk, .os-lnk) { padding: 0; border: 0; background: none; cursor: pointer; font-family: var(--font-sans); white-space: nowrap;
  font-size: var(--text-xs); font-weight: 500; color: var(--muted); transition: color 150ms ease; }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.lnk, .os-lnk):hover { color: var(--accent); }
:is(.dn-wv-foot, .os-dn-wv-foot) :is(.lnk, .os-lnk):is(.danger, .os-danger):hover { color: var(--cancelled); }
/* ── console grid ──────────────────────────────────────────── */
:is(.dn-grid, .os-dn-grid) { display: grid; grid-template-columns: minmax(0,1.04fr) minmax(0,0.96fr); gap: 18px; align-items: start; margin-top: 20px; }
@media (max-width: 980px) { :is(.dn-grid, .os-dn-grid) { grid-template-columns: 1fr; } }
:is(.dn-col-label, .os-dn-col-label) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin: 0 0 11px 2px; }
/* compact density trims */
:is(.wz-compact, .os-wz-compact) :is(.dn-rec, .os-dn-rec) :is(.cell, .os-cell) { padding: 11px 16px; }
:is(.wz-compact, .os-wz-compact) :is(.dn-wv-row, .os-dn-wv-row) { padding: 10px 16px; }
:is(.wz-compact, .os-wz-compact) :is(.dn-card-head, .os-dn-card-head) { padding: 12px 16px; }
/* os-countdown — countdown chip: boxed mono value + plain label ("05 · days to arrival").
 * Source: `.countdown/.cbox/.clab` in arrival-rich.html (the only mockup carrying it).
 * The value box is the only emphasis; the label stays sentence-case running text so the
 * chip can sit inline under a hero title without competing with it.
 */
.os-countdown {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.os-countdown__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: var(--text-xl);
  line-height: var(--leading-xl);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--accent-strong);
  box-shadow: var(--shadow-card);
}
.os-countdown__label {
  font-size: var(--text-xs);
  line-height: var(--leading-xs);
  font-weight: 600;
  color: var(--text-secondary);
}
.os-countdown__label b,
.os-countdown__label strong {
  color: var(--ink);
  font-weight: 700;
}
/* ─────────────────────────────────────────────────────────────────────
   qty.css — `.os-qty`, the quantity stepper.

   WHY THIS EXISTS. Any line-item surface — a POS basket, a folio charge, a
   rental row — needs "how many of this". The system shipped nothing for it,
   so DiveOS wrote `.wz-qty` inside its booking wizard stylesheet and
   arena-ops, porting that flow, was about to write its own third copy under a
   local prefix. That is the exact drift the gem exists to stop, so the
   control is promoted here under its `.os-*` name.

   THE VISUAL CONTRACT, from the DiveOS control this replaces: ONE bordered
   box, not three adjacent widgets. The border belongs to the wrapper, the two
   buttons are flush inside it with no borders or radius of their own, and
   `overflow: hidden` lets their hover fill run into the corners cleanly. The
   value between them is TABULAR — a monospace, fixed-min-width slot — because
   the whole control must not resize when the count crosses 9 to 10, which is
   what makes a stepper feel unstable to hold a pointer over.

   SIZING. Everything derives from the control trio, so the stepper matches
   the button and input beside it at every density and grows inside
   `.os-density--touch` without a modifier. The buttons are SQUARE at the
   control height, which is the same rule `.os-btn--icon` follows. The value
   slot is a fraction of that height rather than a literal, so the control
   stays proportional at 32px and at 48px.

   MARKUP (the buttons are real button elements — see the reset below):

     div.os-qty
       button.os-qty__btn   type=button aria-label="Decrease quantity"
       span.os-qty__value                                    (or an input)
       button.os-qty__btn   type=button aria-label="Increase quantity"

   No Stimulus controller ships with it: the count lives in whatever state the
   consuming flow already owns (a JSON value on a wizard controller, a form
   field, a Turbo round-trip), and a controller here would have to guess.
   ───────────────────────────────────────────────────────────────────── */
.os-qty {
  display: inline-flex;
  align-items: center;
  /* The single border that makes this read as ONE control. */
  border: 1px solid var(--input-border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  /* Clips the button hover fill to the wrapper's corners. */
  overflow: hidden;
  height: var(--control-h);
  transition: border-color 100ms ease, box-shadow 100ms ease;
}
.os-qty:hover {
  border-color: var(--input-border-hover);
}
/* ── The two buttons ──────────────────────────────────────────────────
   Rendered as button elements, which is correct: they act, they do not
   navigate. That means the UA chrome must be reset here in full. v1.6.2
   shipped a fix for exactly this on the segmented control, which set colour
   and padding but never border, background, appearance or font-family, so
   the UA's outset border and buttonface fill showed through and the group
   rendered as mismatched boxes. Enumerated rather than remembered: border,
   background, appearance, font, colour, radius. */
.os-qty__btn {
  -moz-appearance: none;
       appearance: none;
  -webkit-appearance: none;
  border: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: var(--control-fs);
  border-radius: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Square at the control height — the same geometry rule .os-btn--icon
     uses, so the stepper's ends are as clickable as an icon button. */
  width: var(--control-h);
  height: 100%;
  padding: 0;
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color 100ms ease, color 100ms ease;
}
.os-qty__btn:hover {
  background: var(--state-hover);
  color: var(--text-primary);
}
.os-qty__btn:active {
  background: var(--state-active);
}
/* Keyboard focus only, matching .os-btn. The ring is drawn INSIDE the wrapper
   because the wrapper clips overflow — an outer ring would be cut in half by
   the border it sits behind. */
.os-qty__btn:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: -2px;
}
/* A stepper at its floor or ceiling disables the end it cannot move, rather
   than vanishing it — a control that changes shape at the boundary is worse
   than one that greys out. */
.os-qty__btn:disabled, .os-qty__btn[aria-disabled="true"] {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
  pointer-events: none;
}
/* ── The value ────────────────────────────────────────────────────────
   Monospace + a min-width floor so 1 and 10 occupy the same slot. The floor
   is derived from the control height, not typed, so it scales with density.
   Rendered as a span in the read-only case; as .os-qty__input when the count
   must be typed as well as stepped. */
.os-qty__value {
  min-width: calc(var(--control-h) * 0.72);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--control-fs);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
/* The typable variant. It is deliberately NOT .os-input — that class carries
   its own border, background and full width, all three of which would break
   the single-box reading. The spinner buttons are stripped because the
   stepper's own buttons ARE the spinner. */
.os-qty__input {
  min-width: calc(var(--control-h) * 0.72);
  width: calc(var(--control-h) * 1.1);
  border: 0;
  background: transparent;
  outline: none;
  padding: 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--control-fs);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  -webkit-appearance: textfield;
          appearance: textfield;
  -moz-appearance: textfield;
}
.os-qty__input::-webkit-outer-spin-button,
.os-qty__input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* Typing into the value rings the WHOLE control, because the input has no
   visible edge of its own to ring. */
.os-qty:focus-within {
  border-color: var(--input-border-focus);
  box-shadow: var(--shadow-focus);
}
/* ── Modifiers ────────────────────────────────────────────────────────
   Each re-declares the trio ON itself, which pins it against an enclosing
   .os-density--* scope — the same back-compat rule every sized component in
   the gem follows since v1.6.0. */
.os-qty--sm {
  --control-h:  var(--control-h-sm);
  --control-fs: var(--control-fs-sm);
}
.os-qty--touch {
  --control-h:  var(--control-h-touch);
  --control-fs: var(--control-fs-touch);
}
/* A stepper that owns its row rather than sitting at the end of one — a
   phone basket line, where the control spans the column and the value takes
   the slack between the two ends. */
.os-qty--block {
  display: flex;
  width: 100%;
}
.os-qty--block .os-qty__value, .os-qty--block .os-qty__input {
  flex: 1;
}
/* Sits inside a busy row (a table cell, a card line) where a second solid
   border would add noise: drops to the row's own tint and shows its edge on
   interaction only. */
.os-qty--quiet {
  background: var(--surface-alt);
  border-color: transparent;
}
.os-qty--quiet:hover {
  border-color: var(--input-border);
}
/* Whole-control disabled — the row is locked, not just an end of it. */
.os-qty--disabled {
  opacity: var(--disabled-opacity);
  pointer-events: none;
}
/* Public receipt pages — payment result, request-received, link-expired and
   extend-access pages, plus the View-booking page (variant D layout below). They all reuse the
   public confirmation receipt (`dn receipt dn--public`, block "Public
   confirmation (canvas-approved" in components/wizard.css); only the few
   additions that receipt never needed live here. */
:root {
  --receipt-wide-max: 1120px; /* View-booking page content cap (two uses) */
  --receipt-aside-col: 360px; /* View-booking aside column */
  --receipt-tile-icon: 36px; /* receipt tile icon square */
  --receipt-narrow-max: 480px; /* public single-column receipt cap */
}
/* Hero ring tones beyond confirmed/cancelled: a payment still processing is a
   real pending status; an expired link is no status at all, so it stays neutral. */
:is(.dn-ring, .os-dn-ring).dn-ring--pending { background: var(--pending-bg); color: var(--pending); border-color: var(--pending-border); }
:is(.dn-ring, .os-dn-ring).dn-ring--neutral { background: var(--surface-alt); color: var(--muted-2); border-color: var(--hairline); }
/* Supporting line under a bar hero: running copy, not the centred chip row. */
:is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) .dn-hero-note { margin: var(--space-2) 0 0; color: var(--muted); max-width: 72ch; }
:is(.dn-hero, .os-dn-hero) .dn-hero-note strong { color: var(--ink); font-weight: 600; }
/* Record cell: a settled balance reads in the confirmed status colour. */
:is(.dn-rec, .os-dn-rec) :is(.v, .os-v).is-settled { color: var(--confirmed); }
/* Rows that carry a trailing action (gear remove) or no amount (checklists). */
:is(.dn-inv-li, .os-dn-inv-li) .act { align-self: center; display: flex; }
/* Footnote under a card body (hint lines with a leading icon). */
.dn-note { display: flex; align-items: flex-start; gap: var(--space-2); margin-top: var(--space-3); color: var(--muted-2); }
.dn-note > :first-child { flex-shrink: 0; margin-top: 2px; }
/* Payment panel: countdown + pay action on one row, wrapping on phones. */
.dn-paypanel { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-4); padding-top: var(--space-4); }
.dn-paypanel__defer { display: flex; justify-content: flex-end; padding-top: var(--space-3); }
/* Page-level reassurance line below the cards. */
.dn-foot { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-6); color: var(--muted-2); }
/* Two-figure record (payment result: amount + balance) — fits a phone row. */
:is(.dn-rec, .os-dn-rec).dn-rec--2 { grid-template-columns: repeat(2, 1fr); }
/* Phone action grouping. .dn-actions is a 2-col grid on phones (wizard-mobile.css)
   that lifts the primary to a full-width top row — but a button_to / pay_form
   primary is wrapped in a <form>, so the form is the grid item and the button
   never spans. Lift the form instead, and when there are only two actions give
   the secondary the full row too, so both read as one stacked group. */
@media (max-width: 640px) {
  :is(.dn--public, .os-dn--public) :is(.dn-actions, .os-dn-actions) > form:has(.os-btn--primary) { order: -1; grid-column: 1 / -1; }
  :is(.dn--public, .os-dn--public) :is(.dn-actions, .os-dn-actions) > form .os-btn { width: 100%; }
  :is(.dn--public, .os-dn--public) :is(.dn-actions, .os-dn-actions):has(> :nth-child(2):last-child) > *,
  :is(.dn--public, .os-dn--public) :is(.dn-actions, .os-dn-actions) > :only-child { grid-column: 1 / -1; }
}
/* ═══════════════════════════════════════════════════════════════════════
   View-booking (variant D, approved 2026-10-09): hero → "Still to do" strip →
   two columns. The right rail (Payment, Overview) leads the DOM so phones stack
   strip → Payment → Overview → Divers → Waivers → Gear; ≥901px it moves to a
   sticky 360px column beside the main column.
   ═══════════════════════════════════════════════════════════════════════ */
:is(.dn, .os-dn).dn-view { max-width: var(--receipt-wide-max); }
.dn-view :is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) { padding: 0 0 var(--space-6); }
/* Totals are amounts, not status: ink, not the confirmed green. */
:is(.dn--public, .os-dn--public) :is(.dn-sum-row, .os-dn-sum-row):is(.total, .os-total) :is(.r, .os-r) { color: var(--ink); }
/* A figure inside a primary button takes the button's text colour. */
:is(.dn--public, .os-dn--public) .os-btn--primary .os-figure { color: inherit; }
/* "Still to do" — eyebrow above a row of jump-link chips. */
.dn-todo { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); padding: 0 0 var(--space-4); }
.dn-todo__links { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.dn-todo__links a { display: inline-flex; align-items: center; padding: var(--space-1) var(--space-3); border: 1px solid var(--hairline-strong); border-radius: var(--radius-md); color: var(--accent); text-decoration: none; }
.dn-todo__links a:hover { border-color: var(--accent); background: var(--accent-soft); }
.dn-todo__links a .os-figure { color: inherit; margin-left: var(--space-1); }
.dn-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-items: start; }
.dn-grid > * { min-width: 0; }
.dn-rail, .dn-main { display: flex; flex-direction: column; gap: var(--space-4); }
.dn-grid :is(.dn-card, .os-dn-card) + :is(.dn-card, .os-dn-card) { margin-top: 0; }
@media (min-width: 901px) {
  .dn-grid { grid-template-columns: minmax(0, 1fr) var(--receipt-aside-col); gap: var(--space-8); }
  .dn-rail { grid-column: 2; grid-row: 1; position: sticky; top: var(--space-6); }
  .dn-main { grid-column: 1; grid-row: 1; }
}
.dn-view #payment, .dn-view #waivers { scroll-margin-top: var(--space-4); }
/* Payment card: total, big balance, stacked full-width actions, then notices
   grouped tight beneath (proximity — they all speak about payment). */
.dn-paycard { padding: var(--space-4) var(--space-5) var(--space-5); }
.dn-paycard__total { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.dn-paycard__label { margin-top: var(--space-3); }
.dn-paycard__due { margin: var(--space-1) 0 var(--space-3); }
.dn-paycard__actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.dn-paycard__actions form { display: contents; }
.dn-paycard__actions .os-btn { width: 100%; justify-content: center; }
.dn-paycard__note { display: flex; align-items: flex-start; gap: var(--space-2); margin: var(--space-3) 0 0; color: var(--muted); }
.dn-paycard__note > svg { flex-shrink: 0; margin-top: 2px; color: var(--muted-2); }
.dn-paycard__note strong { color: var(--ink); font-weight: 600; }
/* Actionable payment notices (defer offer / deferred banner) sit full width
   between the strip and the columns; the wrapper collapses when empty. */
.dn-notices { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-4); }
.dn-notices:not(:has(.os-callout)) { display: none; }
/* The receipt's desktop top padding (space-16) is for a lone thank-you hero;
   the two-column view starts at the shell's own padding. */
:is(.dn, .os-dn).dn--public.dn-view { padding-top: 0; }
/* Overview contact block: stacked in the narrow rail. */
.dn-overview__contact { display: flex; flex-direction: column; gap: var(--space-5); }
.dn-contact { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1); }
/* Gear tiles — one per rated category, each its own add form. */
.dn-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); padding: var(--space-4) var(--space-5); }
.dn-tile { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-md); min-width: 0; }
.dn-tile.is-on { border-color: var(--accent); background: var(--accent-soft); }
.dn-tile__top { display: flex; align-items: center; gap: var(--space-3); }
.dn-tile__ico { width: var(--receipt-tile-icon); height: var(--receipt-tile-icon); flex-shrink: 0; border-radius: var(--radius-sm); background: var(--surface-alt); color: var(--muted); display: grid; place-items: center; }
.dn-tile.is-on .dn-tile__ico { background: var(--surface); color: var(--accent); }
.dn-tile__bot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.dn-tile__added { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); min-width: 0; }
.dn-gear-rows { display: flex; flex-direction: column; gap: var(--space-2); }
.dn-gear-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.dn-gearfoot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; padding: var(--space-3) var(--space-5); border-top: 1px solid var(--hairline); }
.dn-gearfoot > p { margin: 0; }
/* Phone pay bar: hidden on desktop (the rail is sticky there). */
.dn-paybar { display: none; }
@media (max-width: 640px) {
  .dn-paycard, .dn-tiles, .dn-gearfoot { padding-left: var(--space-4); padding-right: var(--space-4); }
  .dn-tiles { grid-template-columns: minmax(0, 1fr); }
  .dn-paybar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; align-items: center; gap: var(--space-3);
    padding: var(--space-3) var(--space-4); background: var(--surface); border-top: 1px solid var(--hairline-strong);
    transform: translateY(100%); transition: transform 200ms ease; }
  .dn-paybar.is-shown { transform: none; }
  .dn-paybar__bal { flex: 1; min-width: 0; }
  /* Room under the last card so the bar never covers it. */
  .dn-view:has(.dn-paybar) { padding-bottom: calc(var(--space-16) + var(--space-8)); }
}
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  .dn-paybar { transition: none; }
}
/* The engine layout caps header / main / footer (.engine-shell) at max-w-3xl
   (768), which starves the View-booking two-column grid. Same approach as
   booking-trip.css: while .dn-view is on the page, widen the whole column so
   the logo bar, the page and the footer keep one left edge. */
@media (min-width: 901px) {
  .engine-body:has(.dn-view) .engine-shell { max-width: calc(var(--receipt-wide-max) + 2 * var(--space-6)); }
}
@media (max-width: 640px) { .dn-hide-sm { display: none; } }
/* ── View-booking header band (mirrors the staff booking detail band 1) ──
   White full-bleed band under the shop bar: party name + status pill, one
   middot meta line, the status note. The background and hairline bleed to the
   viewport edges via border-image outset, which paints outside the box without
   adding scrollable overflow. Negative top margin cancels the shell's py-6/py-8
   so the band meets the shop bar. */
.dn-band { position: relative; margin: calc(-1 * var(--space-6)) 0 var(--space-6); padding: var(--space-6) 0;
  -o-border-image: conic-gradient(color-mix(in srgb, var(--accent) 9%, var(--surface)) 0 0) 0 / / 0 100vmax;
     border-image: conic-gradient(color-mix(in srgb, var(--accent) 9%, var(--surface)) 0 0) fill 0 / / 0 100vmax; }
.dn-band::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  -o-border-image: conic-gradient(color-mix(in srgb, var(--accent) 18%, var(--surface)) 0 0) 0 / / 0 100vmax;
     border-image: conic-gradient(color-mix(in srgb, var(--accent) 18%, var(--surface)) 0 0) fill 0 / / 0 100vmax; }
@media (min-width: 640px) { .dn-band { margin-top: calc(-1 * var(--space-8)); padding: var(--space-8) 0 var(--space-6); } }
.dn-band__title { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); margin-top: var(--space-1); }
.dn-band__title h1 { margin: 0; color: var(--ink); }
.dn-band__meta { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-1) var(--space-2); margin-top: var(--space-2); color: var(--muted); }
.dn-band__item { display: inline-flex; align-items: center; gap: var(--space-1); white-space: nowrap; }
.dn-band__item svg { color: var(--muted-2); }
.dn-band__id { color: var(--gray-700); font-weight: 600; }
.dn-band__dot { color: var(--muted-2); }
.dn-band__pref, .dn-band__pref svg { color: var(--accent); }
.dn-band__note { margin: var(--space-3) 0 0; color: var(--muted); }
/* ── Stacked receipt (expired link): one narrow left-aligned column —
   icon, title + note, the explanation card, then a full-width action. ── */
:is(.dn, .os-dn).dn--public.dn-stack { max-width: var(--receipt-narrow-max); }
@media (min-width: 641px) { :is(.dn, .os-dn).dn--public.dn-stack { padding-top: var(--space-10); } }
.dn-stack :is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) { flex-direction: column; align-items: flex-start; gap: var(--space-4); padding: 0; }
.dn-stack :is(.dn-cards, .os-dn-cards) { margin-top: var(--space-6); }
.dn-stack :is(.dn-actions, .os-dn-actions) { display: flex; margin: var(--space-4) 0 0; }
.dn-stack :is(.dn-actions, .os-dn-actions) > * { flex: 1; }
.dn-stack :is(.dn-actions, .os-dn-actions) .os-btn { width: 100%; justify-content: center; }
/* View-booking cards: tinted header row so each card reads as a titled panel
   on the canvas (muf, 2026-10-10: the all-white cards read flat). Scoped to
   .dn-view — the receipt/confirmation cards keep the plain head. */
/* Card heads: a light sky tint (the Packages blue was too loud on the cards). */
.dn-view :is(.dn-card-head, .os-dn-card-head) { background: var(--sky-50); border-bottom: 1px solid var(--sky-100); }
/* Packages palette on the chrome only: the shop nav and the booking header
   band take the Packages nav blue (storefront.css .bc-nav ≈ #DBE9F7 over its
   #E9F1FA tint), mixed from the accent so no naked hex. The page canvas and
   the cards stay neutral. Scoped to View-your-booking via :has(.dn-view). */
.engine-body:has(.dn-view) .engine-header { background: color-mix(in srgb, var(--accent) 13%, var(--surface)); border-bottom-color: color-mix(in srgb, var(--accent) 20%, var(--surface)); }
.dn-view :is(.dn-card-head, .os-dn-card-head) :is(.lbl, .os-lbl) :is(.ico, .os-ico) { color: var(--accent); }
.dn-view :is(.dn-card-head, .os-dn-card-head) + * { border-top: 0; }
/* Phones: the middot meta line wraps, and a trailing dot strands at a line
   end — drop the dots and let the gap + icons separate the items. */
@media (max-width: 640px) {
  .dn-band__dot { display: none; }
  .dn-band__meta { gap: var(--space-1) var(--space-3); }
}
/* Gear tile: the Update button stays hidden until the stepper changes
   (dirty-submit controller); .os-btn's display would out-rank the UA [hidden]. */
.dn-tile__top > div:not(.dn-tile__ico):first-of-type { min-width: 0; }
.dn-tile__bot .os-btn[hidden] { display: none; }
/* Stacked pages: the title block (icon, title, note) centres over the column;
   cards and the action stay full width (muf, 2026-10-10). */
.dn-stack :is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) { align-items: center; text-align: center; }
.dn-stack .dn-hero-note { margin-inline: auto; }
/* View booking — a diver's lines grouped under the funnel's day band
   (accent-soft, no rules), full-bleed inside the card body (--space-5 = its 20px sides). */
.dn-inv-body--banded { padding-top: 0; }
.dn-inv-body--banded > .os-databand.dn-band {
  margin: var(--space-2) calc(-1 * var(--space-5)) var(--space-1);
  padding-inline: var(--space-5);
  background: var(--accent-soft);
  border-top: 0;
  border-bottom: 0;
}
.dn-inv-body--banded > .os-databand.dn-band:first-child { margin-top: 0; }
.dn-band .os-databand__ico { color: var(--accent); }
/* Receipt totals: the sums block draws the rule above Total; a Total that
   opens the block doesn't draw a second one. */
:is(.dn--public, .os-dn--public) :is(.dn-inv-sums, .os-dn-inv-sums) > :is(.dn-sum-row, .os-dn-sum-row):is(.total, .os-total):first-child {
  margin-top: 0;
  border-top: 0;
}
/* ─────────────────────────────────────────────────────────────────────
   components/guest-quote.css — the guest quote page (#582, #572 A+): one
   column inside the storefront's 720px frame for every state, phone first.
   Layout only; type roles, buttons, pills and the phone bar (.dn-paybar,
   public-receipt-pages.css) are the shared components.
   ───────────────────────────────────────────────────────────────────── */
.guest-quote { max-width: var(--page-narrow); margin: 0 auto; display: flex; flex-direction: column; gap: var(--space-6);
  padding-block: var(--space-10) calc(var(--space-16) + var(--space-8));
  padding-left: max(var(--space-4), env(safe-area-inset-left, 0px)); padding-right: max(var(--space-4), env(safe-area-inset-right, 0px)); }
.guest-quote__head { display: flex; flex-direction: column; gap: var(--space-2); }
.guest-quote__booked { display: inline-flex; align-items: center; gap: var(--space-2); }
.guest-quote__wide { width: 100%; justify-content: center; }
.guest-quote__name { font-weight: 600; }
/* The quote card. */
.guest-quote__card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); overflow: hidden; }
.guest-quote__card.is-dimmed { opacity: 0.7; }
.guest-quote__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); margin: 0;
  padding: var(--space-4) var(--space-6); }
.guest-quote__facts > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.guest-quote__facts dd { margin: 0; }
.guest-quote__sec { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--hairline-2); }
.guest-quote__item { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); }
.guest-quote__inc { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-4);
  margin: 0; padding: 0; list-style: none; }
.guest-quote__inc li { display: flex; align-items: center; gap: var(--space-2); }
.guest-quote__note { margin: 0; }
.guest-quote__total { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4);
  padding: var(--space-5) var(--space-6); background: var(--canvas); border-top: 1px solid var(--hairline); }
.guest-quote__amount { font-size: var(--text-2xl); }
/* Accept, contact, next steps, footer. */
.guest-quote__accept { display: flex; flex-direction: column; gap: var(--space-2); text-align: center; }
.guest-quote__accept form { display: contents; }
.guest-quote__contact { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4) var(--space-5);
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); }
.guest-quote__contact-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.guest-quote__steps { display: flex; flex-direction: column; gap: var(--space-2); margin: var(--space-3) 0 0; padding: 0;
  list-style: none; counter-reset: guest-step; }
.guest-quote__steps li { display: flex; gap: var(--space-3); align-items: baseline; counter-increment: guest-step; }
/* The step number in a small mono ring (the sequence is information here). */
.guest-quote__steps li::before { content: counter(guest-step); flex-shrink: 0; width: var(--space-6); height: var(--space-6);
  display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--hairline-strong); border-radius: var(--radius-pill);
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); }
.guest-quote__foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-3);
  padding-top: var(--space-4); border-top: 1px solid var(--hairline); }
.guest-quote__foot .os-link { display: inline-flex; align-items: center; gap: var(--space-1); }
.guest-quote__decline { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; }
@media (max-width: 640px) {
  .guest-quote { padding-block: var(--space-8) calc(var(--space-16) + var(--space-8)); }
  .guest-quote__facts { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); padding-inline: var(--space-4); }
  .guest-quote__facts > div { flex-direction: row; justify-content: space-between; gap: var(--space-3); }
  .guest-quote__inc { grid-template-columns: minmax(0, 1fr); }
  .guest-quote__sec, .guest-quote__total { padding-inline: var(--space-4); }
  .guest-quote__bar form { display: contents; }
}
/* Provision-tenant outlet list (admin/tenants/new). Each row lays the outlet
   name input and its remove button on one line inside a full-width field-grid
   cell; the "Add another outlet" button sits below the list. Tokens only. */
.outlet-row__control {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.outlet-row__control .os-input {
  flex: 1 1 auto;
  min-width: 0;
}
.outlet-list__add {
  margin-top: var(--space-3);
}
/* platform-document — the DiveOS/Novas-branded shell for the platform agreement
   signing page and its states (#566, design 5A). */
/* Platform document shell (#566, design 5A): the DiveOS/Novas-branded page a
   dive-centre owner reads and signs the Sign-Up Agreement on. One narrow
   page column (--page-narrow), prose capped at a readable measure, 16px gutter on phones, no
   decoration (DESIGN.md "decoration ceiling for billing"). Tokens only. */
.os-platform-doc { background: var(--surface); }
.os-platform-doc__skip {
  position: absolute; left: var(--space-4); top: var(--space-4);
  transform: translateY(-300%); /* off-canvas until focused; no raw px offset */
  padding: var(--space-2) var(--space-3);
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--hairline-strong); border-radius: var(--radius-sm);
  z-index: var(--z-tooltip);
}
.os-platform-doc__skip:focus { transform: none; }
.os-platform-doc__shell {
  width: 100%; max-width: var(--page-narrow); margin-inline: auto; /* 768px, the engine shell width */
  padding-inline: var(--space-4);
}
@media (min-width: 640px) { .os-platform-doc__shell { padding-inline: var(--space-6); } }
.os-platform-doc__header { border-bottom: 1px solid var(--hairline); }
.os-platform-doc__header-row {
  min-height: var(--space-16); display: flex; align-items: center; gap: var(--space-3);
}
.os-platform-doc__brand { display: inline-flex; align-items: baseline; gap: var(--space-2); min-width: 0; }
.os-platform-doc__mark { align-self: center; flex: none; }
.os-platform-doc__wordmark { font-weight: 600; color: var(--ink); }
.os-platform-doc__issuer { color: var(--muted); }
.os-platform-doc__aside { margin-left: auto; flex: none; color: var(--muted); }
.os-platform-doc__main { flex: 1; padding-block: var(--space-6); }
@media (min-width: 640px) { .os-platform-doc__main { padding-block: var(--space-8); } }
/* The agreement text: a reading column inside the narrow page shell. */
.os-platform-doc__prose { max-width: 65ch; }
.os-platform-doc__prose h2 { margin-top: var(--space-8); margin-bottom: var(--space-3); }
.os-platform-doc__prose h3 { margin-top: var(--space-6); margin-bottom: var(--space-2); }
.os-platform-doc__prose p, .os-platform-doc__prose li { margin-bottom: var(--space-3); }
/* The agreement text itself (the [data-template] articles) is justified, as a formal document
   should read. No auto-hyphenation: it split "diveos.mv" into "di-veos.mv" in the contract text.
   Status pages, form hints and the receipt list share __prose but stay ragged-right. */
.os-platform-doc__prose[data-template] p, .os-platform-doc__prose[data-template] li { text-align: justify; }
.os-platform-doc__prose ul { padding-left: var(--space-5); list-style: disc; }
.os-platform-doc__footer { border-top: 1px solid var(--hairline); }
.os-platform-doc__footer-row {
  padding-block: var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  justify-content: space-between;
}
/* ── Signing page (design 1A / 2C / Pass 6) ───────────────────────────── */
.os-platform-doc__facts { margin-bottom: var(--space-6); }
.os-platform-doc__facts-row { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); align-items: baseline; }
.os-platform-doc__contents { margin-bottom: var(--space-6); }
.os-platform-doc__contents ol { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding: 0; list-style: none; }
.os-platform-doc__sign { margin-top: var(--space-8); padding-top: var(--space-6); border-top: 1px solid var(--hairline); }
.os-platform-doc__sign .os-field { margin-bottom: var(--space-4); }
.os-platform-doc__choice { display: flex; gap: var(--space-3); align-items: flex-start; padding-block: var(--space-2); }
.os-platform-doc__choice .os-checkbox { margin-top: var(--space-1); flex: none; }
.os-platform-doc__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-5); margin-top: var(--space-6); }
/* Phone-only sticky bar that jumps to the signature block; hidden by the
   controller once that block is in view, and never shown on wide screens. */
.os-platform-doc__sticky {
  position: fixed; inset-inline: 0; bottom: 0; z-index: var(--z-tooltip);
  padding: var(--space-3) var(--space-4);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
  background: var(--surface); border-top: 1px solid var(--hairline);
}
.os-platform-doc__sticky .os-btn { width: 100%; }
.os-platform-doc__sticky[hidden] { display: none; }
@media (min-width: 640px) { .os-platform-doc__sticky { display: none; } }
@media (max-width: 639.98px) { .os-platform-doc__has-sticky { padding-bottom: var(--space-16); } }
/* Mobile pane treatment for the wizard (dv-wizm-*) — MUST load after
   wizard.css so its ≤640px overrides win the cascade. Desktop untouched. */
/* ============================================================
   wizard-mobile.css — the dv-wizm-* mobile pane treatment for the
   DiveOS wizard (app-first build; migrates to os-ds `.os-wizm-*` once
   dive-os is on os-ds ≥1.18 — see the mobile-wizard-pattern spec).

   BELOW the phone breakpoint (≤640px) the existing wizard chrome
   (.wz-flow / .wz-couple stepper / .wz-body / .wz-foot, hand-composed in
   account/bookings/_form.html.erb) is re-skinned into the approved
   full-screen PANE model: a fixed full-screen surface with an app-bar
   (back + title/subtitle), a slim segmented progress strip, an `svh`
   scroll body, and a sticky full-width action bar.

   DESKTOP IS UNTOUCHED — every rule here lives inside the @media block,
   plus the .dv-wizm-bar app-bar markup that is `display:none` above the
   breakpoint. Semantic tokens only (design-system gate); no raw palette.

   Platform constraints (os-ds docs/mobile-primitives.md):
     · `svh` not `dvh` for the shell height (vh fallback first).
     · the sticky footer must NOT rely on position:fixed under an open
       keyboard — the shell height is driven from `visualViewport.height`
       by wizard_mobile_controller.js (--wizm-vh), so the flex-pinned
       footer stays glued above the keyboard.
     · action bar pads with env(safe-area-inset-bottom) (34px notch).
   ============================================================ */
/* ── App-bar — mobile only; hidden on desktop ──────────────── */
.dv-wizm-bar { display: none; }
@media (max-width: 640px) {
  /* ── The pane surface: a fixed, full-screen, viewport-tall column.
     Height comes from --wizm-vh (set to visualViewport.height by the
     mobile controller); 100svh is the no-JS fallback. Taking over the
     full screen matches the approved full-screen-pane design and sidesteps
     the surrounding account chrome for the focused booking flow. */
  :is(.wz-flow, .os-wz-flow) {
    position: fixed;
    inset: 0;
    z-index: 60;
    height: var(--wizm-vh, 100svh);
    height: var(--wizm-vh, 100vh); /* older engines: vh fallback */
    background: var(--canvas);
  }

  /* ── App-bar: back chevron + title/subtitle. Replaces the stepper band
     as the top bar (the segmented progress sits just beneath it). ─────── */
  .dv-wizm-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
    /* Always clear the status bar / notch: 16px of breathing room BELOW the
       safe-area inset, so the title never clips against the top edge when the
       wizard is a fixed full-screen surface. */
    padding: calc(env(safe-area-inset-top) + 16px) 10px 12px;
    background: var(--surface);
  }
  .dv-wizm-bar__back {
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    border: 0;
    background: transparent;
    color: var(--ink);
    border-radius: var(--radius-sm);
    cursor: pointer;
  }
  .dv-wizm-bar__back:active { background: var(--surface-alt); }
  .dv-wizm-bar__back[hidden] { display: none; }
  .dv-wizm-bar__ttl {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
  }
  .dv-wizm-bar__ttl .t {
    font-family: var(--font-display);
    font-size: var(--text-md);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .dv-wizm-bar__ttl .s {
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Escape hatch back to the app — right-aligned in the app-bar. */
  .dv-wizm-bar__cancel {
    margin-left: auto;
    flex: 0 0 auto;
    align-self: center;
    padding: 8px 6px;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    white-space: nowrap;
  }
  .dv-wizm-bar__cancel:active { color: var(--ink); }

  /* ── Segmented progress: reuse the .wz-bars stepper, slimmed to a bare
     progress strip — hide the per-step labels + check pips, keep the bars.
     Sits directly under the app-bar (no card, no top margin). ─────────── */
  :is(.wz-flow, .os-wz-flow) > :is(.wz-couple, .os-wz-couple) {
    margin-top: 0;
    padding: 0 16px 12px;
    background: var(--surface);
    border-bottom: 1px solid var(--hairline);
  }
  :is(.wz-flow, .os-wz-flow) > :is(.wz-couple, .os-wz-couple).is-scrolled { margin-top: 0; }
  :is(.wz-couple, .os-wz-couple):is(.wz-couple-card, .os-wz-couple-card) { padding-top: 0; padding-bottom: 12px; }
  :is(.wz-bars, .os-wz-bars) { max-width: none; }
  :is(.wz-bars-inner, .os-wz-bars-inner) { max-width: none; gap: 6px; }
  /* Tappable to jump between REACHED steps (goToStep gates the terminal Done
     step itself). Vertical padding gives the thin bar a real touch target. */
  :is(.wz-seg, .os-wz-seg) { gap: 0; pointer-events: auto; padding: 7px 0; cursor: pointer; }
  /* Bars only — drop the label row on the compact strip. */
  :is(.wz-seg, .os-wz-seg) :is(.lbrow, .os-lbrow) { display: none; }
  :is(.wz-seg, .os-wz-seg):is(.on, .os-on) :is(.bar, .os-bar) { height: 5px; box-shadow: none; }

  /* ── Body: the svh scroll region. It already flex:1's inside .wz-flow;
     just strip the desktop reading-width inset so panes go edge-to-edge. */
  :is(.wz-body, .os-wz-body) { background: var(--canvas); scrollbar-gutter: auto; }
  :is(.wz-inner, .os-wz-inner) { max-width: none; padding: 16px; }
  :is(.wz-inner, .os-wz-inner):is(.narrow, .os-narrow) { max-width: none; }
  /* The Done receipt renders straight into the step (no .wz-inner), so it needs
     its own mobile inset — otherwise its cards sit flush against the edges. */
  :is(.wz-body, .os-wz-body) :is(.dn, .os-dn) { max-width: none; margin: 0; padding: 16px 16px 8px; }

  /* ── Done step success section — mobile redesign ──────────────────
     Hero: ring aligned to the title (not floating mid-block), larger confirm.
     Actions: the repeat action (Start new sale) is a full-width primary on
     top; Print receipt + View booking split the row beneath it — no orphaned,
     centre-wrapped button. */
  :is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) { align-items: flex-start; gap: 14px; padding-bottom: 2px; }
  :is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) h2 { font-size: var(--text-2xl); }
  :is(.dn-hero, .os-dn-hero):is(.bar, .os-bar) :is(.dn-ring, .os-dn-ring) { margin-top: 2px; }

  :is(.dn-actions, .os-dn-actions) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin: 18px 0 4px;
  }
  :is(.dn-actions, .os-dn-actions) :is(.os-btn, .dv-btn) { justify-content: center; height: 46px; margin: 0; }
  :is(.dn-actions, .os-dn-actions) :is(.os-btn--primary, .dv-btn--primary) { order: -1; grid-column: 1 / -1; }
  /* Wrap hero + actions in a card so the top section matches the record/waiver
     cards below it instead of floating on the canvas. (Desktop: plain wrapper.) */
  :is(.dn-top, .os-dn-top) {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 18px 16px;
  }
  :is(.dn-top, .os-dn-top) :is(.dn-actions, .os-dn-actions) { margin-bottom: 0; }
  /* Even 16px gaps between all three cards (matches .dn-card + .dn-card and the
     .dn top inset), so the confirmation card isn't spaced differently. */
  :is(.dn-cards, .os-dn-cards) { margin-top: 16px; }

  /* ── Sticky action bar: full-width primary button per the mockup.
     The footer is a flex sibling pinned at the bottom of the --wizm-vh
     column (NOT position:fixed), so an open keyboard can't shove it off —
     see the controller's visualViewport listener. ─────────────────────── */
  :is(.wz-foot, .os-wz-foot) {
    position: static;
    flex: 0 0 auto;
    box-shadow: 0 -4px 16px -8px rgba(2, 6, 23, 0.12);
  }
  :is(.wz-foot-inner, .os-wz-foot-inner) {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 10px 16px calc(12px + env(safe-area-inset-bottom));
  }
  /* One row: a compact "Back" on the left (only where a Back exists — not Guest),
     the primary "Next" filling the rest with its folded total. Discard leaves
     the footer entirely — the app-bar Cancel is the exit. */
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.center, .os-center) { display: none; }
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.start, .os-start) { display: none; }
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.start, .os-start):has(:is(.os-btn--secondary, .dv-btn--secondary)) {
    display: flex; order: -1; flex: 0 0 auto; align-items: center;
  }
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.start, .os-start) :is(.btn-destructive, .os-btn-destructive),
  :is(.wz-foot, .os-wz-foot) :is(.wz-foot-sep, .os-wz-foot-sep) { display: none; }
  /* Back and Next share the footer row at the 48px touch height (#609 R3;
     was a 34px text Back beside a 50px Next). */
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.start, .os-start) :is(.os-btn--secondary, .dv-btn--secondary) {
    background: transparent; border-color: transparent; box-shadow: none;
    color: var(--muted); height: var(--control-h-touch); padding: 0 var(--space-3); font-size: var(--text-sm); font-weight: 600;
  }
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.end, .os-end) {
    flex: 1 1 auto;
    min-width: 0;
    align-items: stretch;
  }
  :is(.wz-foot, .os-wz-foot) :is(.grp, .os-grp):is(.end, .os-end) :is(.os-btn, .dv-btn) {
    width: 100%;
    justify-content: center;
    height: var(--control-h-touch);
    font-size: var(--text-md);
  }
  /* Folded footer keeps the label left + total pushed right inside the button. */
  :is(.wz-foot, .os-wz-foot).dv-wizm-foot--folded :is(.grp, .os-grp):is(.end, .os-end) :is(.os-btn--primary, .dv-btn--primary) {
    justify-content: flex-start;
  }

  /* Date sub-header row inside a diver card — the date on the left, a per-date
     "Add dive" on the right (opens packages for that date, skipping the picker).
     Same-day dives group under one date row instead of repeating the date. */
  :is(.dv-wizm-daterow, .os-dv-wizm-daterow) {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 9px 14px; border-top: 1px solid var(--hairline-2);
  }
  :is(.dv-wizm-ghead, .os-dv-wizm-ghead) + :is(.dv-wizm-daterow, .os-dv-wizm-daterow) { border-top: 0; }
  :is(.dv-wizm-daterow, .os-dv-wizm-daterow) .d {
    font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.03em;
    text-transform: uppercase; color: var(--muted-2);
  }
  :is(.dv-wizm-adddive-btn, .os-dv-wizm-adddive-btn) {
    display: inline-flex; align-items: center; gap: 4px; padding: 4px 6px; margin: -4px -6px -4px 0;
    font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--accent);
    background: none; border: 0; cursor: pointer;
  }
  /* Items under a date row are tighter (no per-row date now). */
  :is(.dv-wizm-daterow, .os-dv-wizm-daterow) + :is(.dv-wizm-li, .os-dv-wizm-li) { border-top: 0; }
}
/* The four dv-wizm-* add-dive sub-patterns (date / pick-list / option-group /
   group-summary). Inert on desktop (classes only render in the mobile flow). */
/* ============================================================
   wizard-mobile-panes.css — the four dv-wizm-* sub-patterns that the
   mobile add-dive pane flow slots into (date → package → configure →
   summary). Ported 1:1 from the approved mockup
   (docs/superpowers/specs/assets/mobile-add-dive-panes.html) into
   semantic tokens (design-system gate: no raw palette / hex).

   These are the reusable primitives; they migrate to os-ds `.os-*`
   (_date_pane / _pick_list / _option_group / _group_summary_list) when
   dive-os is on os-ds ≥1.18. The classes only ever appear inside the
   mobile pane flow, so they carry no media query — they're inert markup
   on desktop (never rendered there).

   Verify in isolation at /admin/design_system (mobile viewport) before
   the live add-dive flow adopts them.
   ============================================================ */
/* ── Pane scaffold: a full-screen pane pushed over the wizard body ──
   The add-dive sub-flow pushes these panes; each has its own scroll body
   and (where needed) a self-contained sticky foot. These classes are NOT
   media-scoped, so they render identically at any width — which lets the
   showcase preview the mobile look on a desktop screen. */
.dv-wizm-pane { display: flex; flex-direction: column; min-height: 0; background: var(--canvas); }
.dv-wizm-pane__body { flex: 1; min-height: 0; overflow-y: auto; }
/* self-contained action bar (mockup's full-width primary button) — used by the
   add-dive panes; distinct from the shell's media-scoped .wz-foot restyle. */
.dv-wizm-foot { flex: 0 0 auto; background: var(--surface); border-top: 1px solid var(--hairline);
  padding: 10px 16px calc(12px + env(safe-area-inset-bottom)); box-shadow: 0 -4px 16px -8px rgba(2, 6, 23, 0.12); }
.dv-wizm-foot__meta { display: flex; justify-content: space-between; align-items: baseline;
  font-size: var(--text-xs); color: var(--muted); margin-bottom: 8px; }
.dv-wizm-foot .os-btn { width: 100%; height: 50px; }
.dv-wizm-foot .os-btn--primary { justify-content: space-between; }
/* Keep each label/value cluster (e.g. "Fri, Jul 31 ›") on one line — the inline
   chevron SVG otherwise wraps below the date when the button is tight. */
.dv-wizm-foot .os-btn > span { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; min-width: 0; }
/* Showcase-only: the app-bar is display:none off-mobile (shell file); the
   /admin/design_system phone frames force it visible so the panes read as
   whole screens regardless of the viewer's window width. */
.dv-wizm-demo .dv-wizm-bar { display: flex; }
.dv-wizm-pane__eyebrow { padding: 16px 16px 0;
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--muted-2); }
.dv-wizm-pane__h { padding: 4px 16px 12px;
  font-family: var(--font-display); font-size: var(--text-xl); font-weight: 700;
  letter-spacing: -0.02em; color: var(--ink); }
/* ══════════════════════════════════════════════════════════════
   1 · _date_pane — date-only picker (quick chips + month calendar)
   ══════════════════════════════════════════════════════════════ */
.dv-wizm-date__chips { display: flex; gap: 8px; padding: 0 16px 14px; }
.dv-wizm-date__chip { flex: 1; height: 52px; border-radius: var(--radius);
  border: 1px solid var(--hairline-strong); background: var(--surface);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  font: inherit; cursor: pointer; color: var(--ink); }
.dv-wizm-date__chip b { font-size: var(--text-sm); font-weight: 600; }
.dv-wizm-date__chip span { font-size: var(--text-xs); color: var(--muted); }
.dv-wizm-date__chip.is-on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.dv-wizm-date__chip.is-on span { color: var(--accent); }
.dv-wizm-cal { background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-lg); margin: 0 16px; padding: 14px; box-shadow: var(--shadow-sm); }
.dv-wizm-cal__hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.dv-wizm-cal__hd b { font-size: var(--text-sm); font-weight: 600; }
.dv-wizm-cal__nav { display: flex; gap: 6px; }
.dv-wizm-cal__nav button { width: 30px; height: 30px; border-radius: var(--radius);
  border: 1px solid var(--hairline); background: var(--surface); display: grid; place-items: center;
  color: var(--muted); cursor: pointer; }
.dv-wizm-cal__dow { display: grid; grid-template-columns: repeat(7,1fr); gap: 2px; margin-bottom: 4px; }
.dv-wizm-cal__dow span { text-align: center; font-size: var(--text-2xs); font-weight: 600;
  color: var(--muted-2); text-transform: uppercase; }
.dv-wizm-cal__days { display: grid; grid-template-columns: repeat(7,1fr); gap: 3px; }
.dv-wizm-cal__day { aspect-ratio: 1; display: grid; place-items: center; font-size: var(--text-sm);
  border-radius: var(--radius); color: var(--ink); font-variant-numeric: tabular-nums;
  border: 0; background: none; font: inherit; cursor: pointer; }
.dv-wizm-cal__day.is-mut { color: var(--hairline-strong); pointer-events: none; }
.dv-wizm-cal__day.is-today { border: 1.5px solid var(--accent-border); }
.dv-wizm-cal__day.is-sel { background: var(--accent); color: var(--surface); font-weight: 600; }
/* ══════════════════════════════════════════════════════════════
   2 · _pick_list — package menu (category + search + row w/ single +)
   ══════════════════════════════════════════════════════════════ */
.dv-wizm-pick__bar { display: flex; gap: 8px; padding: 12px 16px;
  background: var(--surface); border-bottom: 1px solid var(--hairline); position: sticky; top: 0; z-index: 1; }
.dv-wizm-pick__drop { flex: 1; height: 40px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong); background: var(--surface);
  display: flex; align-items: center; gap: 6px; padding: 0 14px;
  font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--ink); cursor: pointer; }
.dv-wizm-pick__drop .chev { margin-left: auto; color: var(--muted); display: inline-flex; }
.dv-wizm-pick__search { width: 40px; height: 40px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong); background: var(--surface); display: grid; place-items: center;
  color: var(--ink); cursor: pointer; }
.dv-wizm-pick__sec { padding: 14px 16px 6px; font-size: var(--text-md); font-weight: 700; letter-spacing: -0.01em; color: var(--ink); }
.dv-wizm-pick-row { display: flex; gap: 12px; padding: 14px 16px;
  border-bottom: 1px solid var(--hairline-2); align-items: flex-start; }
.dv-wizm-pick-row__info { flex: 1; min-width: 0; }
.dv-wizm-pick-row__info b { font-size: var(--text-sm); font-weight: 600; display: block; margin-bottom: 2px; color: var(--ink); }
.dv-wizm-pick-row__info p { font-size: var(--text-xs); color: var(--muted); line-height: 1.4; margin-bottom: 6px; }
.dv-wizm-pick-row__info .pr { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
.dv-wizm-pick-row__info .pr s { color: var(--muted-2); font-weight: 400; margin-left: 6px; font-size: var(--text-xs); }
/* the single + affordance — filled (fast-path add) / ghost (opens configure) / qty (already in cart) */
.dv-wizm-plus, .dv-wizm-plus--ghost, .dv-wizm-qtymini {
  width: 38px; height: 38px; border-radius: var(--radius-pill); flex: 0 0 auto;
  display: grid; place-items: center; font: inherit; cursor: pointer; }
.dv-wizm-plus { background: var(--accent); color: var(--surface); border: 0; box-shadow: var(--shadow-sm); }
.dv-wizm-plus--ghost { border: 1.5px solid var(--accent-border); color: var(--accent); background: var(--surface); }
.dv-wizm-qtymini { border: 1.5px solid var(--accent); color: var(--accent); background: var(--surface);
  font-size: var(--text-sm); font-weight: 700; font-variant-numeric: tabular-nums; }
/* ══════════════════════════════════════════════════════════════
   3 · _option_group — configure (Pick-1 radios + optional checks + note + qty)
   ══════════════════════════════════════════════════════════════ */
.dv-wizm-optsec { background: var(--surface); border-bottom: 1px solid var(--hairline); }
.dv-wizm-optsec:last-of-type { border-bottom: 0; }
.dv-wizm-optsec__hd { display: flex; align-items: center; justify-content: space-between; padding: 16px 16px 8px; }
.dv-wizm-optsec__hd b { font-size: var(--text-md); font-weight: 700; color: var(--ink); }
.dv-wizm-badge { font-size: var(--text-xs); font-weight: 600; padding: 3px 10px; border-radius: var(--radius-pill); }
.dv-wizm-badge--pick { background: var(--confirmed-bg); color: var(--confirmed); }
.dv-wizm-badge--opt { background: var(--surface-alt); color: var(--muted); }
.dv-wizm-badge--done { background: var(--accent); color: var(--surface); }
/* rows: single hairline between SECTIONS, none between rows within a section */
.dv-wizm-opt-row { display: flex; align-items: center; gap: 12px; padding: 11px 16px; }
.dv-wizm-opt-row__info { flex: 1; }
.dv-wizm-opt-row__info b { font-size: var(--text-sm); font-weight: 500; display: block; color: var(--ink); }
.dv-wizm-opt-row .pr { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); }
.dv-wizm-radio, .dv-wizm-check { width: 22px; height: 22px; flex: 0 0 auto; border: 2px solid var(--hairline-strong); }
.dv-wizm-radio { border-radius: 50%; }
.dv-wizm-radio.is-on { border-color: var(--accent); background: radial-gradient(var(--accent) 42%, var(--surface) 46%); }
.dv-wizm-check { border-radius: 6px; }
.dv-wizm-check.is-on { background: var(--accent); border-color: var(--accent); display: grid; place-items: center; color: var(--surface); }
.dv-wizm-note { margin: 12px 16px; border: 1px solid var(--hairline-strong); border-radius: var(--radius);
  min-height: 74px; padding: 11px; font: inherit; font-size: var(--text-sm); color: var(--ink); width: calc(100% - 32px); resize: vertical; }
.dv-wizm-note::-moz-placeholder { color: var(--muted-2); }
.dv-wizm-note::placeholder { color: var(--muted-2); }
.dv-wizm-qtybar { display: flex; align-items: center; justify-content: center; gap: 22px; padding: 14px; }
.dv-wizm-qtybar button { width: 44px; height: 44px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong); background: var(--surface); display: grid; place-items: center;
  font-size: var(--text-xl); color: var(--accent); cursor: pointer; }
.dv-wizm-qtybar b { font-size: var(--text-lg); font-variant-numeric: tabular-nums; min-width: 30px; text-align: center; }
/* ══════════════════════════════════════════════════════════════
   4 · _group_summary_list — order summary grouped by diver
      (avatar-led header, no intra-group separators, stronger between
      groups, price + tap-to-expand qty stacked right)
   ══════════════════════════════════════════════════════════════ */
.dv-wizm-sum__hd { display: flex; align-items: baseline; justify-content: space-between; padding: 16px 16px 8px; }
.dv-wizm-sum__hd .h { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 700; letter-spacing: -0.02em; color: var(--ink); }
.dv-wizm-sum__hd a { color: var(--accent); font-size: var(--text-sm); font-weight: 600; cursor: pointer; }
/* diver header — STRONGER hairline between people (border-top on the group) */
.dv-wizm-diver { display: flex; align-items: center; gap: 10px; padding: 18px 16px 10px; border-top: 1px solid var(--hairline); }
.dv-wizm-diver:first-of-type { padding-top: 6px; border-top: 0; }
.dv-wizm-diver__av { width: 34px; height: 34px; border-radius: var(--radius-pill); flex: 0 0 auto;
  background: var(--accent-soft); color: var(--accent-strong); display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: 600; }
.dv-wizm-diver__who b { font-size: var(--text-sm); font-weight: 700; letter-spacing: -0.01em; display: block; color: var(--ink); }
.dv-wizm-diver__who span { font-size: var(--text-xs); color: var(--muted); font-weight: 500; }
/* item rows — NO separators within a diver group */
.dv-wizm-srow { display: flex; align-items: flex-start; gap: 12px; padding: 12px 16px; position: relative; }
.dv-wizm-srow__info { flex: 1; min-width: 0; }
.dv-wizm-srow__info b { font-size: var(--text-sm); font-weight: 600; display: block; color: var(--ink); }
.dv-wizm-srow__info .sub { font-size: var(--text-xs); color: var(--muted); display: block; margin-top: 1px; }
.dv-wizm-srow__info .ed { color: var(--accent); font-size: var(--text-xs); font-weight: 600; margin-top: 3px; display: inline-block; cursor: pointer; }
.dv-wizm-srow__right { display: flex; flex-direction: column; align-items: flex-end; gap: 9px; flex: 0 0 auto; }
.dv-wizm-srow__right .pr { font-family: var(--font-mono); font-size: var(--text-sm); font-variant-numeric: tabular-nums; color: var(--ink); }
.dv-wizm-srow.is-hl { background: var(--accent-soft); }
.dv-wizm-sqty { width: 34px; height: 34px; border-radius: var(--radius-pill); border: 1.5px solid var(--accent);
  color: var(--accent); display: grid; place-items: center; font-size: var(--text-sm); font-weight: 700;
  font-variant-numeric: tabular-nums; background: var(--surface); cursor: pointer; }
/* tap-to-expand qty popover — a compact − n + right on the row */
.dv-wizm-qtypop { position: absolute; right: 12px; top: 34px; z-index: 5;
  display: flex; align-items: center; background: var(--surface); border: 1px solid var(--accent);
  border-radius: var(--radius-pill); box-shadow: var(--shadow-panel); overflow: hidden; }
.dv-wizm-qtypop button { width: 40px; height: 40px; border: 0; background: var(--surface);
  font-size: var(--text-lg); color: var(--accent); display: grid; place-items: center; cursor: pointer; }
.dv-wizm-qtypop b { width: 30px; text-align: center; font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
/* ══════════════════════════════════════════════════════════════
   Mobile add-dive integration — desktop composer ⇄ mobile pane flow
   ══════════════════════════════════════════════════════════════ */
/* The mobile flow container is inert on desktop; the ≤640px breakpoint swaps
   the two-column composer out for it. (Matches the shell's 640px breakpoint.) */
.dv-wizm-mob { display: none; }
@media (max-width: 640px) {
  .bk2-dives-desktop { display: none; }
  .dv-wizm-mob { display: block; }
}
/* mobile order-summary chrome (renders into the dives step body) */
.dv-wizm-sum__hd a { display: inline-flex; align-items: center; gap: 4px; }
.dv-wizm-diver__add { margin-left: auto; flex: 0 0 auto; width: 34px; height: 34px;
  border-radius: var(--radius-pill); border: 1.5px solid var(--accent-border);
  color: var(--accent); background: var(--surface); display: grid; place-items: center; cursor: pointer; }
.dv-wizm-mob-empty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 40px 24px; gap: 6px; }
.dv-wizm-mob-empty .ic { color: var(--muted-2); margin-bottom: 6px; }
.dv-wizm-mob-empty .t { font-size: var(--text-md); font-weight: 600; color: var(--ink); }
.dv-wizm-mob-empty .s { font-size: var(--text-sm); color: var(--muted); }
.dv-wizm-mob-emptybtn { margin-top: 14px; width: auto; padding: 0 20px; height: 44px; }
.dv-wizm-mob-tot { display: flex; align-items: baseline; justify-content: space-between;
  padding: 16px; margin-top: 4px; border-top: 1px solid var(--hairline); font-size: var(--text-sm); color: var(--muted); }
.dv-wizm-mob-tot .v { font-family: var(--font-mono); font-weight: 600; color: var(--ink); font-size: var(--text-md); }
/* full-screen add-dive overlay (Date → Package → Configure pane stack) */
.dv-wizm-ov { position: fixed; inset: 0; z-index: 80; background: var(--canvas); }
.dv-wizm-ov__pane { position: absolute; inset: 0; display: flex; flex-direction: column;
  height: 100vh; height: 100svh; background: var(--canvas); }
.dv-wizm-ov .dv-wizm-pane__body { flex: 1; min-height: 0; overflow-y: auto; }
/* per-diver multi-date sub-label inside the mobile summary */
.dv-wizm-datelbl { padding: 8px 16px 2px; font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted-2); }
/* per-diver "Add date" — a quiet dashed affordance under the diver's dives */
.dv-wizm-mob-adddate { padding: 6px 16px 4px; }
.dv-wizm-mob-adddate button { display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--accent);
  background: transparent; border: 1px dashed var(--accent-border); border-radius: var(--radius-pill); cursor: pointer; }
.dv-wizm-mob-adddate button:active { background: var(--accent-soft); }
/* bottom-of-summary "Add another diver" — full-width dashed action */
.dv-wizm-mob-adddiver { display: flex; align-items: center; justify-content: center; gap: 8px;
  width: calc(100% - 32px); margin: 14px 16px 6px; padding: 12px; font: inherit; font-size: var(--text-sm);
  font-weight: 600; color: var(--accent); background: var(--surface);
  border: 1px dashed var(--accent-border); border-radius: var(--radius); cursor: pointer; }
.dv-wizm-mob-adddiver:active { background: var(--accent-soft); }
/* "Remove this dive" — quiet destructive link inside the edit Configure pane */
.dv-wizm-mob-removedive { display: inline-flex; align-items: center; gap: 6px; margin: 4px 16px 8px;
  padding: 8px 0; font: inherit; font-size: var(--text-sm); font-weight: 600; color: var(--cancelled);
  background: none; border: 0; cursor: pointer; }
/* ══════════════════════════════════════════════════════════════
   Mobile Dives summary — Review-style ledger cards (per diver)
   Name-first 2-row header band, no avatar, no per-row icons, total
   folded into the footer button. Supersedes the avatar-led summary
   for the LIVE dives step (the showcase keeps _group_summary_list).
   ══════════════════════════════════════════════════════════════ */
.dv-wizm-mob .dv-wizm-sum__hd { padding: 2px 2px 12px; }
.dv-wizm-card { background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden; margin: 0 0 14px; }
/* header band — row 1: name (full) + diver total; row 2: dive count */
.dv-wizm-ghead { display: flex; flex-wrap: wrap; align-items: baseline; -moz-column-gap: 12px; column-gap: 12px; row-gap: 2px;
  padding: 11px 14px; background: var(--accent-soft); border-bottom: 1px solid var(--hairline-2); }
.dv-wizm-ghead .nm { flex: 1 1 auto; min-width: 0; font-size: var(--text-md); font-weight: 700;
  letter-spacing: -0.01em; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dv-wizm-ghead .tot { flex: 0 0 auto; font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
.dv-wizm-ghead .dcount { flex: 1 0 100%; font-size: var(--text-xs); color: var(--muted); font-weight: 500; }
/* editable name for added divers — reads as the name, dashed underline signals edit */
.dv-wizm-ghead__name { flex: 1 1 auto; min-width: 0; font: inherit; font-size: var(--text-md);
  font-weight: 700; letter-spacing: -0.01em; color: var(--ink); background: transparent;
  border: 0; border-bottom: 1px dashed var(--accent-border); padding: 1px 0 2px; outline: none; }
.dv-wizm-ghead__name::-moz-placeholder { color: var(--muted-2); font-weight: 500; }
.dv-wizm-ghead__name::placeholder { color: var(--muted-2); font-weight: 500; }
.dv-wizm-ghead__name:focus { border-bottom-color: var(--accent); }
/* line row — no icon column; name gets the width */
.dv-wizm-li { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: start; gap: 12px;
  padding: 12px 14px; border-top: 1px solid var(--hairline-2); position: relative; }
.dv-wizm-li:first-of-type { border-top: 0; }
.dv-wizm-li.is-hl { background: var(--accent-soft); }
.dv-wizm-li .info { min-width: 0; }
.dv-wizm-li .info .nm { font-size: var(--text-sm); font-weight: 600; color: var(--ink); display: block; }
.dv-wizm-li .info .dt { font-size: var(--text-xs); color: var(--muted); display: block; margin-top: 2px; }
.dv-wizm-li .info .sub { font-size: var(--text-xs); color: var(--muted); display: block; margin-top: 2px; }
.dv-wizm-li .info .ed { color: var(--accent); font-size: var(--text-xs); font-weight: 600; margin-top: 5px; display: inline-block; cursor: pointer; }
.dv-wizm-li .right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex: 0 0 auto; }
.dv-wizm-li .amt { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
.dv-wizm-card-empty { padding: 14px; font-size: var(--text-sm); color: var(--muted); }
.dv-wizm-cardfoot { padding: 10px 14px 12px; border-top: 1px solid var(--hairline-2); }
.dv-wizm-mob-adddate-btn { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px;
  font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--accent); background: transparent;
  border: 1px dashed var(--accent-border); border-radius: var(--radius-pill); cursor: pointer; }
.dv-wizm-mob-adddate-btn:active { background: var(--accent-soft); }
/* Fold the running total into the dives-step footer button (one row) — only
   that footer is tagged .dv-wizm-foot--folded, so other steps stay intact. */
.dv-wizm-foot-amt { display: none; }
@media (max-width: 640px) {
  :is(.wz-foot, .os-wz-foot).dv-wizm-foot--folded :is(.total, .os-total) { display: none; }
  :is(.wz-foot, .os-wz-foot).dv-wizm-foot--folded :is(.os-btn--primary, .dv-btn--primary) { justify-content: flex-start; }
  :is(.wz-foot, .os-wz-foot).dv-wizm-foot--folded .dv-wizm-foot-amt {
    display: inline; margin-left: auto; font-family: var(--font-mono); font-weight: 600; }
}
/* ============================================================
   summary-card.css — DiveOS Summary Card (design-system component).
   Header band · icon-tile rows · tinted total footer.
   Palette is a cool blue-gray surface (NOT the white card surface) so
   the summary reads as a distinct "running tally" object:
     · card    #F2F5F9   · icon tile #E3EAF2   · footer band #E3EAF1
   Type: label 12px · row title 14px/700 · desc 12px · icon 16 · price 24.
   ============================================================ */
:is(.ds-sum, .os-ds-sum) {
  --ds-sum-bg:     #F2F5F9;
  --ds-sum-tile:   #E3EAF2;
  --ds-sum-line:   var(--slate-200);
  --ds-sum-foot:   #E3EAF1;
  --ds-sum-bd:     #D5DEEA;   /* cool blue-gray outer border — bespoke to this card */
  background: var(--ds-sum-bg);
  border: 1px solid var(--ds-sum-bd);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.05), 0 1px 0 rgba(255,255,255,.6) inset;
  overflow: hidden;
}
/* header band */
:is(.ds-sum-head, .os-ds-sum-head) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 15px 20px 13px; }
:is(.ds-sum-head, .os-ds-sum-head) :is(.t, .os-t) { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; color: var(--slate-500, var(--slate-500)); white-space: nowrap; }
:is(.ds-sum-head, .os-ds-sum-head) :is(.st, .os-st) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); white-space: nowrap; }
:is(.ds-sum-head, .os-ds-sum-head) :is(.st, .os-st):is(.ok, .os-ok) { color: var(--confirmed); }
/* icon-tile rows */
:is(.ds-sum-row, .os-ds-sum-row) { display: flex; align-items: center; gap: 14px; padding: 12px 20px; border-top: 1px solid var(--ds-sum-line); }
:is(.ds-sum-row, .os-ds-sum-row):first-of-type { border-top: 0; }
:is(.ds-sum-row, .os-ds-sum-row) :is(.ico, .os-ico) { width: 36px; height: 36px; border-radius: var(--radius); background: var(--ds-sum-tile); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
/* The label keeps its natural width and never collapses. (It was `flex: 1` with
   `min-width: 0`, which with a `flex-basis: 0%` shrank the label box to 0 and let
   its text overflow onto the value.) The value takes the remaining space below. */
:is(.ds-sum-row, .os-ds-sum-row) :is(.main, .os-main) { flex: 0 0 auto; }
:is(.ds-sum-row, .os-ds-sum-row) :is(.main, .os-main) :is(.nm, .os-nm) { font-family: var(--font-sans); font-weight: 700; font-size: var(--text-sm); letter-spacing: -0.005em; color: var(--ink); line-height: 1.2; }
:is(.ds-sum-row, .os-ds-sum-row) :is(.main, .os-main) :is(.sub, .os-sub) { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; line-height: 1.2; }
/* The value takes the remaining space, right-aligned, and WRAPS a long token
   (e.g. a verbose vessel name) instead of nowrap-overflowing across the label.
   `flex: 1 1 auto` + `min-width: 0` lets it fill and shrink; `overflow-wrap:
   anywhere` breaks unbroken tokens. */
:is(.ds-sum-row, .os-ds-sum-row) :is(.val, .os-val) { flex: 1 1 auto; min-width: 0; font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500; letter-spacing: -0.01em; color: var(--ink); text-align: right; overflow-wrap: anywhere; }
/* progress strip (payment) */
:is(.ds-sum-prog, .os-ds-sum-prog) { padding: 13px 20px; border-top: 1px solid var(--ds-sum-line); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.bar, .os-bar) { height: 7px; border-radius: 99px; background: rgba(100,116,139,0.20); overflow: hidden; }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.bar, .os-bar) > span { display: block; height: 100%; border-radius: 99px; background: var(--accent); transition: width .25s cubic-bezier(0.32,0.72,0,1); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.bar, .os-bar):is(.full, .os-full) > span { background: var(--confirmed); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.row, .os-row) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 9px; font-size: var(--text-xs); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.row, .os-row) :is(.paid, .os-paid) { font-family: var(--font-mono); font-weight: 600; color: var(--accent); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.row, .os-row) :is(.paid, .os-paid):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.row, .os-row) :is(.total, .os-total) { color: var(--muted); }
:is(.ds-sum-prog, .os-ds-sum-prog) :is(.row, .os-row) :is(.total, .os-total) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.ds-sum-state, .os-ds-sum-state) { display: flex; align-items: center; gap: 8px; padding: 11px 20px; border-top: 1px solid var(--ds-sum-line); font-size: var(--text-xs); color: var(--gray-700); }
:is(.ds-sum-state, .os-ds-sum-state):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.ds-sum-state, .os-ds-sum-state):is(.no, .os-no) { color: var(--briefing); }
:is(.ds-sum-state, .os-ds-sum-state) :is(.ico, .os-ico) { display: inline-flex; }
:is(.ds-sum-defer, .os-ds-sum-defer) { display: flex; align-items: baseline; justify-content: space-between; padding: 0 20px 12px; margin-top: -2px; font-size: var(--text-xs); color: var(--muted); }
:is(.ds-sum-defer, .os-ds-sum-defer) :is(.mono, .os-mono) { font-family: var(--font-mono); }
/* tinted total footer */
:is(.ds-sum-foot, .os-ds-sum-foot) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 15px 20px; background: var(--ds-sum-foot); border-top: 1px solid var(--ds-sum-line); }
:is(.ds-sum-foot, .os-ds-sum-foot) :is(.k, .os-k) { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--slate-500, var(--slate-500)); }
:is(.ds-sum-foot, .os-ds-sum-foot) :is(.v, .os-v) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-2xl); letter-spacing: -0.02em; line-height: 1; }
:is(.ds-sum-foot, .os-ds-sum-foot) :is(.v, .os-v):is(.accent, .os-accent) { color: var(--accent); }
:is(.ds-sum-foot, .os-ds-sum-foot) :is(.v, .os-v):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.ds-sum-foot, .os-ds-sum-foot) :is(.v, .os-v) :is(.cents, .os-cents) { font-size: var(--text-md); color: var(--muted-2); }
/* progress-spine — the horizontal phase spine (.os-progress-spine); the public
   waiver wizard's four-phase progress (#413 design 4A). */
/* ─── Progress spine (.os-progress-spine) ────────────────────────────────────
   HORIZONTAL wizard progress: evenly-spread step nodes joined by connector
   segments that fill as steps complete. Each step is an icon node + label +
   optional mono meta line, in one of three states: done / now / todo.

   NOT the gem's `.os-stepper`, which is a different (vertical) component —
   this one neither extends nor replaces it.

   Origin: `.rd-stepper` / `.rd-step*` in arena-ops
   `app/assets/stylesheets/components/reservation_details.css` — the shipped
   original, ported faithfully; re-confirmed by the 2026-07-25 arrival-wizard
   redesign (mockups/arrival.html).

   API
     .os-progress-spine              the track (position: relative)
     .os-progress-spine__step        one step column
     .os-progress-spine__node        44px circle holding an icon
     .os-progress-spine__label       step name
     .os-progress-spine__meta        mono micro sub-line
     .os-progress-spine__seg         absolutely-positioned connector
     .os-progress-spine__seg--fill   progress overlay on a connector
     .os-progress-spine__badge       small warning pip on a delayed step
   States (on __step)
     --done   filled confirmed-green node, white glyph
     --now    accent-light fill, accent border, accent-soft ring
     --todo   muted label

   Composition notes
     · Composes inside `.os-status-card`, below its __head.
     · Segments are positioned by the callsite with layout-only inline
       left/width percentages (geometry, no colour or type) — that is the one
       sanctioned inline style for this component.
     · The spine is secondary navigation: done nodes may be clickable to go
       back; forward progress belongs to the page's primary action.
     · Light-only, token-driven.
   ────────────────────────────────────────────────────────────────────────── */
.os-progress-spine {
  display: flex;
  position: relative;
  padding: 26px var(--space-5) 22px;
}
/* ── Connectors ── */
.os-progress-spine__seg {
  position: absolute;
  top: 47px;
  height: 2px;
  background: var(--hairline);
  z-index: 0;
}
.os-progress-spine__seg--fill {
  background: var(--status-confirmed-fg);
}
/* ── Steps ── */
.os-progress-spine__step {
  flex: 1;
  min-width: 0;
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.os-progress-spine__node {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  display: grid;
  place-items: center;
  position: relative;
  z-index: 2;
  background: var(--surface);
  border: 2px solid var(--border-strong);
  color: var(--muted-2);
}
.os-progress-spine__label {
  font-size: var(--text-sm);
  font-weight: 640;
  color: var(--ink);
  margin-top: 10px;
}
.os-progress-spine__meta {
  font-size: var(--text-2xs);
  color: var(--muted);
  margin-top: 2px;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* ── States ── */
.os-progress-spine__step--done .os-progress-spine__node {
  background: var(--status-confirmed-fg);
  border-color: var(--status-confirmed-fg);
  color: var(--surface);
}
.os-progress-spine__step--now .os-progress-spine__node {
  background: var(--accent-light);
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 5px var(--accent-soft);
}
.os-progress-spine__step--todo .os-progress-spine__label {
  color: var(--muted);
  font-weight: 560;
}
/* ── Warning pip (e.g. a delayed step) ── */
.os-progress-spine__badge {
  position: absolute;
  top: -3px;
  right: calc(50% - 30px);
  z-index: 3;
  width: 16px;
  height: 16px;
  border-radius: var(--radius-pill);
  display: grid;
  place-items: center;
  background: var(--warning);
  color: var(--surface);
  border: 2px solid var(--surface);
}
/* ============================================================
   booking-v2.css — redesigned New Booking flow (Dives + Payment).
   Modern, instrument-grade chrome on the bound DiveOS tokens.
   Prefix: bk2-. Reuses wizard.css line-item widgets (.wz-li / .wz-sel
   / .wz-qty / .wz-price) inside new card/section/rail containers, plus
   three new primitives shared across both directions:
     · date-badge tile     (.bk2-dbadge)
     · KPI summary tiles    (.bk2-tiles / .bk2-tile)
     · balance meter        (.bk2-meter)
   Two directions, toggled by the `direction` Tweak on <html>:
     · .bk2-console  — dense control panel (tiles rail, split payment)
     · .bk2-itin     — roomier itinerary (day tickets, balance hero)
   No gradients, no glow; sky-50 used sparingly as the one tinted zone.
   ============================================================ */
/* ── Stage head with a count line ─────────────────────────── */
/* The redesigned flow drops per-step titles/descriptions — the breadcrumb
   header + wizard stepper already name the step. Hide reused steps' stage
   headers too (this stylesheet only loads on the v2 flow). */
:is(.wz-stage-head, .os-wz-stage-head) { display: none !important; }
/* ── Review ledger (reused step) — calmer, non-interactive hierarchy ──
   The diver name anchors each group (body ink, sentence case — not an
   accent "link"); shared fees use the same neutral band, not amber; the
   orphaned "Order" label is removed in the markup. */
:is(.wz-ledger, .os-wz-ledger) :is(.wz-grouphead, .os-wz-grouphead) { background: var(--sky-50); }
:is(.wz-ledger, .os-wz-ledger) :is(.wz-grouphead, .os-wz-grouphead) :is(.nm, .os-nm) { color: var(--ink); text-transform: none; letter-spacing: 0; font-size: var(--text-sm); font-weight: 600; }
:is(.wz-ledger, .os-wz-ledger) :is(.wz-grouphead, .os-wz-grouphead):is(.warm, .os-warm) { background: var(--sky-50); }
:is(.wz-ledger, .os-wz-ledger) :is(.wz-grouphead, .os-wz-grouphead):is(.warm, .os-warm) :is(.nm, .os-nm) { color: var(--ink); }
/* ── Done step — record status band uses slate, not gray-100 ── */
:is(.dn-rec-status, .os-dn-rec-status) { background: var(--sky-50); border-top: 1px solid var(--hairline-2); }
:is(.bk2-stage, .os-bk2-stage) { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 22px; }
:is(.bk2-stage, .os-bk2-stage) h2 { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl); letter-spacing: -0.02em; color: var(--ink); }
:is(.bk2-stage, .os-bk2-stage) p { margin: 7px 0 0; font-size: var(--text-sm); color: var(--muted); line-height: 1.5; max-width: 60ch; }
:is(.bk2-stage, .os-bk2-stage) :is(.meta, .os-meta) { display: flex; align-items: center; gap: 18px; flex-shrink: 0; }
:is(.bk2-stage, .os-bk2-stage) :is(.meta, .os-meta) :is(.m, .os-m) { text-align: right; }
:is(.bk2-stage, .os-bk2-stage) :is(.meta, .os-meta) :is(.m, .os-m) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
:is(.bk2-stage, .os-bk2-stage) :is(.meta, .os-meta) :is(.m, .os-m) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: 500; letter-spacing: -0.01em; color: var(--ink); margin-top: 3px; }
/* ── Two-column shell (content + rail) ────────────────────── */
/* Cap + centre the two-column steps (the full-bleed wizard has no outer cap).
   Dives sits inside .wz-inner (which already pads); Payment has no wrapper so
   it carries its own padding. Widths per design review. */
/* 800 caps the LEFT (diver-cards) column; the 348 order rail sits beside it.
   Grid content = 800 + 28 gap + 348 = 1176. (Dives is inside .wz-inner, which
   provides the page padding, so no padding here.) */
:root {
  /* Booking two-column grid width (800 + 28 gap + 348). Consumed here and by
     the Trip step's widened engine shell (booking-trip.css). */
  --booking-2col-max: 1176px;
  --receipt-top: 24px; /* public success/receipt pages: room above the hero on desktop (muf: 80px read too much, 2026-10-18) */
}
:is(.bk2-2col, .os-bk2-2col) { max-width: var(--booking-2col-max); margin-inline: auto; }
/* #290 — the Dives step wrapper must be wide enough for the 1176 grid to
   actually reach its designed size. The default .wz-inner (768) + .narrow (880)
   both starved it. 1256 = 1176 grid + the .wz-inner 40px side padding (×2), so
   the left diver column hits its intended 800px and the dive name stops
   clipping. .bk2-2col self-centres at 1176 on narrower viewports. */
:is(.wz-inner, .os-wz-inner):is(.wz-inner--dives, .os-wz-inner--dives) { max-width: 1256px; }
/* Payment: 720 caps the COMPOSER (left) column; the summary rail stays beside
   it at 360. Grid content = 720 + 28 gap + 360 = 1108 (+ 80 side padding). */
:is(.bk2-pay-rail, .os-bk2-pay-rail) { max-width: 1188px; margin-inline: auto; padding: 30px 40px 40px; }
:is(.bk2-2col, .os-bk2-2col) { display: grid; grid-template-columns: minmax(0,1fr) 348px; gap: 28px; align-items: start; }
@media (max-width: 1100px) { :is(.bk2-2col, .os-bk2-2col) { grid-template-columns: 1fr; } :is(.bk2-rail, .os-bk2-rail) { position: static !important; } }
:is(.bk2-col, .os-bk2-col) { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
/* The JS renders all diver cards + the shared-fees card into this wrapper, so it
   needs the same column rhythm — otherwise the cards inside stack flush (the
   .bk2-col gap only separates this wrapper from the add-diver button). */
[data-pos-dives-target="diverSections"] { display: flex; flex-direction: column; gap: 16px; }
:is(.bk2-rail, .os-bk2-rail) { position: sticky; top: 24px; display: flex; flex-direction: column; gap: 16px; }
/* ════════════════════════════════════════════════════════════
   DATE BADGE — the recurring instrument tile (sky-50)
   ════════════════════════════════════════════════════════════ */
:is(.bk2-dbadge, .os-bk2-dbadge) { display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 52px; height: 54px; border-radius: var(--radius); background: var(--sky-50);
  border: 1px solid var(--sky-200); color: var(--accent); line-height: 1; flex-shrink: 0; }
:is(.bk2-dbadge, .os-bk2-dbadge) :is(.m, .os-m) { font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; }
:is(.bk2-dbadge, .os-bk2-dbadge) :is(.d, .os-d) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl); letter-spacing: -0.02em; margin-top: 2px; }
:is(.bk2-dbadge, .os-bk2-dbadge) :is(.w, .os-w) { font-family: var(--font-mono); font-size: var(--text-2xs); letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.65; margin-top: 2px; }
/* ════════════════════════════════════════════════════════════
   DIVER CARD
   ════════════════════════════════════════════════════════════ */
:is(.bk2-dcard, .os-bk2-dcard) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.bk2-dhead, .os-bk2-dhead) { display: flex; align-items: center; gap: 13px; padding: 14px 18px; border-bottom: 1px solid var(--hairline); }
:is(.bk2-dhead, .os-bk2-dhead) :is(.who, .os-who) { display: flex; align-items: center; gap: 11px; min-width: 0; flex: 1; }
/* #289 — the name column must be able to shrink so a long name truncates
   instead of running under the "Primary" badge (which is pinned via
   flex-shrink:0 below). */
:is(.bk2-dhead__ident, .os-bk2-dhead__ident) { min-width: 0; flex: 1; }
:is(.bk2-dhead, .os-bk2-dhead) :is(.nm, .os-nm) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); letter-spacing: -0.01em; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
:is(.bk2-dhead, .os-bk2-dhead) :is(.name-input, .os-name-input) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px dashed var(--input-border); padding: 2px 0; outline: none; min-width: 190px; }
:is(.bk2-dhead, .os-bk2-dhead) :is(.name-input, .os-name-input):focus { border-bottom-color: var(--accent); }
:is(.bk2-dhead, .os-bk2-dhead) :is(.cert, .os-cert) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.bk2-dhead, .os-bk2-dhead) :is(.tot, .os-tot) { font-family: var(--font-mono); font-size: var(--text-md); font-weight: 500; letter-spacing: -0.01em; color: var(--ink); white-space: nowrap; }
:is(.bk2-dhead, .os-bk2-dhead) :is(.tot, .os-tot):is(.zero, .os-zero) { color: var(--muted-2); }
:is(.bk2-drm, .os-bk2-drm) { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0;
  background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); cursor: pointer; flex-shrink: 0; opacity: 0.6; transition: opacity .12s, background .12s, color .12s; }
:is(.bk2-dcard, .os-bk2-dcard):hover :is(.bk2-drm, .os-bk2-drm) { opacity: 1; }
:is(.bk2-drm, .os-bk2-drm):hover { background: var(--cancelled-bg); color: var(--cancelled); }
:is(.bk2-dconfirm, .os-bk2-dconfirm) { display: inline-flex; align-items: center; gap: 8px; padding: 4px 4px 4px 12px;
  background: var(--cancelled-bg); border: 1px solid var(--cancelled-border); border-radius: var(--radius-pill); }
:is(.bk2-dconfirm, .os-bk2-dconfirm) :is(.q, .os-q) { font-size: var(--text-xs); font-weight: 500; color: var(--cancelled); white-space: nowrap; }
:is(.bk2-dconfirm, .os-bk2-dconfirm) :is(.yes, .os-yes) { height: 26px; padding: 0 11px; font: inherit; font-size: var(--text-xs); font-weight: 600; color: var(--surface); background: var(--cancelled); border: 0; border-radius: var(--radius-pill); cursor: pointer; }
:is(.bk2-dconfirm, .os-bk2-dconfirm) :is(.no, .os-no) { height: 26px; padding: 0 9px; font: inherit; font-size: var(--text-xs); font-weight: 500; color: var(--muted); background: transparent; border: 0; cursor: pointer; }
/* ── Day section inside a diver card ──────────────────────── */
:is(.bk2-day, .os-bk2-day) { display: grid; grid-template-columns: 52px minmax(0,1fr); gap: 16px; padding: 16px 18px; border-top: 1px solid var(--hairline-2); }
:is(.bk2-day, .os-bk2-day):first-child { border-top: 0; }
:is(.bk2-day-spine, .os-bk2-day-spine) { display: flex; flex-direction: column; align-items: center; gap: 8px; }
:is(.bk2-day-spine, .os-bk2-day-spine) :is(.line, .os-line) { flex: 1; width: 1px; background: var(--hairline); min-height: 8px; }
:is(.bk2-day-main, .os-bk2-day-main) { min-width: 0; }
:is(.bk2-day-top, .os-bk2-day-top) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
:is(.bk2-day-top, .os-bk2-day-top) :is(.dl, .os-dl) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-sm); letter-spacing: -0.01em; color: var(--ink); }
:is(.bk2-day-top, .os-bk2-day-top) :is(.dl, .os-dl) :is(.full, .os-full) { color: var(--muted); font-weight: 400; font-family: var(--font-sans); font-size: var(--text-xs); margin-left: 7px; }
:is(.bk2-day-x, .os-bk2-day-x) { width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border: 0;
  background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); cursor: pointer; opacity: 0.5; transition: opacity .12s, color .12s, background .12s; }
:is(.bk2-day, .os-bk2-day):hover :is(.bk2-day-x, .os-bk2-day-x) { opacity: 1; }
:is(.bk2-day-x, .os-bk2-day-x):hover { background: var(--gray-100); color: var(--ink); }
/* line items — reuse .wz-li grid but lighter padding here */
:is(.bk2-items, .os-bk2-items) :is(.wz-li, .os-wz-li) { padding-left: 0; padding-right: 0; }
:is(.bk2-items, .os-bk2-items) :is(.wz-li-head, .os-wz-li-head) { padding-left: 0; padding-right: 0; }
/* add chips under a day */
:is(.bk2-addrow, .os-bk2-addrow) { display: flex; gap: 8px; margin-top: 8px; }
:is(.bk2-addchip, .os-bk2-addchip) { display: inline-flex; align-items: center; gap: 5px; padding: 5px 12px; font: inherit; font-size: var(--text-xs); font-weight: 500;
  color: var(--accent); background: transparent; border: 1px dashed var(--accent-border); border-radius: var(--radius-pill); cursor: pointer; }
:is(.bk2-addchip, .os-bk2-addchip):hover { background: var(--accent-softer); }
:is(.bk2-addchip, .os-bk2-addchip):is(.add, .os-add) { color: var(--confirmed); border-color: var(--confirmed-border); }
:is(.bk2-addchip, .os-bk2-addchip):is(.add, .os-add):hover { background: var(--confirmed-bg); }
/* add-date footer of a card — opens the browser-native date picker */
:is(.bk2-adddate, .os-bk2-adddate) { padding: 12px 18px; border-top: 1px solid var(--hairline-2); }
:is(.bk2-adddate-wrap, .os-bk2-adddate-wrap) { position: relative; }
/* #493 D3 — the "Add another…" tiles are the real button (.os-btn --ghost
   --field: 46px on the control scale, was 44 / 52). This is only the dashed
   full-width MODIFIER on top of it — size, type and radius are the button's. */
:is(.bk2-adddate-btn, .os-bk2-adddate-btn) { display: flex; width: 100%;
  border: 1.5px dashed var(--accent-border); transition: background .12s, border-color .12s; }
:is(.bk2-adddate-btn, .os-bk2-adddate-btn):hover { background: var(--accent-softer); border-color: var(--accent); }
:is(.bk2-date-native, .os-bk2-date-native) { position: absolute; left: 16px; bottom: 4px; width: 1px; height: 1px; opacity: 0; border: 0; padding: 0; margin: 0; pointer-events: none; }
/* shared fees + add-diver */
:is(.bk2-fees-head, .os-bk2-fees-head) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--hairline); }
:is(.bk2-fees-head, .os-bk2-fees-head) :is(.t, .os-t) { font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); }
:is(.bk2-fees-head, .os-bk2-fees-head) :is(.c, .os-c) { font-size: var(--text-xs); color: var(--muted); }
:is(.bk2-fees-head, .os-bk2-fees-head) :is(.a, .os-a) { font-size: var(--text-sm); font-weight: 500; color: var(--accent); cursor: pointer; display: inline-flex; align-items: center; gap: 5px; background: none; border: 0; font-family: inherit; padding: 0; }
:is(.bk2-fees-head, .os-bk2-fees-head) :is(.a, .os-a):hover { color: var(--accent-strong); }
:is(.bk2-fee, .os-bk2-fee) { display: grid; grid-template-columns: 22px minmax(0,1fr) 104px 92px 88px 36px; align-items: center; gap: 12px; padding: 9px 18px; border-top: 1px solid var(--hairline-2); }
:is(.bk2-fee, .os-bk2-fee):first-of-type { border-top: 0; }
:is(.bk2-fee, .os-bk2-fee) :is(.kind, .os-kind) { display: inline-flex; justify-content: center; color: var(--muted); }
:is(.bk2-fee, .os-bk2-fee) :is(.amt, .os-amt) { text-align: right; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.bk2-fee-empty, .os-bk2-fee-empty) { padding: 14px 18px; font-size: var(--text-sm); color: var(--muted-2); font-style: italic; }
:is(.bk2-adddiver, .os-bk2-adddiver) { display: flex; width: 100%;
  border: 1.5px dashed var(--accent-border); }
:is(.bk2-adddiver, .os-bk2-adddiver):hover { background: var(--accent-softer); }
/* package header band — accent-tinted, sits above a diver's day cards */
:is(.bk2-pkghead, .os-bk2-pkghead) { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 12px 12px; padding: 8px 12px; color: var(--accent);
  background: var(--accent-soft); border: 1px solid var(--accent-border); border-radius: var(--radius); }
:is(.bk2-pkghead__main, .os-bk2-pkghead__main) { display: flex; align-items: center; gap: 8px; min-width: 0; }
:is(.bk2-pkghead__title, .os-bk2-pkghead__title) { font-size: var(--text-sm); font-weight: 600; color: var(--accent); }
:is(.bk2-pkghead__price, .os-bk2-pkghead__price) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--accent); }
:is(.bk2-pkghead__remove, .os-bk2-pkghead__remove) { font: inherit; font-size: var(--text-xs); font-weight: 500; color: var(--danger);
  background: transparent; border: 1px solid var(--danger-border); border-radius: var(--radius-sm);
  padding: 4px 10px; cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
:is(.bk2-pkghead__remove, .os-bk2-pkghead__remove):hover { background: var(--danger-bg); border-color: var(--danger); }
/* ════════════════════════════════════════════════════════════
   ITINERARY direction — day ticket band per date
   ════════════════════════════════════════════════════════════ */
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-day, .os-bk2-day) { display: block; padding: 0; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-day-spine, .os-bk2-day-spine) { display: none; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) { display: flex; align-items: center; gap: 11px; padding: 13px 18px;
  background: var(--bk2-band, var(--sky-50)); border-top: 1px solid var(--bk2-band-bd, var(--sky-200)); border-bottom: 1px solid var(--bk2-band-bd, var(--sky-200)); }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-day, .os-bk2-day):first-child :is(.bk2-ticketband, .os-bk2-ticketband) { border-top: 0; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) :is(.cal, .os-cal) { display: inline-flex; color: var(--accent); flex-shrink: 0; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) :is(.dtxt, .os-dtxt) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-sm); letter-spacing: -0.005em; color: var(--ink); white-space: nowrap; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) :is(.dow, .os-dow) { font-size: var(--text-xs); color: var(--muted); white-space: nowrap; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) :is(.dow, .os-dow)::before { content: '·'; margin-right: 7px; color: var(--muted-2); }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) :is(.cnt, .os-cnt) { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--accent); white-space: nowrap;
  background: var(--surface); border: 1px solid var(--accent-border); border-radius: var(--radius-pill); padding: 3px 10px; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticketband, .os-bk2-ticketband) :is(.wz-li-acts, .os-wz-li-acts) { display: inline-flex; align-items: center; gap: 2px; }
:is(.bk2-itin, .os-bk2-itin) :is(.bk2-ticket-body, .os-bk2-ticket-body) { padding: 8px 18px 14px; }
/* ════════════════════════════════════════════════════════════
   RAIL · KPI summary tiles (console direction)
   ════════════════════════════════════════════════════════════ */
:is(.bk2-card, .os-bk2-card) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.bk2-card-head, .os-bk2-card-head) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--hairline); }
:is(.bk2-card-head, .os-bk2-card-head) :is(.t, .os-t) { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
:is(.bk2-card-head, .os-bk2-card-head) :is(.ico, .os-ico) { color: var(--muted-2); display: inline-flex; }
:is(.bk2-tiles, .os-bk2-tiles) { display: grid; grid-template-columns: 1fr 1fr; }
:is(.bk2-tile, .os-bk2-tile) { display: flex; align-items: center; gap: 12px; padding: 15px 16px; border-top: 1px solid var(--hairline-2); border-left: 1px solid var(--hairline-2); }
:is(.bk2-tile, .os-bk2-tile):nth-child(-n+2) { border-top: 0; }
:is(.bk2-tile, .os-bk2-tile):nth-child(odd) { border-left: 0; }
:is(.bk2-tile, .os-bk2-tile) :is(.ico, .os-ico) { width: 38px; height: 38px; border-radius: var(--radius); background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
:is(.bk2-tile, .os-bk2-tile) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
:is(.bk2-tile, .os-bk2-tile) :is(.v, .os-v) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl); letter-spacing: -0.01em; color: var(--ink); margin-top: 2px; line-height: 1; }
:is(.bk2-tile, .os-bk2-tile) :is(.v, .os-v):is(.sm, .os-sm) { font-size: var(--text-sm); }
/* rail itemized breakdown */
:is(.bk2-break, .os-bk2-break) { max-height: 38vh; overflow-y: auto; padding: 4px 16px; }
:is(.bk2-break-grp, .os-bk2-break-grp) { padding: 11px 0; border-top: 1px solid var(--hairline-2); }
:is(.bk2-break-grp, .os-bk2-break-grp):first-child { border-top: 0; }
:is(.bk2-break-grp, .os-bk2-break-grp) :is(.gh, .os-gh) { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; }
:is(.bk2-break-grp, .os-bk2-break-grp) :is(.gh, .os-gh) :is(.nm, .os-nm) { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); }
:is(.bk2-break-grp, .os-bk2-break-grp) :is(.gh, .os-gh) :is(.nm, .os-nm):is(.unset, .os-unset) { color: var(--muted-2); }
:is(.bk2-break-grp, .os-bk2-break-grp) :is(.gh, .os-gh) :is(.nm, .os-nm):is(.warm, .os-warm) { color: var(--gray-700); }
:is(.bk2-break-grp, .os-bk2-break-grp) :is(.gh, .os-gh) :is(.tt, .os-tt) { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink); }
:is(.bk2-break-li, .os-bk2-break-li) { display: flex; justify-content: space-between; gap: 8px; font-size: var(--text-xs); padding: 2px 0; }
:is(.bk2-break-li, .os-bk2-break-li) :is(.nm, .os-nm) { color: var(--gray-700); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.bk2-break-li, .os-bk2-break-li) :is(.dt, .os-dt) { color: var(--muted-2); font-family: var(--font-mono); }
:is(.bk2-break-li, .os-bk2-break-li) :is(.amt, .os-amt) { font-family: var(--font-mono); color: var(--muted); flex-shrink: 0; }
:is(.bk2-break-li, .os-bk2-break-li):is(.empty, .os-empty) { font-style: italic; color: var(--muted-2); }
:is(.bk2-total, .os-bk2-total) { display: flex; align-items: baseline; justify-content: space-between; padding: 14px 18px; border-top: 1px solid var(--hairline); background: var(--wz-tint); }
:is(.bk2-total, .os-bk2-total) :is(.k, .os-k) { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
:is(.bk2-total, .os-bk2-total) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-2xl); font-weight: 500; letter-spacing: -0.02em; color: var(--accent); }
/* roll-up (itinerary rail) */
:is(.bk2-roll, .os-bk2-roll) { padding: 4px 16px; }
:is(.bk2-rollrow, .os-bk2-rollrow) { display: flex; align-items: center; gap: 11px; padding: 11px 0; border-top: 1px solid var(--hairline-2); }
:is(.bk2-rollrow, .os-bk2-rollrow):first-child { border-top: 0; }
:is(.bk2-rollrow, .os-bk2-rollrow) :is(.who, .os-who) { flex: 1; min-width: 0; }
:is(.bk2-rollrow, .os-bk2-rollrow) :is(.who, .os-who) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.bk2-rollrow, .os-bk2-rollrow) :is(.who, .os-who) :is(.sub, .os-sub) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; }
:is(.bk2-rollrow, .os-bk2-rollrow) :is(.so-ico, .os-so-ico) { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--gray-100); color: var(--gray-500); flex-shrink: 0; }
:is(.bk2-rollrow, .os-bk2-rollrow) :is(.amt, .os-amt) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
/* special requests */
:is(.bk2-notes, .os-bk2-notes) { padding: 16px 18px; }
:is(.bk2-notes, .os-bk2-notes) label { display: block; font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
:is(.bk2-notes, .os-bk2-notes) textarea { width: 100%; box-sizing: border-box; padding: 9px 11px; resize: vertical; font-family: var(--font-sans);
  font-size: var(--text-sm); line-height: 1.5; color: var(--ink); background: var(--input-bg); border: 1px solid var(--input-border); border-radius: var(--radius-sm); outline: none; }
:is(.bk2-notes, .os-bk2-notes) textarea:focus { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
/* ════════════════════════════════════════════════════════════
   BALANCE METER — shared payment primitive
   ════════════════════════════════════════════════════════════ */
:is(.bk2-meter, .os-bk2-meter) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); padding: 20px 22px; }
:is(.bk2-meter, .os-bk2-meter) :is(.eyebrow, .os-eyebrow) { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
:is(.bk2-meter, .os-bk2-meter) :is(.amt, .os-amt) { font-family: var(--font-display); font-weight: 600; font-size: 44px; letter-spacing: -0.03em; color: var(--ink); margin: 12px 0 2px; line-height: 1; }
:is(.bk2-meter, .os-bk2-meter) :is(.amt, .os-amt) :is(.cents, .os-cents) { color: var(--muted-2); font-size: var(--text-3xl); }
:is(.bk2-meter, .os-bk2-meter) :is(.amt, .os-amt):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-meter, .os-bk2-meter) :is(.sub, .os-sub) { font-size: var(--text-xs); color: var(--muted); }
:is(.bk2-meter, .os-bk2-meter) :is(.bar, .os-bar) { height: 8px; border-radius: 99px; background: var(--gray-200); overflow: hidden; margin: 18px 0 11px; }
:is(.bk2-meter, .os-bk2-meter) :is(.bar, .os-bar) > span { display: block; height: 100%; border-radius: 99px; background: var(--accent); transition: width .25s cubic-bezier(0.32,0.72,0,1); }
:is(.bk2-meter, .os-bk2-meter) :is(.bar, .os-bar):is(.full, .os-full) > span { background: var(--confirmed); }
:is(.bk2-meter, .os-bk2-meter) :is(.foot, .os-foot) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: var(--text-sm); }
:is(.bk2-meter, .os-bk2-meter) :is(.foot, .os-foot) :is(.paid, .os-paid) { font-family: var(--font-mono); font-weight: 600; color: var(--accent); }
:is(.bk2-meter, .os-bk2-meter) :is(.foot, .os-foot) :is(.paid, .os-paid):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-meter, .os-bk2-meter) :is(.foot, .os-foot) :is(.total, .os-total) { color: var(--muted); }
:is(.bk2-meter, .os-bk2-meter) :is(.foot, .os-foot) :is(.total, .os-total) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.bk2-meter, .os-bk2-meter) :is(.state, .os-state) { display: flex; align-items: center; gap: 9px; margin-top: 16px; padding-top: 15px; border-top: 1px solid var(--hairline-2); font-size: var(--text-sm); color: var(--gray-700); }
:is(.bk2-meter, .os-bk2-meter) :is(.state, .os-state) :is(.tick, .os-tick) { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0; }
:is(.bk2-meter, .os-bk2-meter) :is(.state, .os-state):is(.ok, .os-ok) :is(.tick, .os-tick) { background: var(--confirmed-bg); color: var(--confirmed); }
:is(.bk2-meter, .os-bk2-meter) :is(.state, .os-state):is(.no, .os-no) :is(.tick, .os-tick) { background: var(--briefing-bg); color: var(--briefing); }
:is(.bk2-meter, .os-bk2-meter) :is(.defer, .os-defer) { display: flex; align-items: baseline; justify-content: space-between; margin-top: 10px; font-size: var(--text-xs); color: var(--muted); }
:is(.bk2-meter, .os-bk2-meter) :is(.defer, .os-defer) :is(.mono, .os-mono) { font-family: var(--font-mono); }
/* ════════════════════════════════════════════════════════════
   PAYMENT layouts
   ════════════════════════════════════════════════════════════ */
:is(.bk2-pay-split, .os-bk2-pay-split) { display: grid; grid-template-columns: 340px minmax(0,1fr); gap: 26px; align-items: start; }
@media (max-width: 1040px) { :is(.bk2-pay-split, .os-bk2-pay-split) { grid-template-columns: 1fr; } }
:is(.bk2-pay-split, .os-bk2-pay-split) :is(.bk2-meter, .os-bk2-meter) { position: sticky; top: 24px; }
/* itinerary payment — full-width meter hero on a tinted band */
:is(.bk2-pay-hero, .os-bk2-pay-hero) { background: var(--sky-50); border: 1px solid var(--sky-200); border-radius: var(--radius-lg); padding: 22px 24px; margin-bottom: 20px;
  display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 28px; align-items: center; }
@media (max-width: 760px) { :is(.bk2-pay-hero, .os-bk2-pay-hero) { grid-template-columns: 1fr; } }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.lead, .os-lead) :is(.eyebrow, .os-eyebrow) { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sky-800); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.lead, .os-lead) :is(.amt, .os-amt) { font-family: var(--font-display); font-weight: 600; font-size: 50px; letter-spacing: -0.03em; color: var(--ink); margin: 10px 0 4px; line-height: 1; }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.lead, .os-lead) :is(.amt, .os-amt) :is(.cents, .os-cents) { color: var(--sky-700); opacity: 0.6; font-size: var(--text-3xl); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.lead, .os-lead) :is(.amt, .os-amt):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.lead, .os-lead) :is(.sub, .os-sub) { font-size: var(--text-sm); color: var(--sky-800); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) { width: 232px; }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.bar, .os-bar) { height: 8px; border-radius: 99px; background: rgba(3,105,161,0.14); overflow: hidden; }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.bar, .os-bar) > span { display: block; height: 100%; border-radius: 99px; background: var(--accent); transition: width .25s cubic-bezier(0.32,0.72,0,1); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.bar, .os-bar):is(.full, .os-full) > span { background: var(--confirmed); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.row, .os-row) { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 10px; font-size: var(--text-xs); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.row, .os-row) :is(.paid, .os-paid) { font-family: var(--font-mono); font-weight: 600; color: var(--accent); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.row, .os-row) :is(.paid, .os-paid):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.row, .os-row) :is(.total, .os-total) { color: var(--sky-800); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.state, .os-state) { display: flex; align-items: center; gap: 8px; margin-top: 14px; font-size: var(--text-xs); font-weight: 500; }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.state, .os-state):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-pay-hero, .os-bk2-pay-hero) :is(.gauge, .os-gauge) :is(.state, .os-state):is(.no, .os-no) { color: var(--briefing); }
/* method chips */
:is(.bk2-methods, .os-bk2-methods) { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
:is(.bk2-pm, .os-bk2-pm) { display: inline-flex; align-items: center; gap: 8px; padding: 9px 15px; font: inherit; font-size: var(--text-sm); font-weight: 500;
  color: var(--gray-700); background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-pill); cursor: pointer; transition: all .12s ease; }
:is(.bk2-pm, .os-bk2-pm):hover { border-color: var(--accent-border); color: var(--accent); background: var(--accent-softer); }
:is(.bk2-pm, .os-bk2-pm) :is(.ico, .os-ico) { color: var(--muted-2); display: inline-flex; }
:is(.bk2-pm, .os-bk2-pm):hover :is(.ico, .os-ico) { color: var(--accent); }
/* #379 — off-premises settlement methods, revealed by the "Other" disclosure.
   Indented and rule-led so they read as a subordinate group rather than five
   more peers of Cash. Same chip component, quieter resting state: these are
   the exception, not the common path. */
:is(.bk2-methods--other, .os-bk2-methods--other) {
  margin-top: -8px; padding-left: 12px;
  border-left: 2px solid var(--hairline);
}
:is(.bk2-pm--other, .os-bk2-pm--other) { background: var(--surface-alt); color: var(--muted); }
/* #379 — the optional booking ref sitting under the Agent Paid row's agent
   picker. Secondary to the picker above it, so it sits quieter and tighter. */
:is(.bk2-mi--ref, .os-bk2-mi--ref) { margin-top: 6px; font-size: var(--text-xs); }
/* payment rows ledger */
:is(.bk2-prows, .os-bk2-prows) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.bk2-prow, .os-bk2-prow) { display: grid; grid-template-columns: 168px minmax(0,1fr) minmax(0,1fr) 32px; gap: 16px; align-items: start; padding: 16px 18px; border-top: 1px solid var(--hairline-2); }
:is(.bk2-prow, .os-bk2-prow):first-child { border-top: 0; }
:is(.bk2-prow, .os-bk2-prow) > div { min-width: 0; }
:is(.bk2-prow, .os-bk2-prow) :is(.fl, .os-fl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; display: flex; align-items: center; min-height: 14px; }
:is(.bk2-prow, .os-bk2-prow) :is(.fl, .os-fl) :is(.req, .os-req) { color: var(--error); margin-left: 3px; }
:is(.bk2-prow, .os-bk2-prow) :is(.rm, .os-rm) { align-self: start; margin-top: 19px; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0; background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); cursor: pointer; }
:is(.bk2-prow, .os-bk2-prow) :is(.rm, .os-rm):hover { background: var(--cancelled-bg); color: var(--cancelled); }
:is(.bk2-mi, .os-bk2-mi) { width: 100%; box-sizing: border-box; height: 36px; padding: 0 11px; font: inherit; font-size: var(--text-sm); color: var(--ink);
  background: var(--input-bg); border: 1px solid var(--input-border); border-radius: var(--radius-sm); outline: none; }
:is(.bk2-mi, .os-bk2-mi):is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.bk2-mi, .os-bk2-mi):focus { border-color: var(--input-border-focus); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.bk2-psub, .os-bk2-psub) { font-size: var(--text-xs); color: var(--muted); margin-top: 6px; }
:is(.bk2-psub, .os-bk2-psub):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-pro, .os-bk2-pro) { height: 36px; display: flex; align-items: center; font-size: var(--text-sm); color: var(--muted-2); }
:is(.bk2-pcheck, .os-bk2-pcheck) { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: var(--text-xs); color: var(--muted); margin-top: 6px; }
:is(.bk2-pcheck, .os-bk2-pcheck) input { width: 14px; height: 14px; accent-color: var(--accent); }
:is(.bk2-pempty, .os-bk2-pempty) { padding: 22px 18px; text-align: center; font-size: var(--text-sm); color: var(--muted-2); }
/* attribution */
:is(.bk2-attr, .os-bk2-attr) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; margin-top: 16px; }
:is(.bk2-attr-top, .os-bk2-attr-top) { display: flex; align-items: center; gap: 10px; padding: 14px 18px; cursor: pointer; }
/* DiveOS painted checkbox (.diveos-check) is centred to the single-line label here. */
:is(.bk2-attr-top, .os-bk2-attr-top):is(.diveos-check, .os-field-check) { align-items: center; }
:is(.bk2-attr-top, .os-bk2-attr-top) :is(.diveos-check__box, .os-field-check__box) { margin-top: 0; }
:is(.bk2-attr-top, .os-bk2-attr-top) :is(.t, .os-t) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.bk2-attr-body, .os-bk2-attr-body) { padding: 4px 18px 18px; border-top: 1px solid var(--hairline-2); display: flex; flex-direction: column; gap: 14px; }
:is(.bk2-attr-fl, .os-bk2-attr-fl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); margin: 12px 0 8px; }
:is(.bk2-chips, .os-bk2-chips) { display: flex; flex-wrap: wrap; gap: 8px; }
:is(.bk2-chip, .os-bk2-chip) { display: inline-flex; align-items: center; gap: 9px; padding: 6px 12px 6px 7px; border: 1px solid var(--hairline); border-radius: var(--radius-pill); background: var(--surface); cursor: pointer; transition: border-color .12s, background .12s; }
:is(.bk2-chip, .os-bk2-chip):hover { border-color: var(--accent-border); background: var(--accent-softer); }
:is(.bk2-chip, .os-bk2-chip):is(.on, .os-on) { border-color: var(--accent); background: var(--accent-softer); }
:is(.bk2-chip, .os-bk2-chip) :is(.who, .os-who) { display: flex; flex-direction: column; line-height: 1.25; text-align: left; }
:is(.bk2-chip, .os-bk2-chip) :is(.who, .os-who) :is(.nm, .os-nm) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.bk2-chip, .os-bk2-chip) :is(.who, .os-who) :is(.role, .os-role) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted-2); }
:is(.bk2-chip, .os-bk2-chip):is(.on, .os-on) :is(.who, .os-who) :is(.role, .os-role) { color: var(--accent); }
:is(.bk2-chip, .os-bk2-chip) :is(.tick, .os-tick) { display: inline-flex; color: var(--accent); }
:is(.bk2-commrow, .os-bk2-commrow) { display: flex; align-items: center; gap: 12px; }
:is(.bk2-commrow, .os-bk2-commrow) :is(.wz-price, .os-wz-price) { height: 36px; }
:is(.bk2-commrow, .os-bk2-commrow) :is(.note, .os-note) { font-size: var(--text-xs); color: var(--muted); }
:is(.bk2-commrow, .os-bk2-commrow) :is(.note, .os-note) button { background: none; border: 0; color: var(--accent); font: inherit; font-size: var(--text-xs); cursor: pointer; padding: 0; margin-left: 6px; }
/* ════════════════════════════════════════════════════════════
   SUMMARY CARD — package-builder style (header band · icon rows ·
   tinted total footer). Reused as the Payment right rail.
   ════════════════════════════════════════════════════════════ */
:is(.bk2-pay-rail, .os-bk2-pay-rail) { display: grid; grid-template-columns: minmax(0,1fr) 360px; gap: 28px; align-items: start; }
@media (max-width: 1080px) { :is(.bk2-pay-rail, .os-bk2-pay-rail) { grid-template-columns: 1fr; } :is(.bk2-pay-rail, .os-bk2-pay-rail) :is(.ds-sum, .os-ds-sum) { position: static !important; } }
:is(.bk2-pay-rail, .os-bk2-pay-rail) :is(.ds-sum, .os-ds-sum) { position: sticky; top: 24px; }
:is(.bk2-sumcard, .os-bk2-sumcard) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-xl);
  box-shadow: 0 1px 2px rgba(17,24,39,.04); overflow: hidden; }
:is(.bk2-sumcard-head, .os-bk2-sumcard-head) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 22px;
  background: var(--surface-alt); border-bottom: 1px solid var(--hairline); }
:is(.bk2-sumcard-head, .os-bk2-sumcard-head) :is(.t, .os-t) { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase; color: var(--slate-500); }
:is(.bk2-sumcard-head, .os-bk2-sumcard-head) :is(.st, .os-st) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); white-space: nowrap; }
:is(.bk2-sumcard-head, .os-bk2-sumcard-head) :is(.st, .os-st):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-sumrow, .os-bk2-sumrow) { display: flex; align-items: center; gap: 16px; padding: 16px 22px; border-top: 1px solid var(--hairline-2); }
:is(.bk2-sumrow, .os-bk2-sumrow):first-of-type { border-top: 0; }
:is(.bk2-sumrow, .os-bk2-sumrow) :is(.ico, .os-ico) { color: var(--muted-2); display: inline-flex; flex-shrink: 0; }
:is(.bk2-sumrow, .os-bk2-sumrow) :is(.main, .os-main) { flex: 1; min-width: 0; }
:is(.bk2-sumrow, .os-bk2-sumrow) :is(.main, .os-main) :is(.nm, .os-nm) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); letter-spacing: -0.01em; color: var(--ink); line-height: 1.15; }
:is(.bk2-sumrow, .os-bk2-sumrow) :is(.main, .os-main) :is(.sub, .os-sub) { font-size: var(--text-sm); color: var(--muted); margin-top: 2px; }
:is(.bk2-sumrow, .os-bk2-sumrow) :is(.val, .os-val) { font-family: var(--font-mono); font-size: var(--text-md); font-weight: 500; letter-spacing: -0.01em; color: var(--ink); white-space: nowrap; }
/* progress strip above the footer */
:is(.bk2-sumprog, .os-bk2-sumprog) { padding: 15px 22px; border-top: 1px solid var(--hairline-2); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.bar, .os-bar) { height: 7px; border-radius: 99px; background: var(--gray-200); overflow: hidden; }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.bar, .os-bar) > span { display: block; height: 100%; border-radius: 99px; background: var(--accent); transition: width .25s cubic-bezier(0.32,0.72,0,1); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.bar, .os-bar):is(.full, .os-full) > span { background: var(--confirmed); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.row, .os-row) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 9px; font-size: var(--text-xs); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.row, .os-row) :is(.paid, .os-paid) { font-family: var(--font-mono); font-weight: 600; color: var(--accent); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.row, .os-row) :is(.paid, .os-paid):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.row, .os-row) :is(.total, .os-total) { color: var(--muted); }
:is(.bk2-sumprog, .os-bk2-sumprog) :is(.row, .os-row) :is(.total, .os-total) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.bk2-sumcard-foot, .os-bk2-sumcard-foot) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 22px;
  background: var(--slate-100); border-top: 1px solid var(--hairline); }
:is(.bk2-sumcard-foot, .os-bk2-sumcard-foot) :is(.k, .os-k) { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--slate-500); }
:is(.bk2-sumcard-foot, .os-bk2-sumcard-foot) :is(.v, .os-v) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-3xl); letter-spacing: -0.025em; color: var(--accent); line-height: 1; }
:is(.bk2-sumcard-foot, .os-bk2-sumcard-foot) :is(.v, .os-v):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-sumcard-foot, .os-bk2-sumcard-foot) :is(.v, .os-v) :is(.cents, .os-cents) { font-size: var(--text-lg); color: var(--muted-2); }
:is(.bk2-sumcard-state, .os-bk2-sumcard-state) { display: flex; align-items: center; gap: 8px; padding: 13px 22px; border-top: 1px solid var(--hairline-2); font-size: var(--text-xs); color: var(--gray-700); }
:is(.bk2-sumcard-state, .os-bk2-sumcard-state):is(.ok, .os-ok) { color: var(--confirmed); }
:is(.bk2-sumcard-state, .os-bk2-sumcard-state):is(.no, .os-no) { color: var(--briefing); }
:is(.bk2-sumcard-state, .os-bk2-sumcard-state) :is(.ico, .os-ico) { display: inline-flex; }
:is(.bk2-sumcard-defer, .os-bk2-sumcard-defer) { display: flex; align-items: baseline; justify-content: space-between; padding: 0 22px 14px; margin-top: -4px; font-size: var(--text-xs); color: var(--muted); }
:is(.bk2-sumcard-defer, .os-bk2-sumcard-defer) :is(.mono, .os-mono) { font-family: var(--font-mono); }
/* Stepper band — centered, narrower block (per direct edits) */
:is(.wz-bars-inner, .os-wz-bars-inner) { max-width: 720px; }
/* compact density trims */
:is(.wz-compact, .os-wz-compact) :is(.bk2-day, .os-bk2-day) { padding-top: 11px; padding-bottom: 11px; }
:is(.wz-compact, .os-wz-compact) :is(.bk2-tile, .os-bk2-tile) { padding-top: 11px; padding-bottom: 11px; }
:is(.wz-compact, .os-wz-compact) :is(.bk2-prow, .os-bk2-prow) { padding-top: 11px; padding-bottom: 11px; }
/* Desktop: dates sit beside the name (DOM order is name, price, dates). */
:is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) :is(.nm, .os-nm) { order: 1; }
:is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) :is(.dts, .os-dts) { order: 2; margin-right: auto; }
:is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) :is(.sub, .os-sub) { order: 3; }
/* Review ledger group head, mobile (mirrors .dv-wizm-ghead): name never wraps,
   price right-aligned on the name row, dates on their own line underneath. */
@media (max-width: 640px) {
  :is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) { flex-wrap: wrap; align-items: baseline; -moz-column-gap: var(--space-3); column-gap: var(--space-3); row-gap: var(--space-0-5); padding: var(--space-3) var(--space-4); }
  :is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) :is(.nm, .os-nm) { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
  :is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) :is(.sub, .os-sub) { flex: 0 0 auto; }
  :is(.wz-ledger, .os-wz-ledger, .booking-wizard) :is(.wz-grouphead, .os-wz-grouphead) :is(.dts, .os-dts) { order: 4; flex: 1 0 100%; white-space: normal; margin-right: 0; }
}
/* ════════════════════════════════════════════════════════════
   #609 R4 — one card frame (muf, 2026-10-07). In the staff booking / quote
   wizard the diver cards, shared fees, special requests and the order summary
   sit on the os-card frame: hairline border, radius-lg, NO shadow, and the
   24px content inset (was an 18px inset with a drop shadow, and the summary
   in its own blue-gray frame). Scoped to .bk2-dives, the account wizard; the
   public booking engine (.bk2-trip) keeps its own frame. The summary's tinted
   Total band stays — it is the card's footer, not its frame.
   ════════════════════════════════════════════════════════════ */
:is(.bk2-dives, .os-bk2-dives) :is(.bk2-card, .bk2-dcard, .ds-sum) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: none;
}
/* Content rows sit at 24px. A day block is not padded itself: its tinted
   ticket band must stay full-bleed (nor is the wrapper the renderer puts
   around the days), so the band + body carry the inset. */
:is(.bk2-dives, .os-bk2-dives) :is(.bk2-card:not(.bk2-notes), .bk2-dcard, .ds-sum) > :not(.bk2-day, :has(> .bk2-day)) { padding-inline: var(--space-6); }
:is(.bk2-dives, .os-bk2-dives) .bk2-dcard .bk2-day > :is(.bk2-ticketband, .bk2-ticket-body) { padding-inline: var(--space-6); }
:is(.bk2-dives, .os-bk2-dives) .bk2-notes { padding: var(--space-6); }
/* #463 — public booking package Trip step (token-only additions). */
/* ============================================================
   booking-trip.css — public booking funnel, package Trip step
   (#463 / #472). Rendered by app/javascript/lib/package_trip_renderer.js
   inside the internal New Booking itinerary container (booking-v2.css):
     .bk2-itin > .bk2-dcard > .bk2-dhead + .bk2-day > .bk2-ticketband
     + .bk2-ticket-body   (shared/components/_itinerary_row)
   and the os-ds calendar popover (.os-pop.os-pop--cal > .os-cals > .os-cal).
   Token-only additions:
     · --bk2-extra* colour role     extra dive days: light accent (package days = solid accent)
     · .bk2-trip                    widens the engine shell to the 2-col width
     · .bk2-tripday / .bk2-daytag   compact day rows (os-daterail) + package/extra day tag
     · .bk2-pkpop (+ __head / __count)  calendar popover body
     · .bk2-tripsteps               picker step indicator (os-ds .os-hstepper glue)
     · .os-cal__day.is-extra / .is-locked   calendar day states
     · .bk2-pklegend                package vs extra legend
     · .bk2-pk* layout parts        card sections, day body, who's diving
     · .dv-edlabel                  WYSIWYG inline-edit label (pencil)
     · ≤640px: DS mobile wizard panes (dv-wizm-*) — .bk2-mtrip / .bk2-mpane /
       .bk2-mfoot glue + proposed .dv-wizm-cal__day.is-pkg / .is-extra;
       package dates in the os-ds bottom sheet (.os-sheet) — .bk2-msheet glue
   Showcase: /admin/design_system#section-booking-trip
   ============================================================ */
/* ── Size tokens ─────────────────────────────────────────── */
/* --daterail-col comes from os-ds (v1.30.0 tokens).
   --select-min: the narrowest a dive <select> may shrink before its row wraps. */
:root {
  --select-min: 220px;
}
/* ── Colour roles — THE swap point ────────────────────────── */
/* Package days use the accent family (os-cal is-sel, the default ticketband).
   Extra dive days use ONE status triplet, declared once here: swap the three
   values to recolour every extra-day surface (calendar, band, legend). */
.bk2-trip, .bk2-pkpop, .bk2-pkswatch {
  /* Light accent (NOT a status colour — briefing/amber reads as a warning). */
  --bk2-extra: var(--accent-strong);
  --bk2-extra-bg: var(--accent-light);
  --bk2-extra-bd: var(--accent-border);
}
/* ── Wide shell ───────────────────────────────────────────── */
/* The engine layout caps its header / main / footer column (.engine-shell)
   at max-w-3xl (768), which starves the 800 + 348 two-column grid. While the
   Trip step is the visible wizard step, the WHOLE column widens to the
   bk2-2col width (1176 content + the column's own gutter), so the logo bar,
   the "Book your dive" heading + lede and the trip cards share one left edge.
   Keyed off the DOM (not a server flag) because a package picked from the
   add-dive modal swaps the trip shell in client-side. */
.engine-body:has([data-public-wizard-target="step"]:not(.hidden) .bk2-trip) .engine-shell {
  max-width: calc(var(--booking-2col-max) + 2 * var(--space-6));
}
/* ── Package card sections ────────────────────────────────── */
/* Sections inside the package card are separated by spacing, not rules. */
.bk2-pkpad { padding: var(--space-6); }
.bk2-pksec + .bk2-pksec { padding-top: 0; }
.bk2-pkhead { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.bk2-pkhead--tight { margin-bottom: var(--space-3); }
.bk2-pkfieldhint { margin-top: var(--space-2); }
/* The dates trigger is a <button>: keep its value left-aligned like the field it mirrors. */
.bk2-trip .os-datepicker .os-select-field { text-align: left; }
/* Package inclusions strip under the card head */
.bk2-pkincl { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding: var(--space-2) var(--space-6) 0; color: var(--muted); }
.bk2-pkincl > span { display: inline-flex; align-items: center; gap: var(--space-2); }
/* Accent, not --confirmed: an inclusion is a category, not a record status. */
.bk2-pkincl svg { color: var(--accent); flex-shrink: 0; }
/* ── Itinerary: no horizontal rules (muf: separators add cognitive load).
   Days, card heads and the add row are grouped by spacing alone. ── */
.bk2-triphead { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-6) var(--space-6) var(--space-2); }
/* Card padding = --space-6 all round (muf: snapped from the os-card 22px); head flows into body. */
.bk2-trip .bk2-dhead { border-bottom: 0; padding: var(--space-6) var(--space-6) var(--space-2); }
.bk2-trip .bk2-adddate { border-top: 0; padding: var(--space-1) var(--space-6) var(--space-6); }
.bk2-tripdays { padding: 0 var(--space-6) var(--space-4); }
/* Day tag leads the row as its anchor (muf), then the date rail, content, actions. */
.bk2-tripday { display: grid; grid-template-columns: var(--space-16) var(--daterail-col) minmax(0, 1fr) auto; gap: var(--space-4); align-items: start; padding: var(--space-3) 0; }
.bk2-tripday .os-daterail { --os-daterail-top: var(--space-4); }
.bk2-tripday .os-daterail__m { white-space: nowrap; }
.bk2-tripday__side { display: flex; align-items: center; gap: var(--space-2); }
/* Day tag = the .wz-tagbadge pill (shape + type) with a tone modifier only:
   package = solid accent, extra = light accent (same cue as the calendar). */
.wz-tagbadge.bk2-daytag { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.wz-tagbadge.bk2-daytag--extra { background: var(--bk2-extra-bg); border-color: var(--bk2-extra-bd); color: var(--bk2-extra); }
/* Extra day: dive select · "× 2 · $150 each" · total on one line */
.bk2-xday { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.bk2-xday .wz-sel { flex: 1 1 var(--select-min); min-width: 0; }
.bk2-xday__total { margin-left: auto; }
.bk2-dhead__ident .bk2-pktags { justify-content: flex-start; margin-top: var(--space-2); }
/* Day content: package day (dives) · extra day (select line + who's diving) */
.bk2-pkday { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-1) 0; }
.bk2-pkday__kind { display: inline-flex; color: var(--accent); flex-shrink: 0; }
.bk2-pkday__kind--extra { color: var(--bk2-extra); }
.bk2-pkday__main { flex: 1; min-width: 0; }
.bk2-pktags { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); }
.bk2-pkwho { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0 var(--space-1); }
.bk2-addrow.bk2-addrow--lead { margin: 0 0 var(--space-3); flex-wrap: wrap; }
/* ── Calendar popover (.os-pop.os-pop--cal.bk2-pkpop) ─────── */
/* min-content: the months set the width and the head copy wraps to it. */
.os-pop.os-pop--cal.bk2-pkpop {
  width: -moz-min-content;
  width: min-content;
  max-width: calc(100vw - 2 * var(--space-2));
  /* Short viewports: scroll inside the popover so the foot stays reachable. */
  max-height: calc(100vh - 2 * var(--space-2));
  overflow-y: auto;
}
.bk2-pkpop__head { padding: var(--space-1) var(--space-2) var(--space-3); }
.bk2-pkpop__head .os-eyebrow { margin-bottom: var(--space-1); }
.bk2-pkpop .bk2-pklegend { padding: var(--space-3) var(--space-2) 0; }
.bk2-pkpop .os-pop__foot { flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); padding: var(--space-3) var(--space-2) 0; }
/* ── Picker step indicator (.os-hstepper.bk2-tripsteps) ───── */
/* 1 Package days → 2 Extra days (optional). DS stepper as-is; glue only for
   the two-line step-2 label and the locked (aria-disabled) step 2. */
.bk2-tripsteps .os-hstepper__label { text-align: center; }
.bk2-tripsteps__opt { display: block; color: var(--muted-2); }
.bk2-tripsteps.os-hstepper .os-hstepper__item[aria-disabled="true"] { cursor: not-allowed; }
.bk2-tripsteps.os-hstepper .os-hstepper__item[aria-disabled="true"]:hover .os-hstepper__label { color: var(--muted); }
.bk2-tripsteps.os-hstepper .os-hstepper__item[aria-disabled="true"]:hover .os-hstepper__dot { border-color: var(--hairline); }
.bk2-pkpop .bk2-tripsteps { margin: 0 var(--space-2) var(--space-2); }
/* ── Calendar day states (extend os_ds dv_datepicker.css) ─── */
/* Extra dive day: light-accent fill + accent edge (package days = solid accent). */
.bk2-pkpop .os-cal__day.is-extra,
.bk2-pkswatch .os-cal__day.is-extra { background: var(--bk2-extra-bg); border: 1px solid var(--bk2-extra-bd); color: var(--bk2-extra); }
.bk2-pkpop .os-cal__day.is-extra:hover { background: var(--bk2-extra-bg); }
/* Hover must not wash out a picked package day (os-cal hover is generic). */
.bk2-pkpop .os-cal__day.is-sel:hover { background: var(--accent); }
/* Package day in extra mode: shown, not toggleable. */
.os-cal__day.is-locked { cursor: default; }
/* Package mode, all N picked: other days are inert until one is removed. */
.bk2-pkpop .os-cal__day[aria-disabled="true"]:not(.is-sel):not(.is-extra) { color: var(--muted-2); cursor: not-allowed; }
.bk2-pkpop .os-cal__day[aria-disabled="true"]:not(.is-sel):not(.is-extra):hover { background: transparent; }
.bk2-pkpop .os-cal__day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* ── Legend: package (accent) · extra (light accent) ──────────── */
.bk2-pklegend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); color: var(--muted); }
.bk2-pklegend > span { display: inline-flex; align-items: center; gap: var(--space-2); }
.bk2-pklegend i { display: inline-block; width: var(--space-3); height: var(--space-3); border-radius: var(--radius-sm); }
.bk2-pklegend__pkg { background: var(--accent); }
.bk2-pklegend__extra { background: var(--bk2-extra-bg); border: 1px solid var(--bk2-extra-bd); }
/* Trust line under the rail */
.bk2-trust { display: flex; gap: var(--space-2); padding: var(--space-3) var(--space-1) 0; color: var(--muted); }
.bk2-trust svg { flex-shrink: 0; margin-top: 1px; }
/* ── Touch targets (trip scope only — POS keeps its dense sizes) ── */
/* Practical UI / Fitts: ≥48pt. The remove × keeps its 30px look; an invisible
   48px hit area centred on it takes the tap. The add-day button grows to 48. */
.bk2-trip .wz-iconbtn { position: relative; }
.bk2-trip .wz-iconbtn::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: var(--control-h-touch); height: var(--control-h-touch);
  transform: translate(-50%, -50%);
}
.bk2-trip .bk2-adddate-btn { height: var(--control-h-touch); }
/* ── .dv-edlabel — WYSIWYG inline-edit label ──────────────── */
/* Click the text (or pencil) → the text itself becomes contenteditable.
   Enter / blur saves, Esc cancels. Behaviour lives in the host controller. */
.dv-edlabel { display: inline-flex; align-items: center; gap: var(--space-1); cursor: text; border-radius: var(--radius-sm); max-width: 100%; }
.dv-edlabel__t { outline: none; min-width: 2ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dv-edlabel__pen { display: inline-flex; color: var(--muted); opacity: .7; flex-shrink: 0; }
.dv-edlabel:hover .dv-edlabel__pen { color: var(--accent); opacity: 1; }
.dv-edlabel:hover .dv-edlabel__t { -webkit-text-decoration: underline dotted var(--hairline-strong); text-decoration: underline dotted var(--hairline-strong); text-underline-offset: 3px; }
.dv-edlabel__t:focus-visible { box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }
.dv-edlabel.is-editing .dv-edlabel__t { box-shadow: 0 1px 0 0 var(--accent); text-decoration: none; text-overflow: clip; border-radius: 0; }
.dv-edlabel.is-editing .dv-edlabel__pen { display: none; }
/* ── Phone width ── */
@media (max-width: 640px) {
  .bk2-pkday { flex-wrap: wrap; }
}
/* ── Rail summary: money never wraps ──────────────────────── */
/* The DS summary row keeps its label at natural width (summary-card.css), so
   a long package title squeezes the price into a stacked column. On the trip
   rail the label shrinks + wraps instead and the figure stays on one line. */
.bk2-trip .ds-sum-row .main { flex: 1 1 auto; min-width: 0; }
.bk2-trip .ds-sum-row .val { flex: none; white-space: nowrap; }
/* ══════════════════════════════════════════════════════════════
   Mobile Trip step (≤640px) — the DS mobile wizard pane pattern
   (dv-wizm-*, wizard-mobile*.css). Rendered by
   package_trip_renderer#tripMobileHtml only when the
   controller's matchMedia(≤640px) matches; desktop never sees these.
   ══════════════════════════════════════════════════════════════ */
/* ── Proposed dv-wizm-cal day states (token-only) ─────────── */
/* Package day: solid accent. Extra day: light accent (--bk2-extra*).
   Colour only — no dashed outlines, no range spine. */
.bk2-trip .dv-wizm-cal__day.is-pkg { background: var(--accent); color: var(--surface); font-weight: 600; }
.bk2-trip .dv-wizm-cal__day.is-extra { background: var(--bk2-extra-bg); border: 1px solid var(--bk2-extra-bd); color: var(--bk2-extra); }
/* Package day while adding extras: shown, inert. */
.bk2-trip .dv-wizm-cal__day.is-locked { cursor: default; }
/* All N picked: other days are inert until one is removed. */
.bk2-trip .dv-wizm-cal__day[aria-disabled="true"]:not(.is-pkg):not(.is-extra) { color: var(--muted-2); cursor: not-allowed; }
.bk2-trip .dv-wizm-cal__day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bk2-trip .dv-wizm-cal__nav button:disabled { visibility: hidden; }
@media (max-width: 640px) {
  /* The desktop rail summary gives way to the pinned footer (total folded
     into its Next button). Notes + trust line stay. */
  .bk2-trip [data-public-dives-target="orderSummary"] { display: none; }
}
/* Total folded into a primary button: on-accent text, not the figure ink. */
.bk2-trip .os-btn--primary .bk2-mfoot__amt { color: inherit; margin-left: auto; }
/* ── Trip pane body ───────────────────────────────────────── */
/* The page column already insets by the gutter, so section heads sit flush. */
.bk2-mtrip .dv-wizm-sum__hd { padding: var(--space-2) 0 var(--space-3); }
.bk2-mpane__seg { display: flex; }
.bk2-mpane__seg .segmented__option { flex: 1; justify-content: center; min-width: 0; }
.bk2-mpane__seg { margin: var(--space-3) var(--space-4); }
.bk2-mpane__tabdetail { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.bk2-mpane__tabdetail::before { content: "\00b7"; margin: 0 var(--space-1); }
/* Mobile day header: lead with Day N (ink, bold), date follows (muted). */
.bk2-mtrip .dv-wizm-daterow .d.bk2-mdaylbl { display: flex; align-items: baseline; gap: var(--space-2);
  text-transform: none; letter-spacing: 0; font-size: var(--text-sm); color: var(--muted); font-weight: 500; }
.bk2-mtrip .dv-wizm-daterow .d.bk2-mdaylbl b { color: var(--ink); font-weight: 700; }
.bk2-mtrip__addrow { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* Package + extra-days cards: ONE rhythm, no in-card hairlines.
   Between sections --space-4; within a section --space-2/--space-3;
   side padding --space-4. Overrides the shared dv-wizm-* row borders here only. */
.bk2-mtrip .dv-wizm-card { padding-bottom: var(--space-4); }
.bk2-mtrip .dv-wizm-ghead { border-bottom: 0; margin-bottom: var(--space-4); }
.bk2-mtrip__incl { margin: 0; padding: 0 var(--space-4); }
.bk2-mtrip__divers { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 var(--space-4); }
.bk2-mtrip__incl + .bk2-mtrip__divers, .bk2-mtrip__divers + .bk2-mtrip__dates { margin-top: var(--space-4); }
.bk2-mtrip .dv-wizm-diver { padding: 0; border: 0; }
.bk2-mtrip .bk2-mtrip__dates.dv-wizm-srow { padding: 0 var(--space-4); }
.bk2-mtrip .dv-wizm-daterow { padding: 0 var(--space-4); border: 0; margin-top: var(--space-3); }
.bk2-mtrip .bk2-mtrip__dates + .dv-wizm-daterow, .bk2-mtrip .dv-wizm-ghead + .dv-wizm-daterow { margin-top: var(--space-4); }
.bk2-mtrip .dv-wizm-li { padding: 0 var(--space-4); border: 0; margin-top: var(--space-2); }
.bk2-mtrip .dv-wizm-ghead + .dv-wizm-li { margin-top: 0; }
.bk2-mtrip .dv-wizm-cardfoot { border: 0; padding: 0 var(--space-4); margin-top: var(--space-4); }
.bk2-mtrip .dv-wizm-mob-removedive { margin: 0; padding: 0; }
/* Inline name edit inside the DS diver row: the row's <span> meta styling
   must not reach the edit label. */
.bk2-mtrip .dv-wizm-diver__who b :is(.dv-edlabel, .dv-edlabel span) { font-size: inherit; font-weight: inherit; color: inherit; }
.bk2-mtrip .dv-wizm-diver__who b .dv-edlabel__pen { color: var(--muted); }
/* DS rows used as <button>s (a whole-row tap target): reset UA chrome. */
.bk2-mtrip :is(button.dv-wizm-srow, button.dv-wizm-opt-row) {
  width: 100%; text-align: left; font: inherit; color: inherit; background: none; border: 0; cursor: pointer;
}
.bk2-mtrip button.dv-wizm-srow { border-top: 0; align-items: center; }
.bk2-mtrip button.dv-wizm-srow:active,
.bk2-mtrip button.dv-wizm-opt-row:active { background: var(--accent-soft); }
.bk2-mtrip .dv-wizm-opt-row__info { min-width: 0; }
.bk2-mtrip button.bk2-mtrip__ed { background: none; border: 0; padding: 0; font: inherit; }
/* ── Package dates bottom sheet (.os-sheet.bk2-msheet) ────── */
/* os-ds sheet anatomy as-is (scrim, grip, head, scrolling body, sticky
   safe-area foot); glue only for the head row and the body rhythm. */
.bk2-msheet__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.bk2-msheet__ttl { display: flex; flex-direction: column; min-width: 0; }
.bk2-msheet .bk2-tripsteps { margin-top: var(--space-2); }
.bk2-msheet__hint { margin: var(--space-1) 0 var(--space-3); }
/* The sheet body already insets by its own padding. */
.bk2-msheet .dv-wizm-cal { margin: 0; }
.bk2-msheet__legend { padding-top: var(--space-3); }
@media (prefers-reduced-motion: reduce) {
  .bk2-msheet, .bk2-msheet .os-sheet__panel { transition: none; }
}
/* ── Overlay panes ────────────────────────────────────────── */
.bk2-mpane__opts { background: var(--surface); min-height: 100%; }
.bk2-mpane__desc { display: block; margin-top: var(--space-0-5); }
/* The page under an open pane must not scroll. */
html.bk2-mpane-open, html.bk2-mpane-open body { overflow: hidden; }
/* Review ledger row parts (accommodation lines built in JS). */
.booking-wizard .wz-rev-li__icon { justify-content: center; color: var(--accent); }
.booking-wizard .wz-rev-li__body { min-width: 0; }
/* ── Review ledger rows, phone (public funnel only) ─────────────────────
   Stacked, not tabular (muf): the item name gets the full width; qty and
   the line total sit on a second line underneath. Staff POS is untouched. */
@media (max-width: 640px) {
  .booking-wizard .wz-rev-li {
    grid-template-columns: var(--space-5) minmax(0, 1fr) auto;
    grid-template-areas: "icon main main" ". qty amt";
    row-gap: var(--space-1);
    align-items: start;
  }
  .booking-wizard .wz-rev-li > :nth-child(1) { grid-area: icon; padding-top: var(--space-0-5); }
  .booking-wizard .wz-rev-li > :nth-child(2) { grid-area: main; }
  .booking-wizard .wz-rev-li .qty { grid-area: qty; text-align: left; color: var(--muted); }
  .booking-wizard .wz-rev-li .qty::before { content: "Qty "; }
  .booking-wizard .wz-rev-li .amt { grid-area: amt; text-align: right; }
}
/* ── Funnel action bar (os-ds pinned wizard footer, steps/_wizard_foot) ──
   Its buttons sit on the funnel shell's edges: the engine column (48rem,
   1rem / 1.5rem gutters), or the widened two-column shell while the Trip
   step shows (see Wide shell above). */
.booking-wizard { --os-wz-foot-gutter: var(--space-4); --os-wz-foot-max: calc(48rem - 2 * var(--space-6)); }
@media (min-width: 640px) {
  .booking-wizard { --os-wz-foot-gutter: var(--space-6); }
}
.engine-body:has([data-public-wizard-target="step"]:not(.hidden) .bk2-trip) .booking-wizard {
  --os-wz-foot-max: var(--booking-2col-max);
}
/* Package day item names: regular body, only "Day N" is strong. */
.bk2-pkday__main, .bk2-mtrip .dv-wizm-li .info .nm.bk2-mpkitem { font-weight: 400; color: var(--ink); }
/* Card header bars (muf 2026-10-10): package + extra-days heads sit on a
   sky-50 band (muf: lighter than --accent-light/sky-100) so each card reads as a titled block. The band
   follows the card's top corners; the body gets its own top gap. */
.bk2-trip .bk2-dhead,
.bk2-triphead,
.bk2-mtrip .dv-wizm-ghead {
  background: var(--sky-50);
  border-radius: inherit; border-bottom-left-radius: 0; border-bottom-right-radius: 0;
}
.bk2-trip .bk2-dhead, .bk2-triphead { padding-bottom: var(--space-5); margin-bottom: var(--space-4); }
.bk2-mtrip .dv-wizm-ghead { padding-top: var(--space-4); padding-bottom: var(--space-4); }
/* packages-v2 DR-2 / DR-14 — "Where you'll stay" on the Trip step: stacked
   48px radio rows (the diver-row grammar, never a card grid); the picked row
   takes the accent tint. */
.bk2-stay { margin-top: var(--space-6); }
.bk2-stay-rows {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface);
  margin-top: var(--space-3);
}
.bk2-stay-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--space-12);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--hairline);
  cursor: pointer;
}
.bk2-stay-row:first-child { border-top: 0; }
.bk2-stay-row.is-selected,
.bk2-stay-row:has(input:checked) {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-border);
}
.bk2-stay-row input { accent-color: var(--accent); }
.bk2-stay-row__text { display: flex; flex: 1; flex-direction: column; min-width: 0; }
.bk2-stay-row__name { font-weight: 600; color: var(--ink); }
.bk2-stay-caption { padding: var(--space-3) var(--space-1) 0; }
.bk2-stay-gate { color: var(--cancelled); }
/* A house or room closed on the picked days: shown, not pickable. */
.bk2-stay-row.is-closed { cursor: not-allowed; opacity: 0.55; }
.bk2-stay-rooms__label { margin-top: var(--space-4); }
/* ─────────────────────────────────────────────────────────────────────
   stay-tiles.css — "where are you staying", one component everywhere in the
   public funnel (#614 D1/D3, #615). Rendered by lib/stay_tiles_renderer.js.

   Built ON `.os-option-card` (the os-ds selectable row: a card that is the
   control, with a visually-hidden native radio). This file only adds what
   the locked "B+C" design needs on top of it:

     - a check mark at the start of each tile: a filled Lucide circle-check
       when picked (circle --accent, tick --surface), an empty circle when not;
     - the picked HOUSE reads as an accent-soft fill with a 1px inset
       accent-border ring; the picked ROOM inside it as a surface tile with a
       1px --accent ring, so the two levels read apart;
     - the picked house opens a slot that holds its room tiles (3 across from
       640px, full-width rows below), or the room-number / hotel fields;
     - every tile is at least 48px tall (Fitts).

   Candidate for promotion to os-ds as a selectable tile (#552-7), with the
   package builder's guesthouse rows as its second consumer.
   ───────────────────────────────────────────────────────────────────── */
.stay-tiles {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* The house tile holds a head row (the label) and, when picked, its slot. */
.stay-tile.os-option-card {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  min-height: var(--space-12);
  padding: 0;
  cursor: default;
}
.stay-tile.os-option-card + .stay-tile.os-option-card { margin-top: 0; }
.stay-tile__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--space-12);
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
}
/* Picked house: the fill comes from .os-option-card:has(input:checked); the
   ring is an inset 1px accent-border, not the card's accent border. */
.stay-tile.os-option-card:has(> .stay-tile__head input:checked) {
  border-color: transparent;
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-border);
}
.stay-tile.is-disabled .stay-tile__head { cursor: not-allowed; }
.stay-tile.is-disabled,
.stay-room.is-disabled { opacity: .55; }
/* ── The check ─────────────────────────────────────────────────────── */
.stay-tile__check {
  display: flex;
  flex: none;
  color: var(--hairline-strong);
}
.stay-tile__check svg { width: var(--space-5); height: var(--space-5); }
.stay-tile__check svg path { stroke: transparent; }
.stay-tile__head:has(input:checked) .stay-tile__check,
.stay-room:has(input:checked) .stay-room__check {
  color: var(--accent);
}
.stay-tile__head:has(input:checked) .stay-tile__check circle,
.stay-room:has(input:checked) .stay-room__check circle {
  fill: var(--accent);
}
.stay-tile__head:has(input:checked) .stay-tile__check path,
.stay-room:has(input:checked) .stay-room__check path {
  stroke: var(--surface);
}
/* The room's check only shows on the picked room. */
.stay-room__check { display: none; }
.stay-room:has(input:checked) .stay-room__check { display: flex; }
.stay-tile__price {
  margin-left: auto;
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}
.stay-tile__amount { white-space: nowrap; }
/* ── The slot under the picked house ───────────────────────────────── */
.stay-tile__slot {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: 0 var(--space-4) var(--space-4) calc(var(--space-4) + var(--space-5) + var(--space-3));
}
.stay-tile__rooms {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}
.stay-tile__rooms > .stay-room.os-option-card {
  min-height: var(--space-12);
  margin-top: 0;
  background: var(--surface);
}
.stay-room.os-option-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.stay-room.is-disabled { background: var(--surface-alt); cursor: not-allowed; }
.stay-room__price { margin-left: auto; flex: none; }
/* Phone: rooms are full-width rows, name left and price right. From 640px
   they are tiles, three across: name, meta, then the price under them. */
@media (min-width: 640px) {
  .stay-tile__rooms { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stay-tile__rooms > .stay-room.os-option-card {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4);
  }
  .stay-room__price { margin-left: 0; }
  .stay-room .os-option-card__body { padding-right: var(--space-6); }
  .stay-room__check { position: absolute; top: var(--space-3); right: var(--space-3); }
}
/* Field rows ride .os-field-split (os-ds: no stacked-field stagger, controls
   start on one line); this only sets the columns. */
.stay-tile__fields,
.stay-tile__fields.os-field-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
@media (min-width: 640px) {
  .stay-tile__fields.os-field-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .stay-tile__fields--narrow.os-field-split { grid-template-columns: minmax(0, calc(var(--space-12) * 5)); }
}
.stay-tiles__caption { margin-top: var(--space-3); }
/* ── Read-only stay line (package bookings on the Divers step, #617) ── */
.stay-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--space-12);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.stay-line__icon { display: flex; flex: none; color: var(--accent); }
.stay-line__body { display: flex; flex-direction: column; min-width: 0; }
.stay-line__action { margin-left: auto; flex: none; }
/* ── PMS: the shop's own hotel (#618) ──────────────────────────────── */
.stay-pms__dates { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-4); }
.stay-pms__change { padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
.stay-pms__rooms { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }
.stay-pms__total { margin-left: auto; }
/* Phone package card (#616 / #551): Nights above Package dates, then the stay. */
.bk2-mtrip__nights { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); }
.bk2-mtrip__hint { padding: 0 var(--space-4); margin: 0; }
.bk2-mtrip__stay { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); }
/* ─────────────────────────────────────────────────────────────────────
   multi-date-picker.css — the shared multi-date picker (#460), rendered by
   lib/multi_date_picker.js on the os-ds calendar (.os-pop--cal, .os-cal*)
   and, on a phone, the os-ds bottom sheet (.os-sheet).

   Locked look (#460, muf 2026-10-16):
     - consecutive picked days are ONE soft --accent-soft band with solid
       --accent caps at each end; a lone day is a solid --accent dot; the band
       breaks at week-row edges (the renderer ends runs on Mon/Sun);
     - today = a thin ring; past days are muted and not pickable;
     - package mode: package days solid accent, extra days light accent.
   The cell carries the band; its inner span carries the dot / cap.
   ───────────────────────────────────────────────────────────────────── */
.mdp-pop,
.mdp-sheet {
  --mdp-extra: var(--accent-strong);
  --mdp-extra-bg: var(--accent-light);
  --mdp-extra-bd: var(--accent-border);
  --bk2-extra-bg: var(--mdp-extra-bg);
  --bk2-extra-bd: var(--mdp-extra-bd);
}
.mdp-pop.os-pop.os-pop--cal {
  position: fixed;
  z-index: 80;
  margin: 0;
  padding: var(--space-4);
}
.mdp-pop .os-cals { display: flex; gap: var(--space-6); }
.mdp-pop .mdp-month { width: calc(var(--space-10) * 7); }
/* The band needs touching cells: no column gap, a small row gap. */
.mdp-month .os-cal__grid { -moz-column-gap: 0; column-gap: 0; row-gap: var(--space-1); }
.mdp-month .os-cal__nav { display: inline-flex; align-items: center; justify-content: center; }
.mdp-day.os-cal__day {
  aspect-ratio: auto;
  height: var(--space-10);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  font: inherit;
  color: var(--ink);
}
.mdp-day > span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--space-10);
  height: var(--space-10);
  margin: 0 auto;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}
.mdp-day.os-cal__day:not(.is-empty):hover { background: transparent; }
.mdp-day:not(:disabled):hover > span { background: var(--surface-alt); }
.mdp-day:focus-visible { outline: none; }
.mdp-day:focus-visible > span { box-shadow: var(--shadow-focus); }
.mdp-day.is-today > span { box-shadow: inset 0 0 0 1px var(--hairline-strong); }
.mdp-day.is-past { color: var(--muted-2); cursor: not-allowed; }
.mdp-day.is-past > span { font-family: inherit; }
/* Package / plain picks: dot, caps and the band between them. */
.mdp-day.is-picked > span,
.mdp-day.is-picked:hover > span { background: var(--accent); color: var(--surface); font-weight: 600; }
.mdp-day.is-picked.mdp-mid { background: var(--accent-soft); }
.mdp-day.is-picked.mdp-mid > span,
.mdp-day.is-picked.mdp-mid:hover > span { background: transparent; color: var(--accent-strong); }
.mdp-day.is-picked.mdp-start { background: linear-gradient(to right, transparent 50%, var(--accent-soft) 50%); }
.mdp-day.is-picked.mdp-end { background: linear-gradient(to left, transparent 50%, var(--accent-soft) 50%); }
/* Package mode's extra days: the same shapes in the light accent. */
.mdp-day.is-extra > span,
.mdp-day.is-extra:hover > span { background: var(--mdp-extra-bg); color: var(--mdp-extra); box-shadow: inset 0 0 0 1px var(--mdp-extra-bd); }
.mdp-day.is-extra.mdp-mid { background: var(--mdp-extra-bg); }
.mdp-day.is-extra.mdp-mid > span { box-shadow: none; }
.mdp-day.is-extra.mdp-start { background: linear-gradient(to right, transparent 50%, var(--mdp-extra-bg) 50%); }
.mdp-day.is-extra.mdp-end { background: linear-gradient(to left, transparent 50%, var(--mdp-extra-bg) 50%); }
.mdp-head { margin: 0 0 var(--space-3); color: var(--ink); }
.mdp-legend { padding-top: var(--space-3); }
.mdp-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
}
.mdp-summary { flex: 1 1 auto; min-width: 0; color: var(--muted); }
.mdp-summary__count { font-weight: 600; color: var(--ink); }
.mdp-summary .os-figure { color: var(--ink); }
/* Phone: the os-ds bottom sheet, one month, 44px targets, sticky foot. */
.mdp-sheet .os-sheet__head { display: flex; align-items: center; justify-content: space-between; }
.mdp-sheet .os-sheet__body { padding-top: 0; }
.mdp-sheet .mdp-month { width: 100%; }
.mdp-sheet .mdp-day.os-cal__day { height: calc(var(--space-1) * 11); }
.mdp-sheet .mdp-day > span { width: calc(var(--space-1) * 11); height: calc(var(--space-1) * 11); }
.mdp-sheet .os-sheet__foot { display: block; }
.mdp-sheet .mdp-foot { margin: 0; padding: 0; border: 0; flex-wrap: nowrap; }
.mdp-sheet .mdp-summary { flex: 1 1 0; }
.mdp-sheet .mdp-foot > .os-btn { min-height: var(--space-12); }
.mdp-sheet .mdp-foot > .os-btn--primary { padding-inline: var(--space-6); }
html.mdp-lock { overflow: hidden; }
/* ─────────────────────────────────────────────────────────────────────
   guest-funnel.css — layout glue for the guest booking funnel's plain-dives
   Dives step (#607, .gd-*) and Review & send (#608, .rs-*). The pieces are
   os-ds components (.os-card, .os-qty, .os-chip, .os-databand, .ds-sum,
   .os-btn); this file only lays them out to the locked v3 boards.

   The sky date band: an .os-databand in the accent family (the staff view's
   day accent, muf 17 Oct) — scoped here, not a new component.
   ───────────────────────────────────────────────────────────────────── */
.gd-day .os-databand,
.rs-grid .os-databand {
  background: var(--accent-soft);
  border-top: 0;
  border-bottom: 0;
}
.gd-day .os-databand__ico,
.rs-grid .os-databand__ico { color: var(--accent); }
.gd-day .os-databand__x { margin-left: auto; color: var(--accent); }
/* ── Dives step ─────────────────────────────────────────────────────── */
.gd-card.os-card { padding: 0; overflow: hidden; }
.gd-top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4) var(--space-8);
  padding: var(--space-6);
}
.gd-field { display: flex; flex-direction: column; gap: var(--space-2); }
.gd-field--dates { flex: 1 1 calc(var(--space-16) * 4.5); min-width: 0; }
/* Dive dates: one summary field (the landing When field's os-select-field),
   count + compact runs, "Edit" trailing. The value ellipsizes; never wraps. */
.gd-dates.os-select-field { width: 100%; text-align: left; }
.gd-dates__value { flex: 1 1 auto; min-width: 0; display: flex; }
.gd-dates__val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gd-dates__count { font-weight: 600; }
.gd-dates__edit { flex: none; margin-left: auto; padding-left: var(--space-3); color: var(--accent); font-weight: 600; font-size: var(--text-sm); }
/* "Who's diving" chips sit at a touch-friendly height on guest pages. */
.gd-chip.os-chip { height: var(--space-10); padding: 0 var(--space-4); font-size: var(--text-sm); gap: var(--space-2); }
.gd-day__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-4) var(--space-6);
  padding: var(--space-4) var(--space-6);
}
.gd-day__main { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.gd-day__amt { display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
.gd-day__total { font-weight: 600; }
.gd-who { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.gd-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.gd-addons__label { margin: 0; padding: var(--space-2) var(--space-6); }
.gd-lines { border-top: 1px dashed var(--hairline); }
.gd-line {
  display: grid;
  grid-template-columns: var(--space-6) minmax(0, 1fr) auto calc(var(--space-16) + var(--space-4));
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-6);
}
.gd-line + .gd-line { border-top: 1px dashed var(--hairline); }
.gd-line__ico { display: flex; color: var(--accent); }
.gd-line__item { display: flex; flex-direction: column; min-width: 0; }
.gd-line__amt { text-align: right; }
.gd-foot { padding: var(--space-4) var(--space-6) var(--space-6); }
.gd-addday.os-btn {
  width: 100%;
  min-height: var(--space-12);
  justify-content: center;
  border: 1px dashed var(--accent-border);
  color: var(--accent);
}
.gd-addday.os-btn:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
/* "Add add-on" under a day's picked add-ons; the dropdown takes its place. */
.gd-addon-add-row { padding: var(--space-2) var(--space-6) var(--space-4); }
.gd-lines + .gd-addon-add-row { border-top: 1px dashed var(--hairline); }
.gd-addon-add.os-btn { margin-left: calc(-1 * var(--space-3)); }
.gd-addon-pick.os-field-select { max-width: calc(var(--space-16) * 5); }
/* An add-on nested under its dive in the rail: no glyph, indented to the
   dive's text column. */
.ds-sum-row.gd-sum-sub { padding-top: 0; }
.gd-sum-sub .main { padding-left: calc(var(--space-8) + var(--space-3)); }
@media (max-width: 639.98px) {
  .gd-top, .gd-day__body, .gd-foot { padding-left: var(--space-4); padding-right: var(--space-4); }
  .gd-day__body { grid-template-columns: 1fr; }
  .gd-day__amt { flex-direction: row; justify-content: space-between; align-items: baseline; }
  .gd-line { grid-template-columns: var(--space-5) minmax(0, 1fr) auto; padding-left: var(--space-4); padding-right: var(--space-4); }
  .gd-line__amt { grid-column: 2 / -1; text-align: left; }
  .gd-addons__label, .gd-addon-add-row { padding-left: var(--space-4); padding-right: var(--space-4); }
}
/* ── Divers step (#617) ───────────────────────────────────────────── */
/* One os-card per diver: head = badge + title, body = name pair + the
   optional certification accordion. */
.bw-diver-card__title { display: flex; align-items: center; gap: var(--space-3); }
.bw-diver-card .os-card__body { display: flex; flex-direction: column; gap: var(--space-5); }
.bw-diver-card__cert .os-accordion__item { box-shadow: none; }
.bw-diver-card__cert .os-accordion__body { padding-top: var(--space-4); padding-bottom: var(--space-5); }
.bw-field-pair.os-field-split { grid-template-columns: 1fr; gap: var(--space-4) var(--space-5); }
@media (min-width: 640px) {
  .bw-field-pair.os-field-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
/* ── Review & send ─────────────────────────────────────────────────── */
.rs-wrap { display: flex; flex-direction: column; gap: var(--space-5); max-width: calc(var(--space-16) * 11.25); margin: 0 auto; }
.rs-card.os-card { padding: 0; overflow: hidden; }
.rs-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
}
.rs-fact { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.rs-stay {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-top: 1px solid var(--hairline);
}
.rs-stay__body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.rs-stay__change { margin-left: auto; flex: none; }
/* One grid for every line: icon · Item · Qty (fixed, reserved) · Amount. */
.rs-grid { border-top: 1px solid var(--hairline); }
.rs-head,
.rs-row {
  display: grid;
  grid-template-columns: var(--space-6) minmax(0, 1fr) calc(var(--space-16) * 1.9) calc(var(--space-16) * 2.2);
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-6);
}
.rs-head { padding-top: var(--space-4); padding-bottom: var(--space-2); border-bottom: 1px solid var(--accent-border); }
.rs-head > :nth-child(3) { text-align: center; }
.rs-head > :last-child { text-align: right; }
.rs-row + .rs-row { border-top: 1px dashed var(--hairline); }
.rs-row__ico { display: flex; color: var(--accent); }
.rs-row__item { display: flex; flex-direction: column; min-width: 0; }
.rs-row__title { font-weight: 600; }
.rs-row__qty { display: flex; justify-content: center; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.rs-row__amt { text-align: right; }
.rs-row--nested .rs-row__ico { justify-content: flex-end; }
.rs-row--nested .rs-row__item { padding-left: var(--space-4); }
.rs-change { padding: 0 var(--space-6) var(--space-4) calc(var(--space-6) + var(--space-6) + var(--space-3)); }
.rs-section {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6) var(--space-2);
  border-top: 1px solid var(--hairline);
}
.rs-section .os-eyebrow { margin: 0; }
.rs-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6) var(--space-5) calc(var(--space-6) + var(--space-6) + var(--space-3));
  border-top: 1px solid var(--hairline);
  background: var(--surface-alt);
}
.rs-total__label { display: flex; flex-direction: column; gap: var(--space-1); }
.rs-total__amt { font-size: var(--text-2xl); }
.rs-terms { display: flex; flex-direction: column; gap: var(--space-2); }
.rs-terms__check { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; }
.rs-terms__check .os-checkbox { flex: none; margin-top: var(--space-1); }
.rs-terms__link { padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
.rs-send.os-btn { width: 100%; justify-content: center; min-height: var(--space-12); }
.rs-nopay { text-align: center; margin: 0; }
@media (max-width: 639.98px) {
  .rs-facts { padding-left: var(--space-4); padding-right: var(--space-4); }
  .rs-stay { padding-left: var(--space-4); padding-right: var(--space-4); }
  .rs-head, .rs-row { grid-template-columns: var(--space-5) minmax(0, 1fr) auto auto; padding-left: var(--space-4); padding-right: var(--space-4); }
  .rs-change, .rs-total { padding-left: var(--space-4); padding-right: var(--space-4); }
  .rs-section { padding-left: var(--space-4); padding-right: var(--space-4); }
}
/* Wide shell while the plain-dives Dives step shows: the step and its rail
   are the same two-column width as the package trip step (booking-trip.css),
   so the logo bar, heading and cards share one left edge. */
.engine-body:has([data-public-wizard-target="step"]:not(.hidden) .gd-layout) .engine-shell {
  max-width: calc(var(--booking-2col-max) + 2 * var(--space-6));
}
.engine-body:has([data-public-wizard-target="step"]:not(.hidden) .gd-layout) .booking-wizard {
  --os-wz-foot-max: var(--booking-2col-max);
}
/* Landing search bar (#460): the When field shows the picks' summary
   ("18–20 Oct + 24 Oct"), so it takes the room it needs before What. */
@media (min-width: 640px) {
  .pg-search-when { flex: 1.25 1 0; }
}
/* ── Storefront custom-quote request (.qr-*) ────────────────────────────
   One short page (option A): what happens next, then one card holding the
   trip and the contact. Phone: a single column. From md the next-steps sit
   beside the form. Chips light from their checked input (package_builder.css). */
.qr-layout { display: flex; flex-direction: column; gap: var(--space-6); }
.qr-head { display: flex; flex-direction: column; gap: var(--space-2); }
.qr-next { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.qr-next li { display: flex; align-items: flex-start; gap: var(--space-3); }
.qr-next__n {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-6); height: var(--space-6);
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
}
.qr-form { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.qr-card { display: flex; flex-direction: column; gap: var(--space-5); }
.qr-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.qr-card .os-field { margin: 0; }
.qr-dates { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3); margin-top: var(--space-2); }
.qr-dates .os-field { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.qr-dates .os-input { width: 100%; min-width: 0; }
.qr-contact { display: flex; flex-direction: column; gap: var(--space-4); padding-top: var(--space-5); border-top: 1px solid var(--hairline); }
.qr-submit { width: 100%; justify-content: center; }
.qr-nopay { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0; }
.qr-sent { display: flex; flex-direction: column; gap: var(--space-4); }
.qr-sent__eyebrow { display: flex; align-items: center; gap: var(--space-2); }
.qr-sent__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
@media (min-width: 768px) {
  .qr-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--space-8); align-items: start; }
  .qr-head { position: sticky; top: var(--space-6); }
}
/* .dv-card — canonical info-card shell (bug: existed on disk, documented as
   belonging here, but the import line was never added — found by the new
   css_import_gate_test while adding it). Used by 8 views before this fix,
   all rendering unstyled. */
/* ─────────────────────────────────────────────────────────────────────
   DiveOS info card — .dv-card

   Promoted from the Booking Details "Forked card shell" (the page-scoped
   `.bk-detail .card` in account/bookings.css), which the product owner blessed
   as the canonical info-card shell: white surface, 1px hairline, radius-lg,
   NO resting shadow, and an uppercase eyebrow head that flows straight into the
   body (no divider). Reproduced here verbatim as an unscoped component so any
   surface can use it.

   Interaction states (--interactive / --selected) are modeled on the design-
   system handoff's `.dos-card` (Design/templates/rails-handoff): interactive
   cards lift on hover; selected cards take an accent border.

   Spacing: head/body/foot padding is --space-6 on both axes (v1.30.0 —
   the off-grid 22px vertical was reconciled to the 8pt grid).
   Token-driven; @imported from application.css after components/booking-v2.css.
   ───────────────────────────────────────────────────────────────────── */
.os-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding: 0;
}
/* Opt out of the radius clip for cards that host an absolutely-positioned
   popover (e.g. a calendar_input datepicker, .dv-pop z-index:30). The base
   overflow:hidden would clip the popover to the card edge. Only safe on cards
   WITHOUT a nested .dv-table-wrap, which relies on the clip for its radius. */
.os-card--overflow-visible { overflow: visible; }
/* Table-wrapper card (heading head + a flush .dv-table-wrap body via bare:true):
   the card owns the frame, so the nested table-wrap drops its own border/radius
   — no box-in-box. The card's overflow:hidden clips the table to the radius. */
.os-card > .os-table-wrap {
  border: 0;
  border-radius: 0;
  transition: box-shadow var(--t-fast) var(--ease-standard),
              border-color var(--t-fast) var(--ease-standard),
              background-color var(--t-fast) var(--ease-standard);
}
/* v1.36.0 (#493 D2): a table in a card starts at the card head's 24px inset.
   Two compositions ship: the flush wrap (`.os-card > .os-table-wrap`, cells
   at 16px → text at 17) and the wrap that is ALSO the body
   (`.os-card__body.os-table-wrap`: 24px body padding + 16px cell → text at
   41). Both now render the same way: the table runs edge to edge (header band
   and row dividers full-bleed, like the --divided head rule) and the outer
   cells carry the card inset, so column text lines up with the head title.
   Scoped to cards that HAVE an `.os-card__head` (the inset being matched): a
   headless card — e.g. a consumer's root-padded card (HotelOS `hos-card--pad`)
   — keeps the 16px cells. A sortable table's grip column keeps its 12px. */
.os-card:has(> .os-card__head) > .os-table-wrap { padding-left: 0; padding-right: 0; }
.os-card:has(> .os-card__head) > .os-table-wrap > table > * > tr > :is(td, th):first-child { padding-left: var(--space-6); }
.os-card:has(> .os-card__head) > .os-table-wrap > table > * > tr > :is(td, th):last-child { padding-right: var(--space-6); }
.os-card:has(> .os-card__head) > .os-table-wrap:has(tbody [data-sortable-target="handle"]) > table > * > tr > :is(td, th):first-child { padding-left: var(--space-3); }
/* Card-stack (≤639px): rows become their own bordered cards, cells drop their
   padding (!important in table.css). Keep the body's 24px side inset so the
   stacked row cards sit inside the card at the head's inset, as before. */
@media (max-width: 639px) {
  .os-card:has(> .os-card__head) > .os-card__body.os-table-wrap--stack { padding-left: var(--space-6); padding-right: var(--space-6); }
}
/* Head — uppercase eyebrow label (left) + optional actions (right). Top-only
   padding so the head flows into the body with no divider. */
.os-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-6) var(--space-6) 0;
}
.os-card__title {
  display: flex;
  align-items: center;
  gap: 7px;                 /* optical icon gap; off-grid by intent */
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}
.os-card__title i, .os-card__title svg { flex-shrink: 0; color: var(--muted-2); }
/* Display-title head — the 15px General Sans heading (matches
   shared/patterns/_card_title), for cards whose head is a prominent section
   heading rather than the 11px uppercase eyebrow. Pair with --divided when the
   head also carries an action. */
.os-card__title--display {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: none;
  font-family: var(--font-display);
}
.os-card__actions { display: flex; align-items: center; gap: var(--space-2); }
.os-card__body { padding: var(--space-6); }
/* Foot — trailing action row; the mirror of __head. Bottom-only padding so the
   body flows into it with no divider, exactly as the head flows into the body.
   Actions sit right, primary rightmost (--split when a destructive or secondary
   action anchors left). Pair with --divided when the card needs the hairline
   band; the divided rule below mirrors the head's.

   This is the canonical home for a card's actions. `.os-card__actions` is the
   HEAD's action slot (a bare flex row with no padding or divider) — placed
   after the body it renders as a naked row butting the content, which is what
   consumers were hand-rolling card footers to work around. */
.os-card__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: 0 var(--space-6) var(--space-6);
}
.os-card__foot--split { justify-content: space-between; }
/* ── Variants ────────────────────────────────────────────────────────
   --raised  : soft elevation (the bk2-card treatment) for cards that float
               above the canvas rather than sit flush in a column.
   --divided : head sits in its own band with a hairline divider, instead of
               flowing into the body. Use when the head carries an action row
               or the body is dense. */
.os-card--raised { box-shadow: var(--shadow-sm); }
/* --float: the card overlaps a tinted page hero and must lift off it. The ONLY
   other place the overlay tier is used besides the sticky action footer — see
   the two-elevation rule. Deliberately not a third shadow: `--shadow-float` was
   proposed and withdrawn after a pixel diff put it 0.54/765 from this. */
.os-card--float { box-shadow: var(--elevation-overlay); }
.os-card--divided .os-card__head {
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--hairline);
}
.os-card--divided .os-card__foot {
  padding-top: var(--space-4);
  border-top: 1px solid var(--hairline);
}
/* ── Interaction states (from handoff .dos-card) ─────────────────────────
   Apply --interactive only when the whole card is a click target. */
.os-card--interactive { cursor: pointer; }
.os-card--interactive:hover {
  box-shadow: var(--shadow-hover);
  background-color: var(--canvas);
}
.os-card--interactive:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.os-card--selected { border-color: var(--accent); }
/* --danger — a card whose contents are IRREVERSIBLE and consequential to
   someone other than the operator (release the seats and notify every guest;
   delete an account). Distinct from an error (which reports what already went
   wrong) and from a warning: this holds an action about to be taken. Recolours
   the card's OWN border + surface via the cancelled status pair — one signal,
   no extra left stroke, no second knob. The icon stays the callsite's job
   (domain vocabulary: triangle-alert here, ship-off elsewhere) and button
   variants stay the callsite's (`.os-btn--danger` already exists). Pair with
   `.os-card__note` for the blast-radius line the operator is owed. */
.os-card--danger {
  border-color: var(--status-cancelled-border);
  background: var(--status-cancelled-bg);
}
/* Title + note read as one block, so the body sits tighter under the head. */
.os-card--danger .os-card__body { padding-top: var(--space-4); }
/* __note — the muted explanatory line a consequential card owes its operator
   ("both actions release the seats and notify every guest on this manifest").
   Sits between head/body and the actions; small, muted, its own bottom margin.
   Not danger-only, but this is where it earns its keep. */
.os-card__note {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--muted);
}
/* ─── Horizontal stepper (.os-hstepper) ──────────────────────────────────────
   The numbered wizard stepper rendered by shared/patterns/_stepper_horizontal
   (Plan / Team / Gear / Safety / Depart). Each step is a 32px dot over an
   eyebrow label, joined to the next step by a 2px connector.

   STATE IS AN ATTRIBUTE, NOT A CLASS LIST. Every visual below keys on
   `data-state` on `__item` (done | current | pending), so a client-driven
   wizard switches a step by setting ONE attribute — `item.dataset.state` —
   and moving `aria-current="step"`. The number / check-glyph swap is CSS too:
   every item renders both `__num` and `__check`; data-state picks one.

   API
     .os-hstepper               the track (flex row)
     .os-hstepper--navigable    hover affordance on every item (tab-panel mode)
     .os-hstepper__item         one step column ([data-state]; div or button)
     .os-hstepper__dot          32px circle
     .os-hstepper__num          step number (shown unless done)
     .os-hstepper__check        check glyph (shown only when done)
     .os-hstepper__label        eyebrow label (pair with .os-eyebrow)
     .os-hstepper__line         connector to the next step (omitted on last)
   States (on __item[data-state])
     done      accent fill + border, on-accent check; accent connector
     current   accent-light fill, accent border + 3px accent ring, accent number
     pending   surface fill, hairline border, muted number
   Labels: accent on done, accent + bold on current, muted on pending
   (accent on hover when clickable). The pre-1.29 partial asked for this via
   text-accent / font-bold, but .os-eyebrow overrode both so it never
   rendered; 1.29 turns it on deliberately (state selectors outrank
   .os-eyebrow).
   An unknown / missing data-state renders as pending.

   Values are a byte-for-byte port of the partial's former Tailwind utilities
   (w-8 h-8 border-2 gap-1.5 py-2 text-xs font-semibold top-4 h-0.5,
   left-[calc(50%+20px)] right-[calc(-50%+20px)], the 3px 0.12 accent ring),
   so the server-rendered look is unchanged. Token-only. */
.os-hstepper {
  display: flex;
  align-items: flex-start;
  gap: 0;
  padding-block: 8px;
}
.os-hstepper__item {
  position: relative;
  flex: 1 1 0%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: default;
}
button.os-hstepper__item { cursor: pointer; }
.os-hstepper__dot {
  position: relative;
  z-index: 10;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--hairline);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--text-xs);
  line-height: 16px;
  font-weight: 600;
  transition: border-color 150ms var(--ease-standard),
              box-shadow 150ms var(--ease-standard);
}
/* Number ↔ check swap — both always render; state picks one. */
.os-hstepper__num   { display: inline; }
.os-hstepper__check { display: none; line-height: 0; }
.os-hstepper__label {
  color: var(--muted);
  transition: color 150ms var(--ease-standard);
}
.os-hstepper__line {
  position: absolute;
  top: 16px;
  left: calc(50% + 20px);
  right: calc(-50% + 20px);
  height: 2px;
  background: var(--hairline);
}
/* ── done ── */
.os-hstepper__item[data-state="done"] .os-hstepper__dot {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.os-hstepper__item[data-state="done"] .os-hstepper__num   { display: none; }
.os-hstepper__item[data-state="done"] .os-hstepper__check { display: inline-flex; }
.os-hstepper__item[data-state="done"] .os-hstepper__line  { background: var(--accent); }
.os-hstepper__item[data-state="done"] .os-hstepper__label { color: var(--accent); }
/* ── current ── */
.os-hstepper__item[data-state="current"] .os-hstepper__dot {
  background: var(--accent-light);
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}
.os-hstepper__item[data-state="current"] .os-hstepper__label { color: var(--accent); font-weight: 700; }
/* ── hover (navigable track, or any clickable button item) ── */
:is(.os-hstepper--navigable .os-hstepper__item, button.os-hstepper__item):hover .os-hstepper__label {
  color: var(--accent);
}
:is(.os-hstepper--navigable .os-hstepper__item, button.os-hstepper__item):hover:is([data-state="done"]) .os-hstepper__dot {
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}
:is(.os-hstepper--navigable .os-hstepper__item, button.os-hstepper__item):hover:not([data-state="done"], [data-state="current"]) .os-hstepper__dot {
  border-color: var(--accent);
}
/* ─────────────────────────────────────────────────────────────────────
   daterail.css — `.os-daterail`, the sticky day marker for a list grouped
   by day.

   WHY THIS EXISTS. Every operational list in both products is grouped by day
   — a dive schedule, a transfer board, an arrivals list, a statement. The
   grouping was repeatedly expressed as a full-width heading row between
   groups, which costs a whole band of vertical rhythm per day and, worse,
   scrolls away: three screens into a long day the reader no longer knows
   which day they are looking at. The rail moves the marker into a left
   column and makes it STICKY, so the day stays on screen for exactly as long
   as its rows do, and the list itself keeps one uninterrupted rhythm.

   ANATOMY. Big number, then the calendar context under it, then an optional
   summary. `__d` is a display-font numeral at heading size because it is the
   thing the eye returns to; `__m` and `__w` step down in size and colour so
   the block reads top-down without a second glance; `__sum` is MONOSPACE
   because it carries counts and times, and a column of counts that does not
   line up is harder to scan than no column at all.

     div.os-daterail
       div.os-daterail__d    "14"
       div.os-daterail__m    "March 2026"
       div.os-daterail__w    "Saturday"
       div.os-daterail__sum  "6 runs" / "42 pax"          (optional)

   Pair it with a two-column layout (grid or flex) whose second column holds
   the day's rows; the rail carries `align-self: start` so it does not stretch
   to the group's height, which is what makes `position: sticky` bite.

   THE STICKY OFFSET is a component-local custom property with a default, not
   a literal, because the correct value is whatever the CONSUMER's fixed page
   chrome is tall — a workpage header, a filter bar, both. Override it by
   redeclaring --os-daterail-top on the list's own selector — for example a
   value of 116px where a header band and a filter bar stack — not in the
   component.
───────────────────────────────────────────────────────────────────── */
.os-daterail {
  /* Default clears a single sticky header band with a little breathing room.
     Consumers with taller chrome raise it; a consumer with none sets 0. */
  --os-daterail-top: 76px;
  position: sticky;
  top: var(--os-daterail-top);
  /* Without this the rail stretches to the group's full height and sticky has
     nothing to slide within. */
  align-self: start;
}
.os-daterail__d {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.os-daterail__m {
  margin-top: var(--space-0-5);
  font-size: var(--text-sm);
  line-height: var(--leading-sm);
  color: var(--muted);
}
/* Separated from the month by a wider gap than the month is from the number:
   the number + month are one reading ("14 March 2026"), the weekday is a
   second, softer one. */
.os-daterail__w {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  line-height: var(--leading-xs);
  color: var(--muted-2);
}
/* Counts and times. Monospace + a loose line-height so several summary lines
   stack as a scannable column rather than a paragraph. */
.os-daterail__sum {
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  line-height: 1.7;
  color: var(--muted);
}
/* #607 / #608 — the sky date bands on the guest Dives step and Review & send. */
/* ─────────────────────────────────────────────────────────────────────
   databand.css — `.os-databand`, a tinted in-flow group header for a list
   whose groups live INSIDE one container.

   WHY THIS EXISTS, AND HOW IT DIFFERS FROM `.os-daterail`. Both mark the
   groups of a grouped list; they answer different layouts and are not
   interchangeable.

     .os-daterail  — the group marker lives in a LEFT COLUMN beside the rows
                     and sticks while they scroll. Right when the list is the
                     page and the groups are long: a dive schedule, an
                     arrivals board.
     .os-databand  — the group marker is a BAND ACROSS the container, in
                     normal flow. Right when the whole grouped list is itself
                     one document — a sale, a folio, a manifest — where a
                     left column would compete with the document's own left
                     edge, and where each group is a handful of rows rather
                     than a screenful.

   Using the rail in the second case was the observed mistake: the rail's
   sticky column re-indents the content of every group, so a document with a
   header band above it acquires two different left edges and stops reading
   as one object.

   THE TINT IS THE POINT. `--surface-alt` plus a hairline is what makes a
   band read as the LID of a container rather than as a heading floating
   above unrelated rows. A group header that is merely bold text sits at the
   same depth as the rows and the reader has to infer the grouping; a tinted
   band is a boundary they see without reading it.

   ANATOMY. Icon, label, sub-label, then the trailing controls.

     div.os-databand
       span.os-databand__ico      (icon, optional)
       span.os-databand__d        "11 Aug 2026"
       span.os-databand__w        "Tuesday"                (optional)
       span.os-databand__count    "1 seat · $45.00"        (optional)
       button.os-databand__x      (dismiss, optional)

   `__count` is monospace and pill-shaped: it carries figures, and several
   bands stacked in one container turn those figures into a column. It takes
   `margin-left: auto`, so everything after it hugs the right edge.

   `__x` inherits the CANCELLED status colours on hover rather than a generic
   red, because removing a group is destructive and the products already
   teach that colour as "this un-books something".
───────────────────────────────────────────────────────────────────── */
.os-databand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--surface-alt);
  border-bottom: 1px solid var(--hairline);
}
/* Consecutive bands mean an EMPTY group between them. It still needs its own
   top edge or the two bands fuse into one thick stripe. */
.os-databand + .os-databand {
  border-top: 1px solid var(--hairline);
}
.os-databand__ico {
  display: flex;
  flex: none;
  color: var(--muted-2);
}
.os-databand__d {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}
.os-databand__w {
  font-size: var(--text-sm);
  color: var(--muted);
}
.os-databand__count {
  margin-left: auto;
  flex: none;
  padding: var(--space-0-5) var(--space-3);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
/* Also takes margin-left:auto so the dismiss still sits at the right edge
   when the band carries no count. */
.os-databand__x {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  margin-left: auto;
  width: 26px;
  height: 26px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--muted-2);
  cursor: pointer;
  transition: background 120ms var(--ease-standard),
              color 120ms var(--ease-standard);
}
/* When a count is present it has already consumed the auto margin; the
   dismiss then sits directly beside it. */
.os-databand__count + .os-databand__x {
  margin-left: 0;
}
.os-databand__x:hover {
  background: var(--status-cancelled-bg);
  color: var(--status-cancelled-fg);
}
.os-databand__x:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* Canonical info-card component (.dv-card) — promoted from the Booking Details
   forked card shell. Loads AFTER booking-v2.css so the unscoped component wins
   over the page-scoped source. chart-card.css (.dv-chart-card) extends the card
   pattern for Chartkick containers and MUST load after card.css. */
/* callout.css (.dv-callout) — tinted status/info notice panel (status-palette
   tones). desclist.css (.dv-desclist) — key/value <dl> component used inside
   info_card bodies. Both self-scoped, token-only, light-only. */
/* Trip Plan & Run v4 component vocabulary (design-system-gated, shown in
   /admin/design_system). Adopted by the account/dive_trips/* revamp surfaces —
   timeline (stops), avatar (initials disc), chip (dismissible entity), bulkbar
   (multi-select action bar), sheet (mobile bottom sheet / side drawer),
   gear_slot (fitting size row), accordion (collapsible panels). */
/* ═══════════════════════════════════════════════════════════════════════════
   .dv-stops — vertical stops timeline (Board → numbered dives → Return).

   A first-class DiveOS component: a time gutter, a connector rail with nodes,
   and a card lane. Bookend rows (Board / Return) are quiet; stop rows carry a
   numbered accent node, an inline-editable title, a drag handle, and a delete
   control. GapZones between rows reveal an "Add stop" affordance on hover and
   expand into an inline site+time form when activated.

   Ported from the v4 Trip-Run design (lifecycle.css .lc-vt-* + trip-run-v4.css).
   Tokens only. Specimen lives in /admin/design_system → Timeline.
   ═══════════════════════════════════════════════════════════════════════════ */
:is(.dv-stops, .os-stops) { position: relative; }
:is(.dv-stops__row, .os-stops__row) {
  display: grid;
  grid-template-columns: 62px 36px minmax(0, 1fr);
  align-items: start;
}
/* Time gutter */
:is(.dv-stops__time, .os-stops__time) { text-align: right; padding: 16px 14px 0 0; }
:is(.dv-stops__hh, .os-stops__hh) {
  font-family: var(--font-mono);
  font-size: var(--text-md); font-weight: 500; color: var(--ink);
  letter-spacing: -0.01em;
}
:is(.dv-stops__hh--editing, .os-stops__hh--editing) { color: var(--muted-2); letter-spacing: 0.06em; }
:is(.dv-stops__lbl, .os-stops__lbl) {
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted-2); margin-top: 4px;
}
/* Rail + nodes */
:is(.dv-stops__rail, .os-stops__rail) {
  display: flex; flex-direction: column; align-items: center;
  align-self: stretch;
}
:is(.dv-stops__node, .os-stops__node) {
  width: 30px; height: 30px; min-height: 30px; border-radius: 50%;
  border: 2px solid var(--hairline); background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); flex-shrink: 0; flex-grow: 0; margin-top: 14px;
  font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600;
  box-sizing: border-box;
}
:is(.dv-stops__node, .os-stops__node) svg { flex-shrink: 0; }
:is(.dv-stops__rail, .os-stops__rail) > :is(.dv-stops__node, .os-stops__node) { flex: 0 0 30px; height: 30px; max-height: 30px; }
:is(.dv-stops__node--accent, .os-stops__node--accent) {
  border-color: var(--accent); color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
:is(.dv-stops__node--num, .os-stops__node--num) {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
:is(.dv-stops__line, .os-stops__line) {
  flex: 1; width: 2px; background: var(--hairline);
  margin: 4px 0; min-height: 18px;
}
:is(.dv-stops__row, .os-stops__row):last-child :is(.dv-stops__line, .os-stops__line) { display: none; }
/* Cards */
:is(.dv-stops__card, .os-stops__card) {
  margin: 6px 0 16px 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: 14px 16px;
  transition: border-color .12s, box-shadow .12s;
}
:is(.dv-stops__card--bookend, .os-stops__card--bookend) {
  background: var(--surface-alt);
  box-shadow: none; cursor: default;
  margin: 4px 0 6px 12px;
}
:is(.dv-stops__card--stop, .os-stops__card--stop) {
  display: flex; align-items: center; gap: 10px;
  margin: 3px 0 3px 12px;
}
/* Title lane. The eyebrow ("DIVE N · time") was removed as redundant — the
   number + time already live in the gutter — which frees the row to a single
   line with the actions inline. */
:is(.dv-stops__card-main, .os-stops__card-main) { flex: 1; min-width: 0; }
/* Editing state gets extra padding so the inline form breathes. */
:is(.dv-stops__card--stop, .os-stops__card--stop).is-editing { align-items: flex-start; padding: 16px 18px; }
:is(.dv-stops__card--stop, .os-stops__card--stop):hover { border-color: var(--accent-border); }
:is(.dv-stops__card--stop, .os-stops__card--stop).is-editing { border-color: var(--accent-border); box-shadow: 0 0 0 3px var(--accent-soft); }
:is(.dv-stops__eye, .os-stops__eye) {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--text-2xs); letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--muted-2);
}
:is(.dv-stops__ttl, .os-stops__ttl) {
  font-family: var(--font-display);
  font-weight: 600; font-size: var(--text-md); letter-spacing: -0.01em;
  color: var(--ink); margin-top: 5px;
}
:is(.dv-stops__card--bookend, .os-stops__card--bookend) :is(.dv-stops__ttl, .os-stops__ttl) { font-size: var(--text-sm); color: var(--muted); }
:is(.dv-stops__ttl--edit, .os-stops__ttl--edit) { cursor: pointer; }
:is(.dv-stops__ttl--edit, .os-stops__ttl--edit):hover { color: var(--accent); }
/* ── Read-only Plan (inside the info_card) — even stop rhythm ─────────────────
   ROOT CAUSE: the timeline never sets an explicit inter-stop gap. Each row is a
   grid with `align-items: start`; the rail column (node + flex-1 line) stretches
   to the row height, and the row height is max(card-height, rail-intrinsic). So
   the visible gap = row-height − card-height = rail slack, which DEPENDS ON CARD
   CONTENT: a card with a "Max depth" meta line (~84px) exceeds the rail's intrinsic
   height (~70px) → ~6px gap, while a single-line card (~57px) is shorter than the
   rail → ~17px gap. The editable timeline hides this behind fixed-height hover
   gap-zones between every stop; the read-only timeline has none, so the variance
   shows as uneven spacing.
   ROOT FIX: make the gap an EXPLICIT value, not emergent rail slack. An 8px
   top/bottom margin sets the gap; `min-height: 0` on the rail line stops the rail
   from ever out-talling the card, so the card always drives the row and the gap is
   EXACTLY the margins (16px) no matter the card's content. Content-independent, no
   magic card-height constant. Scoped to `.os-card` (info_card) so the editable
   timeline — which already spaces itself via the gap-zones — is untouched. */
.os-card :is(.dv-stops__card--stop, .os-stops__card--stop) {
  margin-top: 8px;
  margin-bottom: 8px;
}
.os-card :is(.dv-stops__line, .os-stops__line) { min-height: 0; }
/* Desktop hover affordance: the stop name reads as an editable field before
   the user clicks. Transparent border colors on hover (no layout shift) via a
   negative-margin inset so the padded box hugs the text. */
@media (hover: hover) and (pointer: fine) {
  :is(.dv-stops__ttl--field, .os-stops__ttl--field) {
    display: inline-block;
    margin: -3px -8px; padding: 3px 8px;
    border: 1px solid transparent; border-radius: var(--radius-sm);
    transition: border-color .12s, background .12s;
  }
  :is(.dv-stops__ttl--field, .os-stops__ttl--field):hover {
    border-color: var(--hairline-strong);
    background: var(--surface);
    cursor: text;
  }
}
:is(.dv-stops__meta, .os-stops__meta) {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); margin-top: 7px;
}
:is(.dv-stops__grip, .os-stops__grip) {
  color: var(--muted-2); flex-shrink: 0; cursor: grab; margin-top: 3px;
}
/* Row actions — edit (signifier) before delete */
:is(.dv-stops__acts, .os-stops__acts) { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
:is(.dv-stops__act, .os-stops__act) {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 8px;
  border: 1px solid var(--hairline); background: var(--surface);
  color: var(--muted-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .12s, background .12s, color .12s;
}
:is(.dv-stops__act, .os-stops__act):hover {
  border-color: var(--accent-border); background: var(--accent-soft); color: var(--accent);
}
:is(.dv-stops__act--del, .os-stops__act--del):hover {
  border-color: var(--cancelled-border); background: var(--cancelled-bg); color: var(--cancelled);
}
/* Board time-slot control (prototype trip time slot) */
:is(.dv-stops__slot, .os-stops__slot) { margin-top: 12px; max-width: 240px; }
/* Read-only summary: quiet time slot + pencil; the select is revealed on click. */
:is(.dv-stops__slot--ro, .os-stops__slot--ro) { display: flex; align-items: center; gap: 8px; }
:is(.dv-stops__slot-sum, .os-stops__slot-sum) {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--muted); letter-spacing: 0.02em;
}
:is(.dv-stops__slot-sum, .os-stops__slot-sum) svg { color: var(--muted-2); }
:is(.dv-stops__slot-edit, .os-stops__slot-edit) { width: 26px; height: 26px; }
:is(.dv-stops__slot-edit-row, .os-stops__slot-edit-row) { display: flex; align-items: flex-end; gap: 8px; }
:is(.dv-stops__slot-edit-row, .os-stops__slot-edit-row) :is(.dv-select--inline, .os-select--inline) { flex: 1; }
/* Inline edit form — roomy, not cramped (prototype-review: "collapsed too
   much, should be plenty of space"). */
:is(.dv-stops__edit, .os-stops__edit) { margin-top: 12px; }
:is(.dv-stops__edit-fields, .os-stops__edit-fields) { display: flex; gap: 14px; align-items: flex-end; }
:is(.dv-stops__edit-actions, .os-stops__edit-actions) { display: flex; gap: 8px; margin-top: 14px; }
/* Shared inline stop form (add === edit) — ONE horizontal row: the site select
   grows to fill the container width; time + Save/Cancel sit inline beside it.
   Supersedes the old stacked .os-stops__edit-fields + .os-stops__edit-actions
   two-row layout (kept above for any legacy callers). */
/* One row when it fits: the site select is the flexible item that shrinks
   first (min-width:0); the row wraps only on narrow containers (below). */
:is(.dv-stops__form, .os-stops__form) { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; container-type: inline-size; }
:is(.dv-stops__form, .os-stops__form) > :is(.dv-select--inline, .os-select--inline) { flex: 1 1 120px; min-width: 0; }
/* Narrow (phone): one row can't hold site + time picker + buttons. Without
   this the site select collapsed to 0px while its invisible native <select>
   still sat over the hour box, so taps opened the site picker. Give the site
   its own full row; time + Save/Cancel follow (and wrap if they must). */
@container (max-width: 560px) {
  :is(.dv-stops__form, .os-stops__form) > :is(.dv-select--inline, .os-select--inline) { flex-basis: 100%; }
}
/* Equal height: the os-ds dv-select trigger (.os-select-field) is 46px, so the
   time input and Save/Cancel buttons match it — one control height across the row. */
:is(.dv-stops__form, .os-stops__form) > :is(.dv-btn, .os-btn) { flex: 0 0 auto; min-height: 46px; }
/* .os-stops__card--stop is display:flex, so the edit form (a flex item beside
   the hidden display row) must grow to fill the card — otherwise it collapses
   to content width with dead space to the right. The endwrap/gap forms are
   block children and already fill their cell. */
:is(.dv-stops__card--stop, .os-stops__card--stop) > :is(.dv-stops__form, .os-stops__form) { flex: 1 1 auto; min-width: 0; }
:is(.dv-stops__card--stop, .os-stops__card--stop) :is(.dv-stops__form, .os-stops__form),
:is(.dv-stops__endwrap, .os-stops__endwrap) :is(.dv-stops__form, .os-stops__form),
:is(.dv-stops__gap, .os-stops__gap) :is(.dv-stops__form, .os-stops__form) { margin-top: 12px; }
/* Empty stop-shell: the ADD form (end-cap + gap-insert), which is NOT inside a
   stop card, renders as a bordered inset card matching a real stop card / the
   collapsed .os-stops__add pill — so the expanded add row aligns left + right
   with the stops instead of breaking out full-bleed and skewing the column.
   Styled on the form itself (display:none until revealed) so no empty box shows
   while collapsed. Left margin + padding mirror .os-stops__card exactly. */
:is(.dv-stops__endwrap, .os-stops__endwrap) :is(.dv-stops__form, .os-stops__form),
:is(.dv-stops__gap, .os-stops__gap) :is(.dv-stops__form, .os-stops__form) {
  margin-left: 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: 14px 16px;
}
:is(.dv-stops__field-label, .os-stops__field-label) {
  display: block; font-size: var(--text-2xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted);
  margin-bottom: 4px;
}
/* The stop time is the os-ds fields--time picker; keep it whole in the row. */
:is(.dv-stops__form, .os-stops__form) .os-time-field { flex-shrink: 0; }
/* ── Gap zone (hover-to-insert) ───────────────────────────────────────────── */
:is(.dv-stops__gap, .os-stops__gap) {
  display: grid;
  grid-template-columns: 62px 36px minmax(0, 1fr);
  align-items: center;
  /* FIXED height + clip so the collapsed reveal (the opacity:0 "Add stop" pill,
     ~26px of natural height) can't inflate the gap — that inflation was spreading
     the stops apart and making the vertical rhythm look uneven. Hover/active
     expand it. */
  height: 10px;
  overflow: hidden;
  transition: height .14s;
}
:is(.dv-stops__gap, .os-stops__gap).is-hover { height: 46px; }
:is(.dv-stops__gap, .os-stops__gap).is-active { height: auto; overflow: visible; }
:is(.dv-stops__gap, .os-stops__gap) :is(.dv-stops__rail, .os-stops__rail) { align-self: stretch; }
:is(.dv-stops__gap, .os-stops__gap) :is(.dv-stops__line, .os-stops__line) {
  flex: 1; width: 2px; min-height: 0; margin: 0;
  background: var(--hairline); transition: background .14s;
}
:is(.dv-stops__gap, .os-stops__gap).is-hover :is(.dv-stops__line, .os-stops__line) { background: var(--accent-border); }
:is(.dv-stops__reveal, .os-stops__reveal) {
  display: flex; align-items: center; gap: 10px;
  padding: 0 4px 0 12px;
  opacity: 0; transition: opacity .14s;
}
:is(.dv-stops__gap, .os-stops__gap).is-hover :is(.dv-stops__reveal, .os-stops__reveal) { opacity: 1; transition-delay: .03s; }
:is(.dv-stops__reveal, .os-stops__reveal) :is(.rule, .os-rule) { flex: 1; height: 0; border-top: 1px solid var(--hairline); }
:is(.dv-stops__insert, .os-stops__insert) {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 11px; border-radius: var(--radius-pill);
  border: 1px solid var(--accent-border); background: var(--surface);
  color: var(--accent); font-size: var(--text-xs); font-weight: 600; cursor: pointer;
  transition: background .12s;
}
:is(.dv-stops__insert, .os-stops__insert):hover { background: var(--accent-soft); }
:is(.dv-stops__gap-form, .os-stops__gap-form) {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 0 8px 12px;
}
/* ── Add-stop placeholder / empty state ───────────────────────────────────── */
:is(.dv-stops__add, .os-stops__add) {
  margin: 6px 0 10px 12px; padding: 13px 18px;
  border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  background: var(--surface); cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  transition: border-color .12s, background .12s;
  /* Full width minus its 12px left inset: a bare 100% + the margin overhung
     the stop cards above it by 12px. */
  width: calc(100% - var(--space-3)); text-align: left;
}
:is(.dv-stops__add, .os-stops__add):hover { border-color: var(--accent-border); background: var(--surface-alt); }
:is(.dv-stops__add--empty, .os-stops__add--empty) { padding: 20px 22px; }
:is(.dv-stops__add, .os-stops__add) :is(.ic, .os-ic) { display: flex; align-items: center; color: var(--muted-2); flex-shrink: 0; }
:is(.dv-stops__add, .os-stops__add):hover :is(.ic, .os-ic) { color: var(--accent); }
:is(.dv-stops__add-txt, .os-stops__add-txt) { display: flex; flex-direction: column; min-width: 0; }
:is(.dv-stops__add-t, .os-stops__add-t) {
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-sm); color: var(--ink);
}
:is(.dv-stops__add-s, .os-stops__add-s) { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
:is(.dv-stops__endcap, .os-stops__endcap) { display: none; }
:is(.dv-stops__endcap, .os-stops__endcap).is-active { display: block; }
/* Inline visible select (edit/insert forms). The DS .dv-select hides its native
   element behind a JS overlay; inside the timeline we want a plain, always-
   visible styled native <select> with a chevron affordance. */
:is(.dv-select--inline, .os-select--inline) { position: relative; display: block; }
:is(.dv-select--inline, .os-select--inline) > select {
  width: 100%;
  min-height: 46px;
  padding: 8px 32px 8px 12px;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  -moz-appearance: none;
       appearance: none; -webkit-appearance: none;
  /* Kill the @tailwindcss/forms select chevron (a hardcoded gray SVG painted on
     every <select>) so it doesn't double up with our Lucide .os-select__chevron.
     `appearance:none` removes the NATIVE arrow but not this background image. */
  background-image: none;
  cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
:is(.dv-select--inline, .os-select--inline) > select:hover { border-color: var(--accent); }
:is(.dv-select--inline, .os-select--inline) > select:focus-visible {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); outline: none;
}
:is(.dv-select--inline, .os-select--inline) :is(.dv-select__chevron, .os-select__chevron) {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--muted); display: flex;
}
/* ── Accessible reorder: drag + up/down buttons + Alt+↑/↓ ──────────────────── */
/* Keyboard-focusable stop row: focus-visible ring so the Alt+↑/↓ target reads. */
:is(.dv-stops__row, .os-stops__row)[draggable] { outline: none; }
:is(.dv-stops__row, .os-stops__row)[draggable]:focus-visible :is(.dv-stops__card--stop, .os-stops__card--stop) {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Drag ghost source — dim while dragging (mirrors dives_reorder opacity-50). */
:is(.dv-stops__row, .os-stops__row).is-dragging { opacity: 0.5; }
/* Moved-row pulse (signature motion, carried from dashboard's reorder pulse). */
:is(.dv-stops__row--pulse, .os-stops__row--pulse) :is(.dv-stops__card--stop, .os-stops__card--stop) {
  animation: dashboard-pulse 200ms cubic-bezier(0, 0, 0.2, 1);
}
/* Up/down reorder buttons. Hover-revealed on fine pointers to keep the row
   quiet; always visible + larger on coarse pointers (the boat, no-drag path). */
:is(.dv-stops__act--move, .os-stops__act--move) svg { flex-shrink: 0; }
:is(.dv-stops__act, .os-stops__act)[disabled] { opacity: 0.35; cursor: default; pointer-events: none; }
@media (hover: hover) and (pointer: fine) {
  :is(.dv-stops__act--move, .os-stops__act--move) { opacity: 0; transition: opacity .12s; }
  :is(.dv-stops__card--stop, .os-stops__card--stop):hover :is(.dv-stops__act--move, .os-stops__act--move), :is(.dv-stops__row, .os-stops__row)[draggable]:focus-visible :is(.dv-stops__act--move, .os-stops__act--move), :is(.dv-stops__act--move, .os-stops__act--move):focus-visible { opacity: 1; }
}
@media (pointer: coarse) {
  :is(.dv-stops__act--move, .os-stops__act--move) { width: 44px; height: 44px; }
}
@media (prefers-reduced-motion: reduce) {
  :is(.dv-stops__row--pulse, .os-stops__row--pulse) :is(.dv-stops__card--stop, .os-stops__card--stop) { animation: none; }
}
/* Off-screen live region for reorder announcements. */
:is(.dv-visually-hidden, .os-visually-hidden) {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* No-JS hover reveal for the gap (server-rendered Plan uses pure :hover where
   the prototype toggled .is-hover from Stimulus). Same visual states. */
:is(.dv-stops__gap, .os-stops__gap):hover { min-height: 46px; }
:is(.dv-stops__gap, .os-stops__gap):hover :is(.dv-stops__line, .os-stops__line) { background: var(--accent-border); }
:is(.dv-stops__gap, .os-stops__gap):hover :is(.dv-stops__reveal, .os-stops__reveal), :is(.dv-stops__gap, .os-stops__gap):focus-within :is(.dv-stops__reveal, .os-stops__reveal) { opacity: 1; transition-delay: .03s; }
:is(.dv-stops__gap, .os-stops__gap):focus-within { min-height: 46px; }
/* Touch screens have no hover, so the insert-between pill was unreachable on a
   phone or tablet. Where the primary pointer can't hover (or is coarse — a
   touchscreen laptop), keep each gap open
   with the pill showing, at a 36px tap height in a 48px row. Desktop keeps the
   hover reveal. */
@media (hover: none), (pointer: coarse) {
  :is(.dv-stops__gap, .os-stops__gap) { height: auto; min-height: var(--space-12); }
  :is(.dv-stops__gap, .os-stops__gap) :is(.dv-stops__reveal, .os-stops__reveal) { opacity: 1; }
  :is(.dv-stops__insert, .os-stops__insert) { min-height: var(--control-h-base); padding-inline: var(--space-4); }
}
/* ── Phone stop sheet (muf's pick for !656) ──────────────────────────────
   On a phone the inline stop row was unusable: the card's four icon buttons
   squeezed the site name out, and the open form crammed site + time + buttons
   into the timeline column. ≤640: the card keeps the site name and a 44px edit
   button (move / remove move into the sheet); an open stop form — edit, gap
   insert or end add — becomes a bottom sheet (os-ds sheet anatomy: grip,
   title, labelled full-width fields, Save / Cancel pinned at the foot) over a
   dimmed page. Wider panes keep the inline row; .os-stops__sheet-only parts
   show only here. */
.os-stops__sheet-only { display: none; }
@media (max-width: 640px) {
  .os-stops__card--stop :is(.os-stops__act--move, .os-stops__act--del, .os-stops__grip) { display: none; }
  .os-stops__card--stop .os-stops__act { width: 44px; height: 44px; }
  .os-stops__card--stop .os-stops__card-main { min-width: 0; }
  /* Long site names wrap to two lines instead of truncating at one. */
  .os-stops__card--stop .os-stops__ttl {
    white-space: normal;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
  }

  .os-stops__form:not([hidden]) {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 70;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2) var(--space-3);
    max-height: 90svh;
    overflow-y: auto;
    margin: 0;
    padding: var(--space-2) var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom));
    border: 0;
    background: var(--surface);
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    box-shadow: 0 0 0 100vmax rgba(17, 24, 39, .45); /* the scrim */
  }
  /* A shadow isn't hit-testable, so a transparent full-screen layer catches
     taps outside the sheet: they close it (dive_stops_controller) instead of
     reaching the page underneath. */
  .os-stops__form:not([hidden])::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
  }
  .os-stops__form:not([hidden]) > * { grid-column: 1 / -1; }
  .os-stops__form:not([hidden]) .os-stops__sheet-only { display: block; }
  .os-stops__form:not([hidden]) > .os-stops__sheet-acts { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
  .os-stops__sheet-acts > .os-btn--secondary { flex: 1 1 0; min-height: var(--control-h-touch); justify-content: center; }
  .os-stops__sheet-remove { color: var(--cancelled); min-height: var(--control-h-touch); }
  .os-stops__sheet-head .os-sheet__grip { margin: 0 auto var(--space-2); }
  .os-stops__sheet-head { padding-bottom: var(--space-2); border-bottom: 1px solid var(--hairline); margin-bottom: var(--space-1); }
  .os-stops__form:not([hidden]) > .os-btn { grid-column: auto; min-height: var(--space-12); justify-content: center; margin-top: var(--space-2); }
  .os-stops__form:not([hidden]) > .os-btn[type="submit"] { order: 2; }
  .os-stops__form:not([hidden]) > .os-btn[type="button"] { order: 1; }
}
/* ─────────────────────────────────────────────────────────────────────
   os-meter — a slim horizontal coverage/progress bar.

   Canonical component for "X% of a module's cases are covered" (QA landing).
   A subtle surface track with an accent fill whose width is DATA-DRIVEN via
   the `--os-meter-fill` custom property (set inline at the call site, 0–100%),
   so no literal `style="width: …"` is ever hand-specced.

   Anatomy:
     .os-meter          → the track (fixed height, rounded, clips the fill)
     .os-meter__fill    → the accent fill; width = var(--os-meter-fill)

   Usage:
     <div class="os-meter" aria-label="42% covered">
       <div class="os-meter__fill" style="--os-meter-fill: 42%"></div>
     </div>
   ───────────────────────────────────────────────────────────────────── */
.os-meter {
  --os-meter-fill: 0%;
  height: 7px;
  width: 100%;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  /* Faint gauge outline so an EMPTY track reads as "measured, 0%" rather than
     "no data / not rendered". The minimum state carries meaning. */
  box-shadow: inset 0 0 0 1px var(--hairline);
  overflow: hidden;
}
.os-meter__fill {
  display: block;
  height: 100%;
  width: var(--os-meter-fill);
  border-radius: var(--radius-pill);
  background: var(--accent);
  transition: width 0.25s cubic-bezier(0.32, 0.72, 0, 1);
}
/* ── Meter card — a coverage-FIRST nav card (QA module grid).
   Coverage % is the hero figure; the module name is a readable title; the
   meter + covered/total fraction are supporting detail. Built on the boxed
   `.os-stat-card--interactive` shell (whole-card link), overriding only the
   internal rhythm so the KPI stat-card's "tiny label / big value" order is
   inverted into "title → hero % → gauge". */
.os-meter-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.os-meter-card__name {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}
.os-meter-card__code {
  flex-shrink: 0;
}
.os-meter-card__metric {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}
/* Neutralise the stat-card value/sub top margins — the flex gap owns spacing. */
.os-meter-card__metric .os-stat-card-value,
.os-meter-card__metric .os-stat-card-sub {
  margin-top: 0;
}
/* run_logsheet.css — person-first Return>Log-dives matrix (sticky name/sign
   columns, two-tier dive-group header), sticky close-bar, and the drawer
   sign/switch/field form. PROMOTION CANDIDATE → os-ds. Token-clean. */
/* PROMOTION CANDIDATE → os-ds: person-first logsheet matrix, close-bar, drawer sign/switch. App-owned until coordinated with the os-ds gem session (v1.3.0 pinned). */
/* ══════════════ side-panel DRAWER chrome ══════════════
   Fixed scrim + right-anchored panel that slides in on `.is-open` (toggled by
   logsheet_controller). Named .dv-drawer to avoid the os-ds `.side-drawer`
   scroll-container utility; the inner body is the os-ds `.side-panel`. Ported
   from the by-person.html mockup, tokenised. */
.dv-drawer {
  position: fixed;
  inset: 0;
  z-index: 80;
  pointer-events: none;
}
/* A dv-select inside this drawer (e.g. the Guide field) moves its menu onto
   <body>; os-ds (>= v1.36.1) stacks that relocated menu at 90, above this
   drawer's 80. Keep this drawer below 90 or its selects open behind it. */
.dv-drawer__scrim {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--ink) 45%, transparent);
  opacity: 0;
  transition: opacity 0.2s var(--ease-standard);
}
.dv-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: min(520px, 94%);
  background: var(--surface);
  box-shadow: var(--shadow-panel);
  transform: translateX(100%);
  transition: transform 0.24s var(--ease-out-quart);
  display: flex;
  flex-direction: column;
}
/* the lazy turbo-frame + its .side-panel body fill the panel height */
.dv-drawer__panel > turbo-frame,
.dv-drawer__panel .side-panel {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  height: 100%;
}
/* The drawer body scrolls; header + action bar stay pinned. The per-diver form
   wraps the body + action-bar, so it too must be a flex column that fills, or
   the body can't grow/scroll and the sign-off section clips off the bottom. */
.dv-drawer .side-panel > form {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.dv-drawer .side-panel__header,
.dv-drawer .side-panel__action-bar { flex: 0 0 auto; }
.dv-drawer .side-panel__body { flex: 1; min-height: 0; overflow-y: auto; }
.dv-drawer.is-open {
  pointer-events: auto;
}
.dv-drawer.is-open .dv-drawer__scrim {
  opacity: 1;
}
.dv-drawer.is-open .dv-drawer__panel {
  transform: translateX(0);
}
/* ══════════════ RETURN panel — width driven by dive-stop count ══════════════
   The whole panel (callout + matrix card + close-bar) is exactly as wide as the
   matrix needs for N dive stops — name column + N dive-groups + sign column —
   so the chrome hugs the table instead of a narrow card floating in a full-width
   bar. Capped at the available width; past ~3 stops it exceeds most screens and
   the matrix card scrolls horizontally. The column widths live here as the
   single source of truth (kept in sync with the cell rules below). */
.dv-return-panel {
  --dv-col-name: 248px;
  --dv-col-group: 310px; /* M 54 + Bar 54 + O₂ 54 + In/Out 148 */
  --dv-col-sign: 108px;
  --dv-stops: 2;
  width: calc(var(--dv-col-name) + var(--dv-col-group) * var(--dv-stops) + var(--dv-col-sign));
  max-width: 100%;
  margin-inline: auto; /* centre the panel in the available width */
}
.dv-return-panel[data-stops="1"] { --dv-stops: 1; }
.dv-return-panel[data-stops="2"] { --dv-stops: 2; }
.dv-return-panel[data-stops="3"] { --dv-stops: 3; }
.dv-return-panel[data-stops="4"] { --dv-stops: 4; }
.dv-return-panel[data-stops="5"] { --dv-stops: 5; }
.dv-return-panel[data-stops="6"] { --dv-stops: 6; }
/* Chrome fills the panel; only the matrix card drives/absorbs overflow. */
.dv-return-panel > .os-tabnav,
.dv-return-panel .os-callout,
.dv-return-panel .dv-close-bar { width: 100%; box-sizing: border-box; }
/* ══════════════ person-first LOGSHEET MATRIX ══════════════
   Sticky diver name (left) + sign (right) columns; the dive-group numeric
   columns scroll horizontally between them. Ported verbatim in structure from
   the by-person.html mockup, renamed to the .dv-* vocabulary and re-tokenised
   (every literal palette value → its semantic token; scroll-shadow gradients
   use color-mix over var(--ink) instead of a raw rgba). */
.dv-logsheet-wrap {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow-x: auto;
  overflow-y: visible;
  -webkit-overflow-scrolling: touch;
  /* Dynamic width: the bordered card hugs the table's content width (no dead
     space inside the border) up to the available width; when the dives outgrow
     it, the card caps at 100% and scrolls horizontally instead. */
  width: -moz-max-content;
  width: max-content;
  max-width: 100%;
}
.dv-logsheet {
  border-collapse: collapse;
  /* Content-sized, not stretched to fill: each column takes its defined width
     (below) and the table is the sum of them. In wide mode this leaves clean
     empty space on the right instead of ballooning every column; when the
     dives outgrow the container the wrap scrolls. */
  width: -moz-max-content;
  width: max-content;
}
.dv-logsheet thead tr { background: var(--canvas); }
.dv-logsheet thead tr:last-child { border-bottom: 1px solid var(--hairline); }
.dv-logsheet th {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted-2);
  text-align: left;
  padding: 12px 14px;
  white-space: nowrap;
}
.dv-logsheet tbody tr {
  border-bottom: 1px solid var(--hairline-2);
  cursor: pointer;
}
.dv-logsheet tbody tr:last-child { border-bottom: none; }
.dv-logsheet tbody tr:hover { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.dv-logsheet td { padding: 11px 14px; vertical-align: middle; }
.dv-logsheet tr.is-absent-all { opacity: .5; }
/* sticky name column (left) */
.dv-logsheet__name {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
  width: 248px;
  max-width: 248px;
}
.dv-logsheet thead .dv-logsheet__name { background: var(--canvas); }
.dv-logsheet tbody tr:hover .dv-logsheet__name { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.dv-logsheet__name::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 16px;
  transform: translateX(100%);
  pointer-events: none;
  background: linear-gradient(to right, color-mix(in srgb, var(--ink) 5%, transparent), transparent);
  opacity: 0;
  transition: opacity var(--t-fast);
}
.dv-logsheet-wrap.is-scroll .dv-logsheet__name::after { opacity: 1; }
.dv-logsheet__name-cell {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}
.dv-logsheet__name-txt { min-width: 0; flex: 1; }
/* Cap long names to the fixed column width — ellipsize instead of ballooning
   the pinned column (and pushing the whole matrix wider). */
.dv-logsheet__name-txt .os-table__primary,
.dv-logsheet__name-txt .os-table__sub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* two-tier logsheet header — dive-spot group over fixed field sub-columns */
.dv-logsheet thead .dv-logsheet__grp {
  text-align: center;
  padding: 11px 8px 8px;
  border-left: 1px solid var(--hairline);
}
.dv-logsheet__grp-sub {
  display: block;
  margin-top: 3px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--text-2xs);
  color: var(--muted-2);
}
.dv-logsheet thead tr.dv-logsheet__subrow th {
  padding: 6px 8px 9px;
  text-align: right;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: .09em;
  color: var(--muted-2);
}
.dv-logsheet thead tr.dv-logsheet__subrow th.is-gstart { border-left: 1px solid var(--hairline); }
.dv-logsheet thead tr.dv-logsheet__subrow th sub { font-size: .8em; }
/* numeric value cells — Geist Mono figures under fixed sub-columns.
   `.dv-logsheet td.dv-logsheet__num` out-specifies the generic `.dv-logsheet td`
   padding so the numeric cells keep their tight 8px sides. Widths are border-box,
   so the content area = width − 16px (e.g. In/Out = 136 − 16 = 120px of value). */
.dv-logsheet td.dv-logsheet__num {
  text-align: right;
  padding: 11px 8px;
  width: 54px;
}
.dv-logsheet__num.is-gstart { border-left: 1px solid var(--hairline); }
/* In/Out is the last cell of each dive group — extra right padding gives the
   time value breathing room before the group divider (width 148 keeps the
   value's content at ~120px). The header cell matches so they stay aligned. */
.dv-logsheet td.dv-logsheet__num.is-io { width: 148px; padding-right: 20px; }
.dv-logsheet thead tr.dv-logsheet__subrow th.is-io { padding-right: 20px; }
.dv-logsheet__fig {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  color: var(--ink);
  white-space: nowrap;
}
.dv-logsheet__fig.is-empty { color: var(--muted-2); }
/* mobile-only summary body + chevron — hidden on desktop/tablet */
.dv-logsheet__mcard { display: none; }
.dv-logsheet__mchev { display: none; }
/* absent span cell (colspan across a dive group) */
.dv-logsheet__absent {
  text-align: center;
  border-left: 1px solid var(--hairline);
}
.dv-logsheet__chip-absent {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--cancelled);
  background: var(--cancelled-bg);
  border: 1px solid var(--cancelled-border);
  border-radius: var(--radius-pill);
  padding: 3px 9px;
}
.dv-logsheet__chip-absent svg { width: 12px; height: 12px; }
/* sticky sign column (right) */
.dv-logsheet__sign {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--surface);
  text-align: right;
  width: 108px;
}
.dv-logsheet thead .dv-logsheet__sign { background: var(--canvas); }
.dv-logsheet tbody tr:hover .dv-logsheet__sign { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.dv-logsheet__sign::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 20px;
  transform: translateX(-100%);
  pointer-events: none;
  background: linear-gradient(to left, color-mix(in srgb, var(--ink) 5%, transparent), transparent);
  opacity: 0;
  transition: opacity var(--t-fast);
}
.dv-logsheet-wrap.is-scroll .dv-logsheet__sign::before { opacity: 1; }
.dv-logsheet__sig-mini {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--accent-strong);
}
/* ══════════════ sticky close bar ══════════════ */
.dv-close-bar {
  position: sticky;
  bottom: 0;
  z-index: 30;
  background: var(--surface);
  border-top: 1px solid var(--hairline);
  box-shadow: 0 -6px 16px -12px color-mix(in srgb, var(--ink) 20%, transparent);
  padding: 14px 28px;
  display: flex;
  align-items: center;
  gap: 20px;
}
.dv-close-bar__stats {
  display: flex;
  align-items: center;
  gap: 22px;
  flex: 1;
  flex-wrap: wrap;
}
.dv-cstat { display: flex; align-items: baseline; gap: 7px; }
.dv-cstat__n {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -.01em;
}
.dv-cstat__n--good { color: var(--confirmed); }
.dv-cstat__n--warn { color: var(--cancelled); }
.dv-cstat__l { font-size: var(--text-xs); color: var(--muted); }
/* ══════════════ drawer sign / switch / field form ══════════════
   Scoped under .dv-form-section so these local field rules never clobber the
   global os-ds .dv-field / .os-field form component. */
.dv-form-section { margin-bottom: 22px; }
.dv-form-section__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.dv-form-section__badge {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent-border);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.dv-form-section__badge svg { width: 15px; height: 15px; }
.dv-field-grid {
  display: grid;
  /* minmax(0, 1fr) — not 1fr — so the columns can shrink below the inputs'
     intrinsic (size-attribute) width; otherwise the grid overflows on narrow
     drawers (the fields would blow out to ~200px each). */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.dv-field-grid.is-disabled { opacity: .4; pointer-events: none; }
/* Full-width field in the 2-col grid (e.g. the Guide dv-select). */
.dv-field-grid .dv-field--wide { grid-column: 1 / -1; }
/* Phone: the time picker + AM/PM and free-text notes need the full row. */
@media (max-width: 640px) {
  .dv-field-grid .dv-field--wide-phone { grid-column: 1 / -1; }
}
.dv-form-section .dv-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.dv-form-section .dv-field label {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--muted-2);
}
.dv-form-section .dv-field__in {
  min-height: 46px;
  width: 100%;
  min-width: 0;
  padding: 0 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--input-border);
  background: var(--input-bg);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  font-weight: 500;
  color: var(--ink);
}
.dv-form-section .dv-field__in:focus {
  outline: none;
  border-color: var(--input-border-focus);
  box-shadow: var(--shadow-focus);
}
.dv-form-section .dv-field__in::-moz-placeholder {
  font-family: var(--font-sans);
  color: var(--muted-2);
}
.dv-form-section .dv-field__in::placeholder {
  font-family: var(--font-sans);
  color: var(--muted-2);
}
.dv-form-section .dv-field__in--text { font-family: var(--font-sans); }
.dv-abs-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  margin-top: 12px;
}
.dv-abs-row.on {
  background: var(--cancelled-bg);
  border-color: var(--cancelled-border);
}
.dv-abs-row__label {
  font-size: var(--text-sm);
  line-height: var(--leading-sm);
  font-weight: 500;
  color: var(--ink);
}
.dv-switch {
  width: 42px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--hairline-strong);
  border: none;
  position: relative;
  cursor: pointer;
  transition: background .15s;
  flex-shrink: 0;
}
.dv-switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--surface);
  transition: transform .15s;
  box-shadow: var(--shadow-sm);
}
.dv-switch.on { background: var(--cancelled); }
.dv-switch.on::after { transform: translateX(18px); }
.dv-sign-box {
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius);
  padding: 16px;
  text-align: center;
  background: var(--canvas);
}
.dv-sign-box.signed {
  border-style: solid;
  background: var(--confirmed-bg);
  border-color: var(--confirmed-border);
}
.dv-sign-scrawl {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  color: var(--accent-strong);
  min-height: 34px;
}
.dv-sign-scrawl.is-empty { color: var(--muted-2); }
/* Drawer signature pad canvas (reuses the .sig-* engine styles + signature
   controller). Class instead of an inline style so the canvas sizes cleanly. */
.dv-sign-frame { position: relative; background: var(--surface); }
.dv-sign-canvas { display: block; width: 100%; height: 132px; touch-action: none; }
.dv-sign-actions { display: flex; align-items: center; gap: 8px; }
.dv-signed-flag { display: inline-flex; align-items: center; gap: 4px; color: var(--confirmed); font-weight: 500; }
/* Signed view — the captured signature shown clearly, with a Re-sign button
   that swaps in the drawing canvas (.dv-sign-edit). */
.dv-sign-view,
.dv-sign-edit { display: block; }
.dv-sign-view[hidden],
.dv-sign-edit[hidden] { display: none; }
/* Match the waiver-form signature display: neutral surface + hairline, not a
   status colour (app/views/account/waiver_forms/show.html.erb). */
.dv-sign-view__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  padding: 8px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.dv-sign-view__img { max-height: 88px; max-width: 100%; }
.dv-sign-view__typed {
  font-family: "Brush Script MT", cursive;
  font-size: var(--text-2xl);
  color: var(--ink);
}
.dv-sign-view__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
}
/* Drawer loading skeleton — swapped into the turbo-frame while the per-diver
   body fetches. Mirrors the diver form's shape (header + two stop blocks + a
   sign row) using the os-ds `.loading-state` shimmer bars, so the panel reads
   as content arriving the instant it slides open (matching the booking
   side-panel), never a blank window or a dead spinner. */
.dv-drawer-skel {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 24px;
}
.dv-drawer-skel__head {
  display: flex;
  align-items: center;
  gap: 14px;
}
.dv-drawer-skel__avatar {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
}
.dv-drawer-skel__block,
.dv-drawer-skel__foot { margin: 0; }
.dv-drawer-skel__foot { margin-top: auto; }
/* ══════════════ mobile card-collapse (≤640px) ══════════════
   Matrix → one summary card per diver: the desktop numeric cells hide and the
   grouped .dv-logsheet__mcard renders instead — each dive labelled ONCE with a
   dense stat strip. The whole card taps through to the drawer to edit. */
@media (max-width: 640px) {
  /* Full-width on mobile — override the desktop content-width panel + wrap so the
     stacked diver cards fill the screen instead of shrinking to their content. */
  .dv-return-panel { width: 100%; margin-inline: 0; }
  .dv-logsheet-wrap { border: 0; background: transparent; overflow: visible; width: auto; max-width: none; }
  .dv-logsheet { min-width: 0; width: 100%; display: block; }
  .dv-logsheet thead { display: none; }
  .dv-logsheet tbody { display: block; }
  .dv-logsheet tbody tr {
    display: block;
    position: relative;
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px 14px;
    margin-bottom: 12px;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
  }
  .dv-logsheet tbody tr:active { background: var(--accent-soft); }
  .dv-logsheet tbody tr:hover { background: var(--surface); }

  /* desktop grid cells: gone on mobile */
  .dv-logsheet td.dv-logsheet__num,
  .dv-logsheet td.dv-logsheet__absent { display: none !important; }

  /* name header row */
  .dv-logsheet td.dv-logsheet__name {
    display: block;
    position: static;
    min-width: 0;
    width: auto;
    max-width: none;
    background: transparent;
    padding: 0 !important;
    border-bottom: 1px solid var(--hairline) !important;
    padding-bottom: 10px !important;
    margin-bottom: 2px;
  }
  .dv-logsheet td.dv-logsheet__name::before { content: none; }
  .dv-logsheet__mchev {
    display: flex;
    align-items: center;
    margin-left: auto;
    color: var(--muted-2);
  }
  .dv-logsheet__mchev svg { width: 19px; height: 19px; }

  /* grouped summary body */
  .dv-logsheet td.dv-logsheet__mcard {
    display: block;
    padding: 0 !important;
    border: 0 !important;
  }
  .dv-logsheet td.dv-logsheet__mcard::before { content: none; }
  .dv-mdive { padding: 10px 0; }
  .dv-mdive + .dv-mdive { border-top: 1px solid var(--hairline-2); }
  .dv-mdive__h {
    margin-bottom: 7px;
    color: var(--muted-2);
    display: flex;
    gap: 7px;
    align-items: baseline;
  }
  .dv-mdive__t {
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--muted-2);
    font-family: var(--font-mono);
  }
  .dv-mstat {
    display: flex;
    gap: 20px;
    align-items: flex-start;
    flex-wrap: wrap;
  }
  .dv-mstat__u { display: flex; flex-direction: column; gap: 2px; }
  .dv-mstat .dv-logsheet__fig {
    font-size: var(--text-md);
    font-weight: 500;
    line-height: 1.1;
  }
  .dv-mstat__us {
    font-size: var(--text-xs);
    color: var(--muted-2);
    margin-left: 1px;
    font-weight: 400;
  }
  .dv-mstat__ul {
    font-size: var(--text-2xs);
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--muted-2);
    font-weight: 600;
  }
  .dv-mtime { margin-top: 6px; font-family: var(--font-mono); }

  /* sign footer row — reuse ::before as the "Sign" label */
  .dv-logsheet td.dv-logsheet__sign {
    display: flex;
    position: static;
    width: auto;
    max-width: none;
    background: transparent;
    justify-content: space-between;
    align-items: center;
    border-top: 1px solid var(--hairline) !important;
    padding: 10px 0 0 !important;
    margin-top: 8px;
    text-align: right;
  }
  /* No sticky-column hover tint on the stacked mobile cards. */
  .dv-logsheet tbody tr:hover .dv-logsheet__name,
  .dv-logsheet tbody tr:hover .dv-logsheet__sign { background: transparent; }
  .dv-logsheet td.dv-logsheet__sign::before {
    content: attr(data-label);
    position: static;
    transform: none;
    width: auto;
    background: none;
    opacity: 1;
    flex: 0 0 auto;
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .dv-logsheet__name::after { display: none; }

  .dv-close-bar { padding: 12px 14px; }
  /* Full-bleed drawer on phones (no scrim strip). */
  .dv-drawer__panel { width: 100%; }
}
/* ══════════════ Running screen — log-later default (boat out) ══════════════
   The "laptop closed" state: a calm spinner + Returned/Emergency + an optional
   ghost link to live logging. Mirrors the log-later prototype's `running` frame. */
.run-running {
  text-align: center;
  max-width: 520px;
  margin: 8px auto 0;
  padding: 32px 20px;
}
.run-running__ring {
  display: block;
  width: 80px;
  height: 80px;
  margin: 0 auto 18px;
  border-radius: 50%;
  border: 3px solid var(--hairline-strong);
  border-top-color: var(--accent);
  animation: run-running-spin 2.4s linear infinite;
}
@keyframes run-running-spin { to { transform: rotate(360deg); } }
.run-running__title { margin-top: 12px; }
.run-running__lead { color: var(--muted); margin: 8px auto 24px; max-width: 46ch; }
.run-running__actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.run-running__optional { margin-top: 20px; }
@media (prefers-reduced-motion: reduce) { .run-running__ring { animation: none; } }
/* The trip-page "Trip is running" info banner: spin its leading loader-circle
   icon so the running state reads as live at a glance. transform-origin:center
   keeps it rotating in place (SVGs otherwise pivot oddly). */
.run-live-banner .dv-callout__icon svg {
  animation: run-running-spin 0.9s linear infinite;
  transform-origin: center;
}
@media (prefers-reduced-motion: reduce) { .run-live-banner .dv-callout__icon svg { animation: none; } }
/* ── dv-avatar ─────────────────────────────────────────────────────────────
   Initials disc for guests + staff where no photo exists. Formalises the
   inline pattern previously shown only in the showcase (accent-soft fill,
   accent ink). Sizes scale with context: list row (sm) → hero header (lg).
   Token-only. Blessed 2026-07-05 (Trip Roster build).
   ────────────────────────────────────────────────────────────────────────── */
.os-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-sm);
  letter-spacing: 0.01em;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.os-avatar--xs { width: 28px; height: 28px; font-size: var(--text-2xs); }
.os-avatar--sm { width: 32px; height: 32px; font-size: var(--text-xs); }
.os-avatar--lg { width: 56px; height: 56px; font-size: var(--text-xl); }
/* Neutral fallback (no initials) */
.os-avatar--muted { background: var(--gray-100); color: var(--muted); }
/* ── dv-chip (entity chip) ─────────────────────────────────────────────────
   A named, dismissible entity token — a selected person/tag rendered as a pill
   with optional avatar + inline remove control. Distinct from the legacy
   package-builder toggle chip (.dv-chip.is-on); an entity chip carries the
   --entity modifier so the two never collide. Token-only.
   Blessed 2026-07-05 (Trip Roster build).
   ────────────────────────────────────────────────────────────────────────── */
.os-chip--entity {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* Right padding is tight (6px) because the ✕ remove control fills that side.
     A NON-dismissible chip (no ✕) has no such filler, so its text would sit
     only 6px from the pill's curved edge — the `:not(:has())` rule below gives
     it comfortable, symmetric end padding. */
  padding: 5px 6px 5px 8px;
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  max-width: 100%;
}
.os-chip--entity:not(:has(.os-chip__x)) { padding-right: 12px; }
.os-chip--entity .os-chip__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.15;
}
.os-chip__name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.os-chip__meta {
  font-size: var(--text-2xs);
  color: var(--muted-2);
  white-space: nowrap;
}
.os-chip__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border: 0;
  background: none;
  border-radius: var(--radius-pill);
  color: var(--muted-2);
  cursor: pointer;
  transition: background .12s, color .12s;
}
.os-chip__x:hover { background: var(--cancelled-bg); color: var(--cancelled); }
.os-chip__x :is(.lucide, .os-lucide) { display: block; }
/* ── .os-chip--sm — compact single-line dismissible pill ────────────────────
   A lighter alternative to --entity for simple one-line tags (dietary flags,
   filters, selected options) where the name/meta stack of the entity chip
   reads as cramped. Single line, tighter padding, a smaller ✕. Pairs with the
   same .os-chip__x remove control. Token-only.
   Promoted from arena-ops (HotelOS) 2026-07-25. */
.os-chip--sm {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px 2px 10px;
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
  max-width: 100%;
}
.os-chip--sm:not(:has(.os-chip__x)) { padding-right: 10px; }
.os-chip--sm .os-chip__x { width: 16px; height: 16px; }
/* option-card — pickable result rows in the dive site "Find a dive site" finder. */
/* os-option-card — a selectable option row (icon tile + title + description + price).
 * Source: `.pick/.pi/.pk-t/.pk-d/.pk-p` (arrival.html, reg-card-hybrid.html) and
 * `.boat/.bi/.bt/.bd/.bp` (transfers.html). Those were the SAME idea at two fidelities —
 * the selectable list row and the "already chosen" accented block — collapsed here into
 * one component with a `--selected` modifier.
 * Works as <label>, <button> or <div>; wrap a visually-hidden radio for real selection.
 */
.os-option-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  /* The card MUST be the containing block for the visually-hidden input it
     owns (see the `position: absolute` rule below). Without this, that input
     resolves against whatever positioned ancestor happens to exist — and in a
     consumer whose page has none, that is the INITIAL containing block. It then
     escapes every `overflow` clip between here and the root (an overflow
     ancestor only clips an abspos descendant it is also the containing block
     for) and adds its own depth to the DOCUMENT's scrollable overflow.
     Measured in arena-ops: a full-bleed wizard pane at 900px viewport reported
     documentElement.scrollHeight 1289 with nothing visible below the fold, and
     the consumer's 100vh app shell scrolled off the top. A component must not
     depend on its host page to contain what the component itself positions.
     Same fix, same reason as `.side-panel__body` in patterns.css. */
  position: relative;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.os-option-card + .os-option-card {
  margin-top: var(--space-2);
}
.os-option-card:hover {
  border-color: var(--hairline-strong);
}
.os-option-card--selected,
.os-option-card--selected:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.os-option-card__icon {
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: var(--radius-md);
  display: grid;
  place-items: center;
  background: var(--surface-alt);
  color: var(--text-secondary);
}
.os-option-card--selected .os-option-card__icon {
  background: var(--surface);
  color: var(--accent);
}
.os-option-card__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.os-option-card__title {
  font-size: var(--text-sm);
  line-height: var(--leading-sm);
  font-weight: 600;
  color: var(--ink);
}
.os-option-card__desc {
  font-size: var(--text-xs);
  line-height: var(--leading-xs);
  color: var(--muted);
  margin-top: 2px;
}
.os-option-card__price {
  margin-left: auto;
  flex: none;
  text-align: right;
  font-size: var(--text-xs);
  line-height: var(--leading-xs);
  font-weight: 600;
  color: var(--accent-strong);
}
/* ── The card IS the control (2026-07-28) ─────────────────────────────────
   A card-shaped option must not also show a radio dot. The card already says
   "pick one of these" through its shape, its hover and its selected fill; a
   radio next to it is the same message twice, and it is the message that looks
   like the real control, so the eye goes to a 16px dot instead of the 400px
   target. A PLAIN radio group still shows its radios — that is what
   `.os-radio` is for. This rule is only for the card form.

   THE BUG IT ALSO FIXES: consumers were painting `--selected` from
   SERVER-rendered state while `checked` followed the click, so selecting a
   different card moved the dot and left the fill behind. Painting from
   `:has(input:checked)` means the fill IS the checked state and cannot
   disagree with it. `--selected` still works for a static/no-JS render. */
.os-option-card :is(input[type="radio"], input[type="checkbox"]) {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.os-option-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.os-option-card:has(input:checked) .os-option-card__icon {
  background: var(--accent-soft);
  color: var(--accent-strong);
}
/* The keyboard ring has to move to the card: the input it belongs to is hidden. */
.os-option-card:has(input:focus-visible) {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* ═══════════════════════════════════════════════════════════════════════
   dv-bulkbar — sticky multi-select action bar.

   Appears when one or more rows in a list/table are ticked; carries the
   selection count + bulk actions (assign, mark, clear). Accent-filled so it
   reads as an active operating mode, not a passive toolbar.

   Anatomy:
     .dv-bulkbar
       .dv-bulkbar__count     — "N selected"
       .dv-bulkbar__action    — a bulk action button (repeatable)
       .dv-bulkbar__clear     — dismiss selection (pushed to the right)
   ═══════════════════════════════════════════════════════════════════════ */
.os-bulkbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  margin: 12px 0;
  border-radius: var(--radius-lg);
  background: var(--accent);
  color: var(--surface);
  box-shadow: var(--shadow-md);
}
.os-bulkbar__count {
  font-weight: 600;
  font-size: var(--text-xs);
  padding-right: 4px;
}
.os-bulkbar__action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  min-height: 38px;
  border-radius: var(--radius-md);
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(255, 255, 255, .12);
  color: var(--surface);
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
}
.os-bulkbar__action:hover { background: rgba(255, 255, 255, .22); }
.os-bulkbar__action :is(.lucide, .os-lucide) { opacity: .9; }
.os-bulkbar__clear {
  margin-left: auto;
  padding: 6px 10px;
  background: transparent;
  border: 0;
  color: rgba(255, 255, 255, .85);
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
}
.os-bulkbar__clear:hover { color: var(--surface); text-decoration: underline; }
/* ═══════════════════════════════════════════════════════════════════════
   dv-sheet — mobile bottom sheet.

   A modal surface that slides up from the bottom edge for edit-in-context
   tasks on touch/phone (log a dive, pick a value). Backdrop dims the page;
   the panel is capped at 90svh (see the note on .dv-sheet__panel) and scrolls
   internally. On tablet/desktop the same content is better served by a drawer
   or inline panel — the sheet is intended for narrow viewports.

   Anatomy:
     .dv-sheet                 — fixed backdrop (toggle .is-open)
       .dv-sheet__panel        — the sheet surface
         .dv-sheet__grip       — drag affordance pill
         .dv-sheet__head
         .dv-sheet__body       — scroll region
         .dv-sheet__foot       — sticky action row
   ═══════════════════════════════════════════════════════════════════════ */
.os-sheet {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: flex-end;
  background: rgba(17, 24, 39, .45);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s var(--ease-standard);
}
.os-sheet.is-open {
  opacity: 1;
  pointer-events: auto;
}
.os-sheet__panel {
  width: 100%;
  /* `svh`, not `vh` or `dvh` — and on a bottom sheet the distinction is not
     cosmetic. `vh` is the LARGE viewport (toolbar hidden), so with the toolbar
     showing a 90vh panel is taller than the visible area and `.dv-sheet__foot`
     — the action row — sits behind the browser chrome on the one component
     type where the actions matter most.

     `dvh` would track the toolbar live and repaint the panel mid-scroll.
     `svh` is the small viewport (toolbar shown), so the sheet always fits.
     `vh` stays first as the fallback; both svh/dvh are Safari 15.4+.
     See docs/mobile-primitives.md §1. */
  max-height: 90vh;
  max-height: 90svh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: var(--shadow-panel);
  transform: translateY(100%);
  transition: transform .24s var(--ease-out-quart);
}
.os-sheet.is-open .os-sheet__panel { transform: translateY(0); }
.os-sheet__grip {
  width: 40px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--gray-300);
  margin: 10px auto 4px;
  flex-shrink: 0;
}
.os-sheet__head {
  padding: 8px 20px 12px;
  border-bottom: 1px solid var(--hairline);
}
.os-sheet__head .os-eyebrow { color: var(--muted-2); }
.os-sheet__body {
  padding: 18px 20px;
  overflow-y: auto;
  flex: 1;
  /* Containing block, for the same reason as `.os-drawer__body` — this scrolls
     inside a `position: fixed` sheet, and an unowned abspos descendant anchors
     to that wrapper rather than to this scroller. See the note there. */
  position: relative;
}
.os-sheet__body > .os-eyebrow { display: block; color: var(--muted-2); margin-bottom: 4px; }
.os-sheet__foot {
  display: flex;
  gap: 10px;
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--hairline);
  background: var(--surface);
}
.os-sheet__foot > .os-btn { flex: 1; justify-content: center; min-height: 48px; }
/* The sheet is a mobile pattern; on wide viewports keep it available but it is
   typically driven only under a media query by the consuming surface. */
@media (min-width: 641px) {
  .os-sheet__panel { max-width: 440px; margin: 0 auto; border-radius: var(--radius-xl); }
  .os-sheet { align-items: center; }
}
/* ═══════════════════════════════════════════════════════════════════════
   os-filter-sheet — the mobile filter grammar (dive-os #329).

   ONE DOM, two layouts. A list's `.os-page-tools` row keeps its primary facet
   (`.os-scope-tabs--primary`) as a horizontal-scroll strip on phones; every
   secondary facet (payment, date range, toggles…) renders ONCE inside
   `.os-filter-sheet__body`, and CSS decides where it shows:

     >640px  the trigger is hidden; the sheet, panel, body and group wrappers
             are `display: contents` and head / foot / labels are hidden, so the
             secondary facets lay out inline in the tools row exactly as if the
             wrappers were absent. Desktop is unchanged.
     ≤640px  the trigger is a pill after the primary strip; the sheet is a fixed
             bottom sheet (the `.os-sheet` visual tokens) that stacks the facets.

   Anatomy (inside .os-page-tools[data-controller="filter-sheet"]):
     .os-filter-trigger            — mobile-only pill (toggle .is-on when count>0)
       [icon] <span>Filters</span>
       .os-filter-trigger__count   — active-facet count badge
     .os-filter-sheet              — fixed backdrop (toggle .is-open)
       .os-filter-sheet__panel     — the sheet surface
         .os-filter-sheet__head
           .os-filter-sheet__grip
           .os-filter-sheet__title
           .os-filter-sheet__clear — optional reset link
         .os-filter-sheet__body    — scroll region; the facets
           .os-filter-sheet__group — optional facet group
             .os-filter-sheet__label — facet heading (sheet only)
         .os-filter-sheet__foot    — sticky; full-width primary .os-btn ("Done")

   Driven by the `filter-sheet` Stimulus controller (open/close, Esc, backdrop
   click, focus, aria-expanded, body.os-filter-sheet-open scroll lock, count).
   ═══════════════════════════════════════════════════════════════════════ */
/* ── Desktop / tablet (>640px): invisible wrappers ─────────────────────── */
@media (min-width: 641px) {
  .os-filter-trigger { display: none; }
  .os-filter-sheet,
  .os-filter-sheet__panel,
  .os-filter-sheet__body,
  .os-filter-sheet__group { display: contents; }
  .os-filter-sheet__head,
  .os-filter-sheet__foot,
  .os-filter-sheet__label { display: none; }
}
/* ── Phones (≤640px): trigger pill + bottom sheet ──────────────────────── */
@media (max-width: 640px) {
  /* Trigger — reads as a sibling of the .os-scope-tab pills it follows. */
  .os-filter-trigger {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    padding: 6px 13px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    color: var(--ink);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color var(--t-fast) ease, background var(--t-fast) ease, color var(--t-fast) ease;
    /* Pinned to the trailing edge of the scrolling tools strip so it is never
       scrolled out of reach; the primary pills slide cleanly under it. A solid
       surface block + hairline divider (::before) marks the pinned zone — no
       fade, so pills never ghost through. */
    position: sticky;
    right: 0;
    z-index: 1;
    margin-left: auto;
    /* Shadows paint UNDER the pill's own fill, so they back it without
       touching its shape: the left copy fills behind the rounded left side
       (pills can't show through the corner curve); the right one masks the
       strip's trailing padding. */
    box-shadow: -12px 0 0 2px var(--surface), 20px 0 0 4px var(--surface);
  }
  .os-filter-trigger::before {
    content: "";
    position: absolute;
    top: -4px;
    bottom: -4px;
    left: -9px;
    width: 8px;
    background: var(--surface);
    border-left: 1px solid var(--hairline);
  }
  .os-filter-trigger:hover { background: var(--canvas); }
  .os-filter-trigger svg,
  .os-filter-trigger [data-lucide] { color: var(--muted-2); flex-shrink: 0; }
  .os-filter-trigger__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--accent-soft);
    color: var(--accent);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--text-2xs);
    font-weight: 600;
    line-height: 1;
  }
  .os-filter-trigger__count[hidden] { display: none; }
  .os-filter-trigger.is-on {
    /* accent-soft is translucent; layer it on an opaque surface so the pills
       scrolling beneath the pinned trigger don't show through. */
    background: linear-gradient(var(--accent-soft), var(--accent-soft)), var(--surface);
    border-color: var(--accent-border);
    color: var(--accent);
  }
  .os-filter-trigger.is-on svg,
  .os-filter-trigger.is-on [data-lucide] { color: var(--accent); }
  .os-filter-trigger.is-on .os-filter-trigger__count {
    background: var(--accent);
    color: var(--on-accent);
  }

  /* Backdrop — mirrors .os-sheet. */
  .os-filter-sheet {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: flex;
    align-items: flex-end;
    background: rgba(17, 24, 39, .45);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s var(--ease-standard);
  }
  .os-filter-sheet.is-open {
    opacity: 1;
    pointer-events: auto;
  }

  /* Containing-block + stacking trap. The tools row is sticky (z 4 → its own
     stacking context, so a fixed child would paint UNDER the z 5 title bar) and
     slides out with `transform` (which would make it the containing block of
     this position:fixed sheet, pinning the sheet to the row instead of the
     viewport). While the sheet is open, lift the row and drop the transform.
     Its overflow-x scroller does not clip a fixed descendant once it is no
     longer the containing block. */
  .os-page-tools:has(.os-filter-sheet.is-open) {
    transform: none !important;
    z-index: 70;
  }

  /* Panel — the sheet surface (svh cap: see the note on .os-sheet__panel). */
  .os-filter-sheet__panel {
    width: 100%;
    max-height: 90vh;
    max-height: 90svh;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    box-shadow: var(--shadow-panel);
    transform: translateY(100%);
    transition: transform .24s var(--ease-out-quart);
    outline: none;
  }
  .os-filter-sheet.is-open .os-filter-sheet__panel { transform: translateY(0); }

  .os-filter-sheet__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    position: relative;
    padding: 24px 20px 12px; /* top clears the absolutely-centred grip */
    border-bottom: 1px solid var(--hairline);
    flex-shrink: 0;
  }
  /* Centred above the title regardless of what else sits in the head row
     (a flex-basis:100% grip can't force a wrap once max-width caps it). */
  .os-filter-sheet__grip {
    position: absolute;
    top: 10px;
    left: 50%;
    width: 40px;
    height: 4px;
    margin-left: -20px;
    border-radius: var(--radius-pill);
    background: var(--gray-300);
  }
  .os-filter-sheet__title {
    flex: 1 1 auto;
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: var(--leading-lg);
    letter-spacing: -0.01em;
    color: var(--ink);
  }
  .os-filter-sheet__clear {
    font: inherit;
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--muted);
    text-decoration: none;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
  }
  .os-filter-sheet__clear:hover { color: var(--ink); text-decoration: underline; }

  /* Body — scrolls internally; facets stack. position: relative so it owns
     any abspos descendant (same reason as .os-sheet__body). */
  .os-filter-sheet__body {
    position: relative;
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 18px 20px;
  }
  .os-filter-sheet__body > *,
  .os-filter-sheet__group > * { max-width: 100%; }
  /* Specificity beats the ≤640 strip rule that sets nowrap on scope-tabs
     inside the tools row, regardless of import order. */
  .os-filter-sheet .os-filter-sheet__body .os-scope-tabs {
    flex-wrap: wrap;
    gap: 6px;
    width: 100%;
    margin-left: 0; /* drop inline-row spacers (e.g. ml-2) — groups stack here */
  }
  .os-filter-sheet__body .os-vrule,
  .os-filter-sheet__body .os-spacer { display: none; }

  /* Date disclosure — the popover renders inline, full width, and shown even
     while the <details> is closed (the controller also sets [open] on closed
     disclosures while the sheet is open, for engines without
     ::details-content). !important beats the callsite's utility positioning. */
  .os-filter-sheet__body details { width: 100%; }
  /* The summary is the desktop popover's toggle; in the sheet the fields are
     always shown, so it would be a dead control. */
  .os-filter-sheet__body details > summary { display: none; }
  .os-filter-sheet__body details::details-content {
    content-visibility: visible;
    display: contents;
  }
  .os-filter-sheet__body details > :not(summary) {
    display: grid;
    position: static !important;
    inset: auto !important;
    width: 100% !important;
    min-width: 0 !important;
    margin-top: 0 !important;
    box-shadow: none !important;
  }

  .os-filter-sheet__group {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
  }
  .os-filter-sheet__label {
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.4;
    color: var(--muted-2);
  }

  .os-filter-sheet__foot {
    position: sticky;
    bottom: 0;
    display: flex;
    gap: 10px;
    padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--hairline);
    background: var(--surface);
    flex-shrink: 0;
  }
  .os-filter-sheet__foot > .os-btn { flex: 1; justify-content: center; min-height: 48px; }

  body.os-filter-sheet-open { overflow: hidden; }
}
/* #329 mobile filter sheet (os-ds v1.28) */
/* ── dv-gear-slot ──────────────────────────────────────────────────────────
   A single gear-sizing row for the Gear Fitting surface: an icon-badged slot
   name, an optional size segment (All / S / M / L …) and a box select fed from
   inventory. Formalises the standalone `.gslot` markup as a token-only DS
   component so fitting surfaces (drawer + mobile overlay) never hand-roll it.
   Blessed 2026-07-05 (Trip Plan · Gear Fitting build).

   Anatomy:
     .dv-gear-slot
       .dv-gear-slot__head      — icon badge + slot name
         .dv-gear-slot__icon
         .dv-gear-slot__name
       .dv-segment (size)       — reuse the segmented control; sizes wrap
       .dv-select (box)         — reuse the DS select for the box number

   Pairs live in a responsive grid via .dv-gear-slot-grid (2-up ≥560px).
   ────────────────────────────────────────────────────────────────────────── */
:is(.dv-gear-slot-grid, .os-gear-slot-grid) {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px 24px;
}
@media (min-width: 560px) {
  :is(.dv-gear-slot-grid, .os-gear-slot-grid) { grid-template-columns: 1fr 1fr; }
}
/* In the ~560px Side panel drawer (fitting), 2-up packs the size pills +
   select too tightly — keep a single column there (matches the prototype
   drawer's single-column form). */
:is(.side-panel, .os-side-panel) :is(.dv-gear-slot-grid, .os-gear-slot-grid) { grid-template-columns: 1fr; }
:is(.dv-gear-slot, .os-gear-slot) {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
/* Grid cells stretch to the tallest slot in their row, so a slot WITH size
   pills is taller than one without (e.g. Fin vs Regulator). Pin the field to
   the bottom of the cell so every slot's dropdown lands on the same baseline
   across the 2-up grid — the pills float at the top, the inputs align in a
   clean horizontal line. The last child is the <select>/.diveos-input. */
:is(.dv-gear-slot, .os-gear-slot) > :last-child {
  margin-top: auto;
}
:is(.dv-gear-slot__head, .os-gear-slot__head) {
  display: flex;
  align-items: center;
  gap: 8px;
}
:is(.dv-gear-slot__icon, .os-gear-slot__icon) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent);
}
:is(.dv-gear-slot__icon, .os-gear-slot__icon) svg { width: 15px; height: 15px; }
:is(.dv-gear-slot__name, .os-gear-slot__name) {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--text-primary);
}
/* The size segment wraps for slots with many sizes (Suit, Fin). Keep each
   option compact so a 5-up row still fits the slot column. */
:is(.dv-gear-slot, .os-gear-slot) :is(.dv-segment, .os-segment) {
  flex-wrap: wrap;
  gap: 6px;
}
:is(.dv-gear-slot, .os-gear-slot) :is(.dv-segment__option, .os-segment__option) {
  flex: 0 0 auto;
}
:is(.dv-gear-slot, .os-gear-slot) :is(.dv-segment__label, .os-segment__label) {
  min-width: 40px;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 10px;
}
/* ── .dv-accordion ──────────────────────────────────────────────────────────
   Disclosure accordion: a stack of collapsible panels. Each item is a
   header button that toggles its body open/closed. Tokens only — no raw
   palette, no hex. Built for the trip Return checklist (boxes → gear rows)
   but general enough for any grouped disclosure list.

   Anatomy:
     .dv-accordion            wrapper (stacks items with gap)
       .dv-accordion__item    one panel  (+ .is-open)
         .dv-accordion__head  the toggle button (full-width, ≥44px tall)
           .dv-accordion__icon   leading glyph slot
           .dv-accordion__title  heading text
           .dv-accordion__meta   right-aligned mono progress/count
           .dv-accordion__chev   trailing chevron (rotates when open)
         .dv-accordion__body  disclosed content (hidden unless .is-open)
------------------------------------------------------------------------------- */
.os-accordion {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.os-accordion__item {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs, 0 1px 2px rgba(17, 24, 39, .04));
  overflow: hidden;
}
.os-accordion__head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 52px;
  padding: 14px 18px;
  background: none;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--ink);
  transition: background .12s;
}
.os-accordion__head:hover { background: var(--surface-alt); }
.os-accordion__head:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.os-accordion__item.is-open .os-accordion__head {
  border-bottom: 1px solid var(--hairline);
}
.os-accordion__icon {
  display: inline-flex;
  color: var(--muted-2);
  flex-shrink: 0;
}
.os-accordion__title {
  font-family: var(--font-display, var(--font-sans));
  font-weight: 600;
  font-size: var(--text-base, 15px);
  color: var(--ink);
}
.os-accordion__meta {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs, 12.5px);
  color: var(--muted);
  white-space: nowrap;
}
.os-accordion__chev {
  display: inline-flex;
  color: var(--muted-2);
  flex-shrink: 0;
  transition: transform .18s ease;
}
.os-accordion__item.is-open .os-accordion__chev { transform: rotate(180deg); }
.os-accordion__body { padding: 4px 18px 16px; }
.os-accordion__item:not(.is-open) .os-accordion__body { display: none; }
/* Right-aligned actions strip inside a body (e.g. "Return all"). */
.os-accordion__foot {
  display: flex;
  justify-content: flex-end;
  padding-top: 12px;
}
/* ─── Popover — anchored multi-select / picker (.dv-pop) ─────────────────────
   Ported from the Trip v4 prototype roster (pt-pop → dv-pop). An anchored
   floating panel: search row on top, a scrollable option list, a footer for
   count + Done. Options are .dv-opt rows (avatar · name+meta · checkbox).
   The anchor wrapper needs position:relative (.dv-msel) — and remember
   .dv-card clips overflow; give the host card .dv-card--overflow-visible.
   Showcased in /admin/design_system (Popover section). */
.os-msel { position: relative; }
.os-pop {
  position: absolute;
  z-index: 40; top: calc(100% + 8px); left: 0;
  width: var(--width-xs);
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-panel);
  overflow: hidden;
}
.os-pop[hidden] { display: none; }
.os-pop__search {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 12px; border-bottom: 1px solid var(--hairline);
}
.os-pop__search :is(.lucide, .os-lucide) { color: var(--muted-2); flex-shrink: 0; }
.os-pop__search input {
  flex: 1; border: 0; background: none; outline: none;
  font: inherit; font-size: var(--text-sm); color: var(--ink);
}
.os-pop__search input::-moz-placeholder { color: var(--muted-2); }
.os-pop__search input::placeholder { color: var(--muted-2); }
.os-pop__list { max-height: 268px; overflow-y: auto; padding: 4px; }
.os-pop__empty { padding: 16px; text-align: center; }
/* Option row — works as a bare <button> or a button_to form's button. */
.os-pop__list form { display: contents; }
.os-opt {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left;
  padding: 8px 10px; border: 0; background: none; cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background .1s;
}
.os-opt:hover { background: var(--hover-warm); }
.os-opt__body { flex: 1; min-width: 0; line-height: 1.25; }
.os-opt__name { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
.os-opt__meta { font-size: var(--text-2xs); color: var(--muted-2); }
.os-opt__meta.is-off { color: var(--cancelled); }
.os-optcheck {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex-shrink: 0;
  border: 1.5px solid var(--hairline-strong); border-radius: 4px;
  color: var(--surface); background: var(--surface);
  transition: background .1s, border-color .1s;
}
.os-opt.is-on .os-optcheck { background: var(--accent); border-color: var(--accent); }
.os-optcheck :is(.lucide, .os-lucide) { opacity: 0; }
.os-opt.is-on .os-optcheck :is(.lucide, .os-lucide) { opacity: 1; }
.os-pop__foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; border-top: 1px solid var(--hairline);
}
.os-pop__foot :is(.cnt, .os-cnt) { font-size: var(--text-2xs); color: var(--muted); }
.os-pop__foot :is(.cnt, .os-cnt) :is(.mono, .os-mono) { font-family: var(--font-mono); }
@media (max-width: 1024px) {
  .os-pop { width: min(var(--width-xs), calc(100vw - 48px)); }
}
/* ─── Popover dialog (.os-popover) ───────────────────────────────────────────
   A small anchored FORM DIALOG — head / body / foot in a bordered panel,
   role="dialog". Distinct from .os-pop above (a select/search DROPDOWN): this
   is for a focused mini-form (edit a flight, add a payment) rather than picking
   an option. Promoted from arena-ops (HotelOS) 2026-07-25. Token-only. */
.os-popover {
  width: 100%;
  max-width: var(--width-sm);
  max-height: 90vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-panel);
  display: flex;
  flex-direction: column;
}
.os-popover__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--hairline);
}
.os-popover__body {
  padding: var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.os-popover__body--flush { padding: 0; }
.os-popover__sep { height: 1px; background: var(--hairline); margin: var(--space-1) 0; }
.os-popover__foot {
  display: flex; gap: var(--space-2); justify-content: flex-end;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--hairline);
}
.os-popover__foot--bare { padding: var(--space-3) 0 0; border: none; }
/* hstepper — state-driven .os-hstepper (os-ds v1.29). The gem's
   shared/patterns/_stepper_horizontal (Run stepper, wizard_layout, showcase)
   emits these classes; without the sheet the stepper renders unstyled. */
/* profile_row — the shared person/entity row (avatar · name+meta · trailing
   status/action). os-ds v1.3.0 promoted it after DiveOS's `.bk-detail
   .waiver-diver-row` and arena's `.hos-occrow` proved to be the same rule.
   Consumed by account/bookings/_waiver_roster. Do NOT re-add a local copy. */
/* ─── Profile row (.os-profile-row) ──────────────────────────────────────────
   A person/entity row: avatar · name + meta · trailing status/action. The most
   repeated list shape in both products — guest capture, occupants, waiver
   divers, crew, agents, staff pickers.

   Promoted 2026-07-26 from arena-ops `.hos-occrow` (the fuller BEM version);
   dive-os had the same base rule as the page-scoped `.bk-detail
   .waiver-diver-row` (identical flex/gap/padding/border), and arena carried a
   second copy in its guest-portal sheet. One component, three implementations —
   this is the one.

   Structure:
     .os-profile-row            (or --link on an <a>, --pick on a <label>)
       .os-profile-row__avatar  (+ --alt / --empty)
       .os-profile-row__info
         .os-profile-row__name
         .os-profile-row__meta
       .os-profile-row__trail   (or __badges / __status)

   Domain colourings (a role pill, an id pill) stay in the consuming app —
   they are status vocabulary, not row structure. Token-only. */
.os-profile-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--hairline);
}
.os-profile-row:last-child { border-bottom: none; }
/* Whole row is a link — keeps the row's own type colour, tints on hover. */
.os-profile-row--link {
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius-md);
}
.os-profile-row--link:hover { background: var(--accent-softer); }
.os-profile-row__avatar {
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: var(--radius-pill);
  /* Accent-derived, NOT a raw ramp stop: this shipped in v1.3.0 reading
     `--teal-900`, which the gem does not define. An unresolvable var() voids
     the WHOLE background declaration, so the avatar lost its fill and its
     white initials vanished — invisible in arena (which defines that token
     locally) and broken in dive-os. Gem components read gem tokens. */
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--surface);
}
/* --alt flips the gradient so adjacent rows read as different people. */
.os-profile-row__avatar--alt   { background: linear-gradient(135deg, var(--accent-strong), var(--accent)); }
/* --empty: a placeholder person (not captured / unassigned). */
.os-profile-row__avatar--empty { background: var(--surface-alt); color: var(--muted-2); }
.os-profile-row__info { flex: 1; min-width: 0; }
.os-profile-row__name { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
.os-profile-row__meta { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; }
/* Trailing zones — __trail for actions, __status for pills, __badges for both. */
.os-profile-row__trail,
.os-profile-row__status {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}
.os-profile-row__status { flex-wrap: wrap; }
.os-profile-row__badges {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  flex: none;
  flex-wrap: wrap;
}
/* The trailing "Open ›" affordance on a --link row. */
.os-profile-row__open {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--muted);
}
/* ── --last: an explicit terminal row ───────────────────────────────────────
   `:last-child` is not enough when a control follows the list (a "view all"
   link after a capped roster) — the last ROW is then not the last CHILD.
   Requested by dive-os during the v1.4.0 adoption. */
.os-profile-row--last { border-bottom: none; }
/* ── __badges--columns: align trailing slots across rows ────────────────────
   The flex default lets each row size its own trailing block, so status pills
   drift out of alignment when labels differ in length ("Signed" vs "Valid
   waiver on file"). This switches to a grid whose track list the consumer
   sets, e.g. `style="--os-profile-row-badge-cols: 158px 80px"`. */
.os-profile-row__badges--columns {
  display: grid;
  grid-template-columns: var(--os-profile-row-badge-cols, auto auto);
  align-items: center;
}
/* NOTE: the --teal-900 shim profile_row.css needs is at the BOTTOM of this file.
   It cannot live here — postcss-import drops every @import that follows a
   non-@import statement, which silently deletes the rest of the bundle. */
/* card.css — the canonical .dv-card info-card shell (white surface, hairline,
   radius-lg, --raised/--interactive/--selected states). Its own header declares
   it is "@imported from application.css after components/booking-v2.css"; that
   import had been dropped, leaving .dv-card unstyled on every surface that uses
   it (12 views + the /admin/design_system showcase). Restored here. */
/* engine.css — v4 booking-engine wizard chrome (calendar grid + step
   indicator), ported light from the legacy dark public.css. Slice 2A. */
/* ─────────────────────────────────────────────────────────────────────
   engine.css — booking engine (Slice 2A) wizard chrome.

   The public booking wizard's calendar grid + funnel stepper styling used
   to live in the legacy dark public.css (not loaded by the v4 engine). This
   file is the v4 light port: token-driven, no dark blocks, no naked hex.
   Two jobs:
     1. Structural CSS the wizard partials need (.bw-cal-grid is a 7-col grid;
        .bw-funnel-stepper 860px cap; states come from os-ds .os-hstepper).
     2. Remap the handful of raw-blue Tailwind classes the date-picker /
        dives controllers inject (bg-blue-600 selected cells, text-blue-600
        prices, blue chips) onto the per-tenant accent token, so the funnel
        tracks the shop's brand instead of a hardcoded blue.

   @imported from application.css after booking-v2.css.
   ───────────────────────────────────────────────────────────────────── */
:root {
  --funnel-stepper-max: 860px; /* booking funnel stepper content cap */
}
/* ── Calendar grid (7 columns) ──────────────────────────────────────── */
:is(.bw-cal-grid, .os-bw-cal-grid) {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
/* Remap the date-picker's JS-injected blue onto the tenant accent (light).
   Default (gray-700) + past (gray-300) cells already read fine on canvas. */
:is(.booking-wizard, .os-booking-wizard) :is(.bw-cal-grid, .os-bw-cal-grid) :is(.bg-blue-600, .os-bg-blue-600) {
  background-color: var(--accent) !important;
}
:is(.booking-wizard, .os-booking-wizard) :is(.bw-cal-grid, .os-bw-cal-grid) :is(.ring-blue-600, .os-ring-blue-600) {
  --tw-ring-color: var(--accent) !important;
}
:is(.booking-wizard, .os-booking-wizard) :is(.bw-cal-grid, .os-bw-cal-grid) :is(.text-blue-600, .os-text-blue-600) {
  color: var(--accent) !important;
}
:is(.booking-wizard, .os-booking-wizard) :is(.bw-cal-grid, .os-bw-cal-grid) :is(.hover, .os-hover)\:bg-blue-50:hover {
  background-color: var(--accent-soft) !important;
}
/* Selected-date chips + product prices the controllers inject in raw blue. */
:is(.booking-wizard, .os-booking-wizard) :is(.bg-blue-50, .os-bg-blue-50) { background-color: var(--accent-soft) !important; }
:is(.booking-wizard, .os-booking-wizard) :is(.border-blue-200, .os-border-blue-200) { border-color: var(--accent-border) !important; }
:is(.booking-wizard, .os-booking-wizard) :is(.text-blue-700, .os-text-blue-700), :is(.booking-wizard, .os-booking-wizard) :is(.text-blue-600, .os-text-blue-600) { color: var(--accent) !important; }
/* ── Funnel stepper ─────────────────────────────────────────────────── */
/* The os-ds _stepper_horizontal pattern (.os-hstepper) renders
   the states; the funnel only caps it at the wizard-layout 860px, centred. */
.bw-funnel-stepper { max-width: 860px; margin: 0 auto var(--space-6); }
/* Desktop: always-visible sticky bar, full-bleed --surface with a hairline;
   the stepper content stays capped at 860px (padding-inline, not max-width,
   so the background spans the viewport). Below popovers/dialogs (--z-dropdown < --z-modal). */
@media (min-width: 641px) {
  .bw-funnel-stepper { position: sticky; top: 0; z-index: var(--z-tooltip); max-width: none;
    background: var(--surface); border-bottom: 1px solid var(--hairline); margin: 0 calc(50% - 50vw) var(--space-6);
    padding: var(--space-3) max(var(--space-4), calc((100vw - var(--funnel-stepper-max)) / 2)); }
}
/* Phone: header + stepper are ONE sticky top group. public-wizard toggles
   body.bw-chrome-hidden on scroll-down (past ~150px) and removes it on scroll-up;
   transform-only so layout never shifts. Header is 4rem (h-16). */
@media (max-width: 640px) {
  body:has(.bw-funnel-stepper) .engine-header { position: sticky; top: 0; z-index: var(--z-tooltip);
    transition: transform .2s ease; }
  body:has(.bw-funnel-stepper) .bw-funnel-stepper { position: sticky; top: var(--space-16); z-index: var(--z-tooltip);
    background: var(--surface); border-bottom: 1px solid var(--hairline);
    margin: 0 calc(50% - 50vw) var(--space-4); padding: var(--space-3) var(--space-4);
    transition: transform .2s ease; }
  body.bw-chrome-hidden .engine-header { transform: translateY(-100%); }
  body.bw-chrome-hidden .bw-funnel-stepper { transform: translateY(calc(-100% - 4rem)); }
}
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  body:has(.bw-funnel-stepper) .engine-header, body:has(.bw-funnel-stepper) .bw-funnel-stepper { transition: none; }
}
/* Accommodation picker: dive-date marker on os-cal days. */
.bw-cal-grid button.os-cal__day { border: 0; padding: 0; font-family: inherit; }
.bw-cal-grid { row-gap: 2px; }
.bw-cal-grid .os-cal__day { position: relative; }
/* Dive day = small accent dot under the number (not a ring, so it can't read as selected). */
.bw-cal-grid .os-cal__day.bw-accom-dive::after { content: ""; position: absolute; bottom: 18%; left: 50%;
  width: var(--space-1); height: var(--space-1); margin-left: -2px; border-radius: 50%; background: var(--accent); }
.bw-cal-grid .os-cal__day.is-sel.bw-accom-dive::after { background: var(--surface); }
.bw-cal-grid .os-cal__day.is-range { border: 0; box-shadow: none; }
/* Hover/active/focus must never wash out a selected or in-range day. */
.bw-cal-grid .os-cal__day.is-sel:is(:hover, :active, :focus) { background: var(--accent-strong); color: var(--surface); }
.bw-cal-grid .os-cal__day.is-range:not(.is-sel):is(:hover, :active, :focus) { background: var(--accent-light); color: var(--accent-strong); }
.bw-cal-grid .os-cal__day.is-sel.range-start { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.bw-cal-grid .os-cal__day.is-sel.range-end { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
/* ── Waiver signature field ─────────────────────────────────────────── */
/* Mode toggle (Draw / Type); the signature controller toggles .active. */
:is(.sig-mode-btn, .os-sig-mode-btn) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  height: 2.5rem;
  padding: 0 0.875rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink);
  background-color: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-btn, 6px);
  cursor: pointer;
  transition: color 150ms, background-color 150ms, border-color 150ms;
}
:is(.sig-mode-btn, .os-sig-mode-btn):hover { background-color: var(--surface-alt); }
:is(.sig-mode-btn, .os-sig-mode-btn):is(.active, .os-active) {
  color: var(--accent);
  background-color: var(--accent-soft);
  border-color: var(--accent);
}
/* Canvas — white surface with a subtle ruled guide line. */
:is(.sig-canvas-container, .os-sig-canvas-container) {
  background-color: var(--surface);
  background-image: repeating-linear-gradient(
    0deg, transparent, transparent 39px, var(--hairline) 39px, var(--hairline) 40px
  );
}
:is(.sig-canvas, .os-sig-canvas) { cursor: crosshair; display: block; }
/* Typed signature — dashed field, cursive preview. */
:is(.sig-typed-input, .os-sig-typed-input) {
  width: 100%;
  height: 3.25rem;
  padding: 0 0.875rem;
  font-family: "Brush Script MT", cursive;
  font-size: 1.25rem;
  color: var(--ink);
  background-color: var(--surface);
  border: 2px dashed var(--hairline-strong);
  border-radius: var(--radius-md, 8px);
}
:is(.sig-typed-input, .os-sig-typed-input):focus {
  outline: none;
  border-color: var(--accent);
}
/* ── Legacy boolean-toggle-buttons (bootstrap variant) ──────────────── */
/* The shared themes/legacy/_boolean_toggle_buttons partial emits Bootstrap
   btn-group classes; the boolean-toggle-buttons controller swaps btn-primary
   (active) ↔ btn-outline-secondary (inactive). The engine doesn't load
   Bootstrap, so we style those classes to v4 — scoped to .engine-body so it
   only affects the booking engine, never account/POS surfaces. */
:is(.engine-body, .os-engine-body) :is(.btn-group, .os-btn-group) {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
:is(.engine-body, .os-engine-body) :is(.btn-group, .os-btn-group) :is(.btn, .os-btn) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  height: 2.75rem;
  padding: 0 1rem;
  font-size: 0.875rem;
  font-weight: 500;
  border-radius: var(--radius-md, 8px);
  border: 1px solid var(--hairline);
  background-color: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: color 150ms, background-color 150ms, border-color 150ms;
}
:is(.engine-body, .os-engine-body) :is(.btn-group, .os-btn-group) :is(.btn-outline-secondary, .os-btn-outline-secondary):hover { background-color: var(--surface-alt); }
:is(.engine-body, .os-engine-body) :is(.btn-group, .os-btn-group) :is(.btn-primary, .os-btn-primary) {
  color: var(--accent);
  background-color: var(--accent-soft);
  border-color: var(--accent);
}
/* ── Wizard modals (product picker + accommodation) ─────────────────── */
/* base_dives / public-accommodation inject a .bw-modal-overlay > .bw-modal-panel
   dialog. The overlay/panel constraint CSS lived in the dark public.css; this is
   the light port, scoped to .engine-body. The positive `.hidden` rule below keeps
   the static accommodation modal hidden until the controller reveals it (the product modal
   is added to the DOM only while open, so it has no .hidden). The bw-modal-grid
   (product card grid) is reused inside the panel. */
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay) {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
/* The static accommodation modal ships with .hidden; keep it hidden until the
   controller reveals it (our scoped overlay rule outranks Tailwind's .hidden). */
:is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay).hidden { display: none !important; }
:is(.engine-body, .os-engine-body) :is(.bw-modal-panel, .os-bw-modal-panel) {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-height: 90dvh;
  background-color: var(--surface);
  color: var(--ink);
  box-shadow: 0 20px 50px rgba(17, 24, 39, 0.25);
}
@media (min-width: 640px) {
  :is(.engine-body, .os-engine-body) :is(.bw-modal-overlay, .os-bw-modal-overlay) { align-items: center; }
  :is(.engine-body, .os-engine-body) :is(.bw-modal-panel, .os-bw-modal-panel) {
    max-width: var(--bw-modal-max-width, 56rem);
    margin: 0 1rem;
    max-height: 85vh;
  }
}
:is(.bw-modal-grid, .os-bw-modal-grid) {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
}
@media (min-width: 576px) {
  :is(.bw-modal-grid, .os-bw-modal-grid) { grid-template-columns: 1fr 1fr; }
}
/* ── Room-card banner (#336) ─────────────────────────────────────────────
   Photo (.bw-room-image__img) fills a fixed-ratio banner; with no/broken
   image the banner shows a tinted surface + the Lucide `image` glyph. The
   glyph always sits behind the <img>, so it is the loading/placeholder state
   and the onerror fallback (.bw-room-image--placeholder) needs no extra DOM. */
:is(.bw-room-image, .os-bw-room-image) {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 180px;
  overflow: hidden;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--hairline);
  color: var(--muted-2);
}
:is(.bw-room-image__icon, .os-bw-room-image__icon) { width: 32px; height: 32px; flex: none; }
:is(.bw-room-image__img, .os-bw-room-image__img) {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}
/* Public page ground (muf 2026-10-10): every guest-facing public page — booking
   funnel, receipts, payment, waivers, storefront — sits on slate-50 so white
   cards lift off it. One rule here, not per page. */
.engine-body { background: var(--slate-50); }
/* Funnel page head (muf 2026-10-10): "Book your dive" sits IN the header —
   same full-bleed --surface fill as the brand bar above and the stepper below,
   so the top reads as one white header block over the slate page (Cancel lives
   top-right in the brand bar). Pulled up over the shell's top padding; content
   stays on the page column (padding mirrors the bleed). */
.bw-funnel-head { background: var(--surface); margin: calc(-1 * var(--space-6)) calc(50% - 50vw) 0; padding: var(--space-5) calc(50vw - 50%) var(--space-2); }
@media (min-width: 640px) { .bw-funnel-head { margin-top: calc(-1 * var(--space-8)); } }
.bw-funnel-head + * { margin-top: 0 !important; }
/* A flash (e.g. a rejected send) renders above the page; the band then starts
   below it instead of pulling up over it (S10). */
.engine-shell > [role="alert"] ~ * > .bw-funnel-head { margin-top: 0; }
body:has(.engine-shell > [role="alert"]) .engine-header { border-bottom-color: var(--hairline); }
body:has(.bw-funnel-head) .engine-header { border-bottom-color: transparent; }
/* dv-toast — transient confirmation toasts, top-right stack.
   Spawned by controllers/toast_controller.js (flash → toast bridge). */
/* ───────────────────────────────────────────────────────────────────
   dv_toast — transient confirmation toasts (operator / light theme)
   Approved design: Option A, top-right stack (tmp/toast-preview.html).
   Floats over content, stacks newest-on-top, auto-dismisses after 4s
   with a progress bar, manual close. Token-only.
   Spawned by toast_controller.js (flash → toast bridge).
   ─────────────────────────────────────────────────────────────────── */
:is(.toast-stack, .os-toast-stack) {
  position: fixed;
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 360px;
  max-width: calc(100vw - 32px);
  pointer-events: none;
}
:is(.toast-stack, .os-toast-stack):is(.tr, .os-tr) { top: 16px; right: 16px; }
/* Mobile bottom-center placement — floats above a bottom tab bar / dock, where
   a top-right 360px slab would cover the header context. --os-toast-btm is a
   consumer knob: set it to clear your bottom chrome — over an .os-bottomnav,
   calc(var(--os-bottomnav-h) + var(--space-3)), never a literal bar height. */
:is(.toast-stack, .os-toast-stack):is(.bc, .os-bc) {
  top: auto;
  right: auto;
  left: 50%;
  bottom: var(--os-toast-btm, 24px);
  transform: translateX(-50%);
  align-items: center;
  width: -moz-max-content;
  width: max-content;
  max-width: calc(100vw - 32px);
}
/* Click-through: a bottom-center toast overlaps the primary CTA underneath it,
   so the card must not eat the tap — only the dismiss control stays interactive.
   (Errors are sticky, so a caller relying on the CTA is never blocked by a timer.) */
:is(.toast-stack, .os-toast-stack):is(.bc, .os-bc) :is(.toast, .os-toast) { pointer-events: none; }
:is(.toast-stack, .os-toast-stack):is(.bc, .os-bc) :is(.toast__x, .os-toast__x) { pointer-events: auto; }
/* Off-screen assertive live region: mirrors error toasts so a screen reader
   announces them urgently (the visual stack is polite). Visually hidden, never
   a second visual surface. Created at boot by toast_controller.js. */
:is(.toast-live, .os-toast-live) {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
:is(.toast, .os-toast) {
  pointer-events: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--text-muted);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 30px rgba(17, 24, 39, 0.16), 0 2px 6px rgba(17, 24, 39, 0.08);
  padding: 12px 14px;
  display: flex;
  gap: 11px;
  align-items: flex-start;
  animation: os-toast-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
  position: relative;
  overflow: hidden;
}
:is(.toast, .os-toast):is(.out, .os-out) { animation: os-toast-out 0.18s ease forwards; }
@keyframes os-toast-in {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}
@keyframes os-toast-out {
  to {
    opacity: 0;
    transform: translateX(16px);
    height: 0;
    padding-top: 0;
    padding-bottom: 0;
    margin-top: -10px;
  }
}
:is(.toast__ic, .os-toast__ic) { flex-shrink: 0; margin-top: 1px; }
:is(.toast__ic, .os-toast__ic) svg { display: block; }
:is(.toast__body, .os-toast__body) { flex: 1; min-width: 0; }
:is(.toast__title, .os-toast__title) { font-size: var(--text-sm); font-weight: 600; color: var(--text-primary); }
:is(.toast__msg, .os-toast__msg) { font-size: var(--text-sm); color: var(--text-secondary); margin-top: 1px; }
:is(.toast__x, .os-toast__x) {
  flex-shrink: 0;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px;
  margin: -2px -2px 0 0;
  border-radius: 4px;
  background: none;
  border: 0;
  line-height: 0;
}
:is(.toast__x, .os-toast__x) svg { display: block; }
:is(.toast__x, .os-toast__x):hover { background: var(--surface-alt, var(--gray-100)); color: var(--text-primary); }
:is(.toast__bar, .os-toast__bar) {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  background: currentColor;
  opacity: 0.4;
  animation: os-toast-shrink 4s linear forwards;
}
@keyframes os-toast-shrink {
  from { width: 100%; }
  to   { width: 0; }
}
/* status accents — generic notification semantics from tokens.css */
:is(.toast, .os-toast):is(.success, .os-success) { background: var(--green-100); border-color: var(--success-border); border-left-color: var(--success); }
:is(.toast, .os-toast):is(.success, .os-success) :is(.toast__ic, .os-toast__ic), :is(.toast, .os-toast):is(.success, .os-success) :is(.toast__bar, .os-toast__bar) { color: var(--success); }
:is(.toast, .os-toast):is(.error, .os-error) { background: var(--rose-100); border-color: var(--danger-border); border-left-color: var(--danger); }
:is(.toast, .os-toast):is(.error, .os-error) :is(.toast__ic, .os-toast__ic), :is(.toast, .os-toast):is(.error, .os-error) :is(.toast__bar, .os-toast__bar) { color: var(--danger); }
:is(.toast, .os-toast):is(.warning, .os-warning) { background: var(--amber-100); border-color: var(--warning-border); border-left-color: var(--warning); }
:is(.toast, .os-toast):is(.warning, .os-warning) :is(.toast__ic, .os-toast__ic), :is(.toast, .os-toast):is(.warning, .os-warning) :is(.toast__bar, .os-toast__bar) { color: var(--warning); }
:is(.toast, .os-toast):is(.info, .os-info) { background: var(--sky-100); border-color: var(--info-border); border-left-color: var(--info); }
:is(.toast, .os-toast):is(.info, .os-info) :is(.toast__ic, .os-toast__ic), :is(.toast, .os-toast):is(.info, .os-info) :is(.toast__bar, .os-toast__bar) { color: var(--info); }
@media (prefers-reduced-motion: reduce) {
  :is(.toast, .os-toast), :is(.toast, .os-toast):is(.out, .os-out) { animation-duration: 0.01ms; }
  :is(.toast__bar, .os-toast__bar) { animation: none; width: 0; }
}
/* waiver_share — shared "Show QR & link" control (booking roster + POS success). */
/* waiver_share — the shared "Show QR & link" control rendered by the booking
   roster and the POS success screen (shared/waivers/_waiver_share). Token-only
   per the design gate; no raw palette colors. #35. */
:is(.wv-share, .os-wv-share) {
  margin-top: 8px;
}
:is(.wv-share__toggle, .os-wv-share__toggle) {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--accent);
  background: none;
  border: none;
  padding: 2px 0;
  cursor: pointer;
}
:is(.wv-share__toggle, .os-wv-share__toggle):hover {
  color: var(--accent-strong);
}
:is(.wv-share__panel, .os-wv-share__panel) {
  margin-top: 8px;
  padding: 12px;
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-start;
}
:is(.wv-share__qr, .os-wv-share__qr) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 6px;
  line-height: 0;
}
:is(.wv-share__linkrow, .os-wv-share__linkrow) {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-width: 0;
}
:is(.wv-share__url, .os-wv-share__url) {
  flex: 1 1 auto;
  min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
  color: var(--muted);
  word-break: break-all;
}
:is(.wv-share__copy, .os-wv-share__copy) {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: 6px;
  padding: 4px 8px;
  cursor: pointer;
}
:is(.wv-share__copy, .os-wv-share__copy):hover {
  background: var(--surface-alt);
}
:is(.wv-share__copy, .os-wv-share__copy):is(.copied, .os-copied) {
  color: var(--confirmed);
  border-color: var(--confirmed-border);
}
/* Waiver amendment ledger (#347) — the audit trail in the waiver show rail.
   "Ledger" direction: each amendment is a ledger entry hung off a 2px accent
   rule, with the value transitions set in the figure/mono face so a staff
   member can compare old against new down a column at a glance.

   Sits inside the 320px .hero-show__rail, so every measure here is tuned for
   that width. Tokens only — no raw hex, no px type. */
:is(.wv-ledger, .os-wv-ledger) {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
/* An entry. The left rule carries recency: the newest amendment gets the
   accent, older ones a muted hairline. That encodes "most recent" without
   spending a badge or a component on it. */
:is(.wv-ledger__entry, .os-wv-ledger__entry) {
  border-left: 2px solid var(--hairline-strong);
  padding-left: 12px;
}
:is(.wv-ledger__entry--latest, .os-wv-ledger__entry--latest) {
  border-left-color: var(--accent);
}
/* Line 1 — absolute timestamp. Deliberately NOT mono: it is a label, not a
   value to compare, and the eyebrow role already sets 10px/uppercase/0.08em. */
:is(.wv-ledger__stamp, .os-wv-ledger__stamp) {
  display: block;
  margin-bottom: 2px;
}
/* Line 2 — who made the correction, plus an optional medical badge. */
:is(.wv-ledger__actor, .os-wv-ledger__actor) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
}
/* The diffs. */
:is(.wv-ledger__diffs, .os-wv-ledger__diffs) {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
:is(.wv-ledger__field, .os-wv-ledger__field) {
  display: block;
  font-size: var(--text-xs);
  color: var(--muted);
  margin-bottom: 1px;
}
/* Values get the mono face — this is the one place monospace earns its keep,
   because it column-aligns the before/after digits for comparison. */
:is(.wv-ledger__values, .os-wv-ledger__values) {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}
:is(.wv-ledger__was, .os-wv-ledger__was) {
  color: var(--muted-2);
  text-decoration: line-through;
}
:is(.wv-ledger__arrow, .os-wv-ledger__arrow) {
  color: var(--muted-2);
  flex-shrink: 0;
}
:is(.wv-ledger__now, .os-wv-ledger__now) {
  color: var(--ink);
  font-weight: 600;
}
/* Divider between the factual diff and the human justification. */
:is(.wv-ledger__rule, .os-wv-ledger__rule) {
  border: 0;
  border-top: 1px solid var(--hairline);
  margin: 10px 0;
}
/* Why it was changed. */
:is(.wv-ledger__why, .os-wv-ledger__why) {
  font-size: var(--text-xs);
  color: var(--ink);
}
:is(.wv-ledger__category, .os-wv-ledger__category) {
  margin-left: 6px;
}
/* Page-scoped CSS for redesigned families (added per page-family rollout). */
/* ─────────────────────────────────────────────────────────────────────
   Fleet — page-specific CSS for account/boats/index.

   White-label benchmark: project/pages/m4-fleet.html (extracted spec in
   tmp_fleet_benchmark.md). m4-fleet is a card grid of vessel cards (default
   view) + a table view toggle + a detail drawer.

   Only genuinely page-specific primitives live here. The header band,
   toolbar, chips and vertical divider are SHARED — they come from
   components/header_band.css (.dv-page-band / .dv-toolbar / .chip / .dv-divider)
   and are consumed as-is. Status pills come from the shared .status-pill family
   (dashboard.css). Do NOT redefine any of those here.

   Token-driven (consumes the semantic aliases from tokens.css).
   ───────────────────────────────────────────────────────────────────── */
/* ── Vessel card (default grid view) ──────────────────────────────────
   WL §6a. Card shell + the procedural boat illustration (no image asset —
   pure CSS clip-path silhouette over a paper-gradient tile). */
/* Vessel cards — as many 320px (--width-xs)+ columns as fit: one on a phone,
   two on a tablet, three on desktop. A fixed three-up squeezed each card to
   ~100px at 375 (name gone, Capacity/Trips labels overlapping). Same rule as
   the desk cards (.fo-card-grid). */
.vessel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--width-xs)), 1fr));
  gap: var(--space-3);
}
:is(.vessel-card, .os-vessel-card) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg, 10px);
  padding: 20px;
  cursor: pointer;
  transition: border-color 120ms ease;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
  text-decoration: none;
  color: inherit;
}
:is(.vessel-card, .os-vessel-card):hover { border-color: var(--hairline-strong, #D9D4C5); }
/* ── Boat illustration — card (80×56) ─────────────────────────────────
   ::before = hull silhouette, ::after = waterline. Type modifiers swap the
   hull clip-path: default speedboat, .catamaran twin-hull, .dhoni curved. */
:is(.vessel-illu, .os-vessel-illu) {
  width: 80px; height: 56px;
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--canvas) 0%, var(--surface-alt) 100%);
  border-radius: 8px;
  border: 1px solid var(--hairline);
  position: relative;
  overflow: hidden;
}
:is(.vessel-illu, .os-vessel-illu)::before {
  content: '';
  position: absolute;
  left: 12px; right: 12px;
  bottom: 16px; height: 14px;
  background: var(--ink);
  clip-path: polygon(8% 0, 92% 0, 100% 100%, 0 100%);
  border-radius: 2px;
}
:is(.vessel-illu, .os-vessel-illu)::after {
  content: '';
  position: absolute;
  left: 14px; right: 28px;
  bottom: 8px; height: 8px;
  background: linear-gradient(180deg, transparent 50%, var(--accent) 50%);
  border-radius: 0 0 999px 999px;
  opacity: 0.6;
}
:is(.vessel-illu, .os-vessel-illu):is(.catamaran, .os-catamaran)::before {
  clip-path: polygon(0 0, 45% 0, 50% 100%, 55% 0, 100% 0, 100% 100%, 0 100%);
  height: 18px; bottom: 14px;
}
:is(.vessel-illu, .os-vessel-illu):is(.catamaran, .os-catamaran)::after { display: none; }
:is(.vessel-illu, .os-vessel-illu):is(.dhoni, .os-dhoni)::before {
  clip-path: polygon(0 60%, 12% 0, 88% 0, 100% 60%, 96% 100%, 4% 100%);
  height: 18px; bottom: 16px;
}
/* ── View toggle (segmented Card / Table control) ─────────────────────
   WL §4. Presentational here — only the Card view has a server render; the
   Table segment is a disabled placeholder (flagged in
   DESIGN_PARITY_MISSING_CONTENT.md). */
:is(.view-toggle, .os-view-toggle) {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 2px;
  gap: 2px;
}
:is(.view-btn, .os-view-btn) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 26px;
  border: none; border-radius: 6px; cursor: pointer;
  color: var(--muted-2); background: transparent;
  transition: background 120ms ease, color 120ms ease;
}
:is(.view-btn, .os-view-btn):hover { color: var(--ink); background: var(--hairline-2); }
:is(.view-btn, .os-view-btn):is(.active, .os-active) { background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent-border); }
:is(.view-btn, .os-view-btn).is-disabled { cursor: not-allowed; }
:is(.view-btn, .os-view-btn).is-disabled:hover { color: var(--muted-2); background: transparent; }
/* ── Search field (toolbar) ───────────────────────────────────────────
   WL .search-wrap. Presentational (no fleet-search backend yet). */
:is(.fleet-search, .os-fleet-search) {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  border-radius: 8px;
  padding: 0 10px;
  height: 32px;
}
:is(.fleet-search, .os-fleet-search) svg { width: 14px; height: 14px; color: var(--muted); flex-shrink: 0; }
:is(.fleet-search, .os-fleet-search) input {
  border: none; outline: none; background: transparent;
  font-size: var(--text-sm); color: var(--ink); font-family: var(--font-sans); width: 100%;
}
:is(.fleet-search, .os-fleet-search) input::-moz-placeholder { color: var(--muted); }
:is(.fleet-search, .os-fleet-search) input::placeholder { color: var(--muted); }
/* ─────────────────────────────────────────────────────────────────────
   Gear index — page-scoped components.

   Ported from the White-label-design benchmark (m6-gear.html). WL is the
   visual source of truth; tokens are remapped to Dive-Management's palette
   (tokens.css). Structure (dv-page-band header + dv-toolbar + dv-table-wrap)
   is consumed from the shared component layer (components/header_band.css,
   account/divers.css). This sheet adds ONLY the genuinely page-specific bits:

   1. the category `--cat-*` color token set (WL hard-coded these hex values
      twice — once on the type-card swatch, once on the item-id dot; the spec
      flagged the duplication, so they are tokenized here as the single
      source of truth), and
   2. the `.type-card` summary tile + `.item-id` colored ID + `.svc-cell`
      service-date cell, which exist only on this page.

   Status badges use the synced `.status-pill` system (status_palette_helper
   `equipment_status_presentation`), NOT WL's `.dv-badge`.
   ───────────────────────────────────────────────────────────────────── */
/* ── Per-category color tokens ────────────────────────────────────────
   8 categories (Equipment::CATEGORIES). WL only swatched 6; the two extra
   DM categories (mask, smb) get their own hues so every row dot is distinct.
   Both the type-card swatch and the item-id dot reference these.
   v4: every hue derives from the system palette (the WL swatches were
   v3-era hex, incl. a banned purple). smb stays amber-orange — real
   SMBs are orange — via the amber ramp rather than an off-system hex. */
:root {
  /* P3-N (2026-06-29): category swatches no longer borrow status hues
     (Fins read as red/alert, Regulators as green/OK). One neutral swatch
     for every category — the label carries identity; red/green/amber stay
     reserved for real item status (serviceable / service-due / quarantined). */
  --cat-tank:      var(--muted-2);
  --cat-bcd:       var(--muted-2);
  --cat-regulator: var(--muted-2);
  --cat-suit:      var(--muted-2);
  --cat-fin:       var(--muted-2);
  --cat-computer:  var(--muted-2);
  --cat-mask:      var(--muted-2);
  --cat-smb:       var(--muted-2);
}
/* ── Type strip cards ─────────────────────────────────────────────────
   Category summary tiles above the table. Page-local — WL m6-gear only. */
:is(.type-card, .os-type-card) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 12px 14px;
  cursor: pointer;
  transition: border-color 120ms ease;
}
:is(.type-card, .os-type-card):hover { border-color: var(--hairline-strong); }
:is(.type-card, .os-type-card).is-on { background: var(--accent-soft); border-color: var(--accent-border); }
:is(.type-card, .os-type-card) :is(.swatch, .os-swatch) {
  width: 8px; height: 8px; border-radius: 2px;
  display: inline-block; margin-right: 8px; vertical-align: middle;
}
:is(.type-card, .os-type-card) :is(.tname, .os-tname) { font-family: var(--font-display); font-weight: 500; font-size: var(--text-sm); color: var(--ink); }
:is(.type-card, .os-type-card) :is(.tval, .os-tval)  { font-family: var(--font-mono); font-size: var(--text-md); font-weight: 500; color: var(--ink); margin-top: 6px; }
:is(.type-card, .os-type-card) :is(.tval, .os-tval) small { color: var(--muted); font-size: var(--text-xs); margin-left: 3px; }
:is(.type-card, .os-type-card) :is(.talert, .os-talert) { font-size: var(--text-2xs); font-weight: 500; color: var(--briefing); letter-spacing: 0.02em; margin-top: 4px; }
:is(.type-card, .os-type-card) :is(.talert--muted, .os-talert--muted) { color: var(--muted); }
:is(.type-card, .os-type-card).is-on :is(.talert, .os-talert) { color: var(--accent); }
/* ── Item ID with category color dot ──────────────────────────────────
   mono identifier preceded by an 8px rounded square in the category hue. */
:is(.item-id, .os-item-id) {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
:is(.item-id, .os-item-id)::before {
  content: '';
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--accent);
}
:is(.item-id, .os-item-id):is(.t-tank, .os-t-tank)::before      { background: var(--cat-tank); }
:is(.item-id, .os-item-id):is(.t-bcd, .os-t-bcd)::before       { background: var(--cat-bcd); }
:is(.item-id, .os-item-id):is(.t-regulator, .os-t-regulator)::before { background: var(--cat-regulator); }
:is(.item-id, .os-item-id):is(.t-suit, .os-t-suit)::before      { background: var(--cat-suit); }
:is(.item-id, .os-item-id):is(.t-fin, .os-t-fin)::before       { background: var(--cat-fin); }
:is(.item-id, .os-item-id):is(.t-computer, .os-t-computer)::before  { background: var(--cat-computer); }
:is(.item-id, .os-item-id):is(.t-mask, .os-t-mask)::before      { background: var(--cat-mask); }
:is(.item-id, .os-item-id):is(.t-smb, .os-t-smb)::before       { background: var(--cat-smb); }
/* ── Service cell (last / next maintenance date) ──────────────────────
   Two-line: uppercase micro-label over a mono date. warn/urgent recolor the
   date when service is approaching / overdue. */
:is(.svc-cell, .os-svc-cell) { display: flex; flex-direction: column; gap: 2px; }
:is(.svc-cell, .os-svc-cell) :is(.l, .os-l) { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); }
:is(.svc-cell, .os-svc-cell) :is(.v, .os-v) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink); }
:is(.svc-cell, .os-svc-cell) :is(.v, .os-v):is(.warn, .os-warn)   { color: var(--briefing); }
:is(.svc-cell, .os-svc-cell) :is(.v, .os-v):is(.urgent, .os-urgent) { color: var(--cancelled); }
/* ── Registry table <900px (D20) ──────────────────────────────────────
   Intentional narrow layout instead of a squeezed 5-column table: the
   Next-service + Assigned columns drop out and their values re-stack as
   a second meta line under Description (`.gear-registry__stacked`,
   hidden on desktop). Horizontal scroll on the wrap stays as the
   fallback for anything still wider than the viewport. */
:is(.gear-registry, .os-gear-registry):is(.dv-table-wrap, .os-table-wrap) { overflow-x: auto; }
:is(.gear-registry__stacked, .os-gear-registry__stacked) { display: none; }
@media (max-width: 899px) {
  :is(.gear-registry, .os-gear-registry) th:nth-child(4), :is(.gear-registry, .os-gear-registry) td:nth-child(4), :is(.gear-registry, .os-gear-registry) th:nth-child(5), :is(.gear-registry, .os-gear-registry) td:nth-child(5) { display: none; }
  :is(.gear-registry__stacked, .os-gear-registry__stacked) {
    display: flex;
    flex-wrap: wrap;
    -moz-column-gap: 8px;
         column-gap: 8px;
  }
}
/* ── Gear landing header + category tiles (#609 R1) ───────────────────────
   The six view links sit inline in the page-head actions from tablet up; on
   phones (the os-ds page-head's ≤640 icon-only band) seven buttons overflowed
   370px, so they fold into one "More" menu (.os-pop of .os-opt links, toggled
   by the os-ds dropdown controller) beside the primary +. */
.gear-views { display: contents; }
.gear-views-menu { display: none; }
.gear-views-menu .gear-views-menu__pop { left: auto; right: 0; }
@media (max-width: 640px) {
  .gear-views { display: none; }
  .gear-views-menu { display: block; }
}
/* Category tiles: one row on desktop (--N = tiles per row, 4 past six
   categories), 2-across on phones so labels don't clip. */
.gear-category-grid--1 { grid-template-columns: minmax(0, 1fr); }
.gear-category-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gear-category-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gear-category-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gear-category-grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.gear-category-grid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 767px) {
  .gear-category-grid[class*="gear-category-grid--"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* account/ledger.css — page-scoped styles for the Ledger page.
   Shared primitives (.dv-page-band, .dv-toolbar, .chip, .dv-table-wrap,
   .status-pill) are defined in components/header_band.css + dashboard.css.
   Only ledger-specific rules live here. */
/* ── Date navigation arrows & Close-day button ────────────────────────
   Promoted to the shared button family in components/buttons.css. The arrows
   now use `.dv-btn dv-btn--secondary dv-btn--icon dv-btn--sm` (32px square,
   hairline outline) and Close-day uses `.dv-btn dv-btn--primary`. The former
   one-off `.ledger-nav-arrow` / `.ledger-close-btn` rules were removed. */
/* ── KPI stat card grid ───────────────────────────────────────────────
   Promoted to the shared boxed-stat component (.dv-stat-card-grid /
   .dv-stat-card / -label / -value) in components/stat_card.css. The Ledger
   day-summary now consumes those shared classes; the former .ledger-stat-*
   rules were removed (values carried over byte-for-byte). */
/* ── Transaction table row hover ─────────────────────────────────── */
:is(.ledger-table-row, .os-ledger-table-row) {
  transition: background 120ms ease-out;
}
:is(.ledger-table-row, .os-ledger-table-row):hover {
  background: var(--hover-warm, var(--canvas));
}
/* ── Amount colours ───────────────────────────────────────────────── */
:is(.ledger-amount--income, .os-ledger-amount--income) {
  color: var(--green-700, #15803d);
}
:is(.ledger-amount--refund, .os-ledger-amount--refund) {
  color: var(--red-600, #dc2626);
}
/* ── Payment method badge ─────────────────────────────────────────── */
:is(.ledger-method-badge, .os-ledger-method-badge) {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 7px;
  border-radius: 4px;
  border: 1px solid var(--hairline);
  background: var(--canvas);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink-2, var(--muted));
  white-space: nowrap;
}
/* Method-specific tints (subtle, not loud) */
:is(.ledger-method-badge--cash, .os-ledger-method-badge--cash)          { background: var(--confirmed-bg); border-color: var(--confirmed-border); color: var(--confirmed); }
:is(.ledger-method-badge--credit_card, .os-ledger-method-badge--credit_card), :is(.ledger-method-badge--debit_card, .os-ledger-method-badge--debit_card)    { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent); }
:is(.ledger-method-badge--bank_transfer, .os-ledger-method-badge--bank_transfer) { background: var(--inwater-bg); border-color: var(--inwater-border); color: var(--inwater); }
:is(.ledger-method-badge--online_payment, .os-ledger-method-badge--online_payment){ background: var(--briefing-bg); border-color: var(--briefing-border); color: var(--briefing); }
:is(.ledger-method-badge--agent_credit, .os-ledger-method-badge--agent_credit)  { background: var(--pending-bg); border-color: var(--pending-border); color: var(--pending); }
/* ── Cash drawer count (day-close denomination grid, MR-D) ────────────
   Optional till count keyed before close. Token-clean, page-scoped. */
:is(.ledger-close-card, .os-ledger-close-card) {
  padding: 16px 18px;
}
/* Review-first head — the "what's being locked" lead (left) and the Net for
   the day hero figure (right), so the operator scans the outcome before the
   itemised breakdown below. Wraps to stacked on narrow cards. */
:is(.ledger-close-card__head, .os-ledger-close-card__head) {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.os-ledger-close-card__lead {
  display: grid;
  gap: 4px;
  min-width: 0;
}
.os-ledger-close-card__net {
  display: grid;
  gap: 2px;
  justify-items: end;
  text-align: right;
}
.os-ledger-close-card__net-fig {
  font-size: var(--text-2xl);
  font-weight: 600;
  line-height: 1.1;
}
.os-ledger-close-card__net-fig--neg { color: var(--cancelled); }
/* Action bar — a natural card footer with the irreversibility note (left) and
   the primary/cancel controls (right). Optional steps above are collapsed by
   default, so this stays near the top / immediately reachable on load. */
:is(.ledger-close-card__actions, .os-ledger-close-card__actions) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
}
.os-ledger-close-card__note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  color: var(--muted);
}
.os-ledger-close-card__note :is(svg, .lucide) { color: var(--muted-2); flex-shrink: 0; }
.os-ledger-close-card__btns { display: inline-flex; align-items: center; gap: 10px; }
/* Optional-step disclosure — the collapsed card-reconciliation + drawer-count
   sections. Summary carries an icon title, an "Optional" badge, and a chevron
   that rotates when open. */
.os-ledger-close-card__form { display: grid; gap: 10px; }
.os-ledger-optional {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface);
}
.os-ledger-optional__summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  cursor: pointer;
  list-style: none;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.os-ledger-optional__summary::-webkit-details-marker { display: none; }
.os-ledger-optional__summary::marker { content: ""; }
.os-ledger-optional__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}
.os-ledger-optional__title :is(svg, .lucide) { color: var(--muted-2); flex-shrink: 0; }
.os-ledger-optional__flag { margin-left: auto; }
.os-ledger-optional__chevron { color: var(--muted-2); transition: transform .15s ease; }
.os-ledger-optional[open] .os-ledger-optional__chevron { transform: rotate(180deg); }
.os-ledger-optional__body {
  display: grid;
  gap: 12px;
  padding: 0 14px 14px;
}
/* Gap-days — compact count+range summary is the callout title; the full date
   list collapses into this disclosure. */
.os-ledger-gap-days { margin-top: 8px; }
.os-ledger-gap-days__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  list-style: none;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--accent);
}
.os-ledger-gap-days__toggle::-webkit-details-marker { display: none; }
.os-ledger-gap-days__toggle::marker { content: ""; }
.os-ledger-gap-days__chevron { transition: transform .15s ease; }
.os-ledger-gap-days[open] .os-ledger-gap-days__chevron { transform: rotate(180deg); }
.os-ledger-gap-days__list {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 3px;
}
/* Live counted total per currency section (below the denomination rows). */
.os-ledger-drawer__foot {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--hairline);
  display: grid;
  gap: 2px;
}
.os-ledger-drawer__count {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.os-ledger-drawer__ref { color: var(--muted-2); }
:is(.ledger-drawer-count__head, .os-ledger-drawer-count__head) {
  display: grid;
  gap: 2px;
  margin-bottom: 12px;
}
:is(.ledger-drawer, .os-ledger-drawer) {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 640px) {
  :is(.ledger-drawer, .os-ledger-drawer) { grid-template-columns: 1fr; }
}
:is(.ledger-drawer__section, .os-ledger-drawer__section) {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 12px 14px;
}
:is(.ledger-drawer__cur, .os-ledger-drawer__cur) {
  margin-bottom: 10px;
}
:is(.ledger-drawer__rows, .os-ledger-drawer__rows) {
  display: grid;
  gap: 6px;
}
:is(.ledger-drawer__row, .os-ledger-drawer__row) {
  display: grid;
  grid-template-columns: 1fr 84px;
  align-items: center;
  gap: 10px;
  margin: 0;
}
:is(.ledger-drawer__denom, .os-ledger-drawer__denom) {
  color: var(--muted);
}
:is(.ledger-drawer__qty, .os-ledger-drawer__qty) {
  text-align: right;
  padding-top: 6px;
  padding-bottom: 6px;
}
/* #312 — card reconciliation (POS statement vs recorded card) at close. */
:is(.ledger-card-recon, .os-ledger-card-recon) {
  display: grid;
  gap: 12px;
  margin-top: 14px;
}
:is(.ledger-card-recon__head, .os-ledger-card-recon__head) {
  display: grid;
  gap: 2px;
}
:is(.ledger-card-recon__body, .os-ledger-card-recon__body) {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 12px 14px;
}
:is(.ledger-card-recon__recorded, .os-ledger-card-recon__recorded) {
  display: grid;
  gap: 2px;
}
:is(.ledger-card-recon__field, .os-ledger-card-recon__field) {
  display: grid;
  gap: 4px;
  margin: 0;
}
:is(.ledger-card-recon__input-wrap, .os-ledger-card-recon__input-wrap) {
  position: relative;
  display: inline-flex;
  align-items: center;
}
:is(.ledger-card-recon__sym, .os-ledger-card-recon__sym) {
  position: absolute;
  left: 10px;
  color: var(--muted);
  pointer-events: none;
}
:is(.ledger-card-recon__input, .os-ledger-card-recon__input) {
  width: 140px;
  text-align: right;
  padding-left: 22px;
}
:is(.ledger-card-recon__variance, .os-ledger-card-recon__variance) {
  width: 100%;
}
/* Phones (#609 R1): the os-ds page head pins its actions at their natural
   width (flex: 0 0 auto), so the pager + Exports + Close day row ran 13px past
   a 370px viewport once it wrapped under the title. Cap it at the row so the
   actions wrap among themselves instead. */
@media (max-width: 640px) {
  .os-page-head__actions:has(> .os-pager) { max-width: 100%; }
}
/* ═══════════════════════════════════════════════════════════════════════════
   Trip Run v4 — FULL-SCREEN tablet surface (account/dive_trips/run/show, layout
   "run"). Own icon rail + focus bar replace the account sidebar; a full-bleed
   sticky stepper, a centred stage flanked by a (reserved) dive-stops rail + a
   summary tray, and a pinned bottom action bar. Ported from prototype/run.css.
   Server-driven step flow unchanged. Tokens only, no dark:.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ── Shell layout ─────────────────────────────────────────────────────────── */
:is(.run, .os-run) { min-height: 100vh; background: var(--canvas); color: var(--ink); display: flex; }
:is(.run-main, .os-run-main) { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* App rail — the canonical collapsed DiveOS sidebar (diveos/_sidebar), pinned
   to its 64px icon strip. `.diveos-shell` is normally a full-width grid; inside
   the Run flex row we override it to hug just the rail so `.run-main` keeps the
   stage. The collapsed sidebar's own width/styles come from
   `.diveos-shell.is-rail-collapsed .diveos-sidebar` (diveos_shell.css). */
:is(.run-appnav-shell, .os-run-appnav-shell) {
  display: block;      /* not the shell grid — only the rail child sizes it */
  flex: 0 0 auto;
  min-height: 0;
}
/* Focus bar */
:is(.run-focusbar, .os-run-focusbar) {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 28px; min-height: 52px;
  background: var(--surface); border-bottom: 1px solid var(--hairline);
}
:is(.run-focusbar__back, .os-run-focusbar__back) {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-xs); font-weight: 600; color: var(--muted);
  text-decoration: none; padding: 6px 10px; border-radius: var(--radius-md);
  transition: background .12s, color .12s; flex-shrink: 0;
}
:is(.run-focusbar__back, .os-run-focusbar__back):hover { background: var(--hover-warm); color: var(--ink); }
:is(.run-focusbar__back, .os-run-focusbar__back) :is(.lucide, .os-lucide) { color: var(--muted-2); }
:is(.run-focusbar__id, .os-run-focusbar__id) { display: flex; align-items: center; gap: 10px; min-width: 0; }
:is(.run-focusbar__title, .os-run-focusbar__title) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--ink); letter-spacing: -0.01em; }
/* Full-bleed sticky stepper — the stepper itself centred. */
:is(.run-stepper, .os-run-stepper) {
  position: sticky; top: 0; z-index: 15;
  padding: 16px 32px;
  background: var(--canvas); border-bottom: 1px solid var(--hairline);
  overflow-x: auto;
}
:is(.run-stepper__inner, .os-run-stepper__inner) { max-width: 760px; margin: 0 auto; }
/* Content sits below the stepper: reserved rail / centred stage / summary. */
:is(.run-shell, .os-run-shell) {
  flex: 1;
  width: 100%; margin: 0 auto;
  padding: 32px 40px 0;
  display: grid;
  grid-template-columns: 260px minmax(720px, 800px) 300px;
  gap: 48px;
  justify-content: center;
  min-height: 0;
  align-items: start;
}
/* Explicit placement so a hidden rail doesn't let the stage collapse into it. */
:is(.run-rail, .os-run-rail)  { grid-column: 1; background: transparent; padding: 0; display: flex; flex-direction: column; position: sticky; top: var(--run-stick-top, 112px); }
:is(.run-rail, .os-run-rail)[hidden] { display: none; }
/* Comfortable reading cap: when the stage fills a wide tablet (tray dropped,
   grid track 1fr), the log columns stop stretching past --run-stage-cap. No
   effect on desktop, where the track is already ≤800px. */
:is(.run-stage, .os-run-stage) { grid-column: 2; min-width: 0; max-width: var(--run-stage-cap, 1200px); padding: 0 0 120px; }
:is(.run-tray, .os-run-tray)  { grid-column: 3; align-self: start; position: sticky; top: var(--run-stick-top, 112px); }
/* Returned Log-dives surface with >1 dive: the person-first matrix widens with
   each dive-group (4 numeric columns). Reclaim the reserved rail + summary tray
   and let the stage span the full shell width so more dives fit before the
   matrix has to scroll horizontally. Single-dive returns keep the default. */
/* .run-shell.run-shell--wide (0,2,0) beats the base :is(.run-shell,…) (0,1,0). */
.run-shell.run-shell--wide { grid-template-columns: minmax(0, 1fr); justify-content: stretch; max-width: 1680px; }
.run-shell.run-shell--wide :is(.run-rail, .os-run-rail),
.run-shell.run-shell--wide :is(.run-tray, .os-run-tray) { display: none; }
.run-shell.run-shell--wide :is(.run-stage, .os-run-stage) { grid-column: 1; min-width: 0; max-width: none; }
:is(.run-tray__note, .os-run-tray__note) { font-size: var(--text-xs); color: var(--muted); margin: 9px 0 0; line-height: 1.45; }
/* Pinned bottom action bar. */
:is(.run-actionbar, .os-run-actionbar) {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 40px; background: var(--surface);
  border-top: 1px solid var(--hairline); box-shadow: var(--shadow-md);
}
:is(.run-actionbar__lead, .os-run-actionbar__lead) { display: flex; align-items: center; gap: 16px; min-width: 0; }
:is(.run-actionbar__back-form, .os-run-actionbar__back-form) { flex-shrink: 0; }
:is(.run-actionbar__note, .os-run-actionbar__note) { display: flex; align-items: center; gap: 8px; font-size: var(--text-sm); color: var(--muted); min-width: 0; }
:is(.run-actionbar__note, .os-run-actionbar__note) :is(.lucide, .os-lucide) { color: var(--muted-2); }
:is(.run-actionbar__note, .os-run-actionbar__note).is-warn { color: var(--briefing); }
:is(.run-actionbar__note, .os-run-actionbar__note).is-warn :is(.lucide, .os-lucide) { color: var(--briefing); }
:is(.run-actionbar__cta, .os-run-actionbar__cta) { min-width: 180px; justify-content: center; }
:is(.run-actionbar__cta, .os-run-actionbar__cta):disabled { opacity: var(--disabled-opacity); cursor: not-allowed; }
/* Compact mobile stepper twin + condensed trip-context strip — mobile-only
   (shown in the ≤640 block). */
:is(.run-stepper--m, .os-run-stepper--m) { display: none; }
:is(.run-ctx, .os-run-ctx) { display: none; }
:is(.run-ctx__line, .os-run-ctx__line) {
  flex: 1; min-width: 0;
  font-size: var(--text-xs); font-weight: 500; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
:is(.run-ctx__line, .os-run-ctx__line) b { color: var(--ink); font-weight: 600; }
:is(.run-ctx__line, .os-run-ctx__line) .d { color: var(--hairline-strong); margin: 0 5px; }
:is(.run-ctx__hc, .os-run-ctx__hc) {
  flex: 0 0 auto; display: inline-flex; align-items: baseline; gap: 3px;
  font-family: var(--font-mono); font-weight: 600; font-size: var(--text-sm); color: var(--ink);
}
:is(.run-ctx__hc, .os-run-ctx__hc) small { font-size: var(--text-2xs); color: var(--muted); font-weight: 500; }
/* ── Check-in .run-person rows (v4) ─────────────────────────────────────────
   A single hairline-divided LIST of bodies in one surface (single elevation —
   border, never border+shadow). Each row = avatar + name/ref + cert meta + the
   real check control, with an "Aboard" confirmed badge once checked in. No green
   left-inset (anti-slop). Rows are a ≥48pt tap target. */
:is(.run-list, .os-run-list) {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
}
:is(.run-person, .os-run-person) {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 9px 16px;
  min-height: 60px;
  border-top: 1px solid var(--hairline);
}
:is(.run-person, .os-run-person):first-child { border-top: 0; }
:is(.run-person--absent, .os-run-person--absent) { background: var(--surface-alt); }
:is(.run-person__id, .os-run-person__id) { flex: 1; min-width: 0; display: flex; flex-direction: column; }
:is(.run-person__name, .os-run-person__name) {
  font-weight: 600; font-size: var(--text-sm); color: var(--ink);
  display: flex; align-items: center; flex-wrap: wrap; gap: 0;
}
:is(.run-person__ref, .os-run-person__ref) {
  font-family: var(--font-mono); font-weight: 500; font-size: var(--text-xs);
  color: var(--muted); margin-left: 7px;
}
:is(.run-person--absent, .os-run-person--absent) :is(.run-person__name, .os-run-person__name) { color: var(--muted); }
:is(.run-person__cert, .os-run-person__cert) { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
:is(.run-person__aside, .os-run-person__aside) { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* ═══ Dive · log table (PR-D2, prototype run.css §log table) ═══
   One surface card like the check-in list: rows in a single card, hairline-
   separated, grid-aligned columns, green left accent once a diver is back.
   The container clips (overflow hidden) so the accent is a straight strip. */
:is(.run-logtable, .os-run-logtable) {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
:is(.run-logrow, .os-run-logrow) {
  display: grid;
  /* sel · who(+guide) · depth · min · bar · gas · Back */
  grid-template-columns: 26px minmax(120px, 1.4fr) 84px 84px 84px 104px 92px;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-top: 1px solid var(--hairline-2);
}
:is(.run-logrow, .os-run-logrow):first-child { border-top: 0; }
/* Reopen list (#3) — a done stop's divers, each a full-row link that opens the
   detail sheet. Simple flex (name grows) — NOT the 7-col log grid, which
   crushed the name into its 26px checkbox column. */
:is(.run-reopen-list, .os-run-reopen-list) {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  overflow: hidden;
}
:is(.run-reopen-row, .os-run-reopen-row) {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  border-top: 1px solid var(--hairline-2);
  text-decoration: none; color: var(--ink);
  transition: background .12s;
}
:is(.run-reopen-row, .os-run-reopen-row):first-child { border-top: 0; }
:is(.run-reopen-row, .os-run-reopen-row):hover { background: var(--hover-warm); }
:is(.run-reopen-row__who, .os-run-reopen-row__who) { display: flex; flex-direction: column; min-width: 0; flex: 1; }
:is(.run-reopen-row__name, .os-run-reopen-row__name) {
  font-size: var(--text-sm); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
:is(.run-reopen-row__guide, .os-run-reopen-row__guide) { font-size: var(--text-xs); color: var(--muted); }
:is(.run-reopen-row__stat, .os-run-reopen-row__stat) { font-size: var(--text-xs); color: var(--muted); flex-shrink: 0; }
:is(.run-reopen-row__sign, .os-run-reopen-row__sign) {
  display: inline-flex; align-items: center; justify-content: flex-end; gap: 4px;
  min-width: 72px; flex-shrink: 0;
  font-size: var(--text-xs); color: var(--muted-2);
}
:is(.run-reopen-row__sign, .os-run-reopen-row__sign).is-signed { color: var(--confirmed); font-weight: 500; }
:is(.run-logrow, .os-run-logrow).is-back { box-shadow: inset 3px 0 0 var(--confirmed); }
/* Select-all header (trips can have 20+ divers). */
:is(.run-logtable__head, .os-run-logtable__head) {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 14px 10px;
}
:is(.run-logtable__head-lbl, .os-run-logtable__head-lbl) { font-size: var(--text-xs); font-weight: 600; color: var(--muted); }
/* ═══ Dive · titled SIBLING cards (v4 redesign) ═══
   Each dive is its own os-card on the canvas — NO outer wrapper card, and the
   diver list is NOT a second bordered box (single elevation, no card-in-card).
   The card head is a .run-cardhead eyebrow; the body hosts the list flush. */
:is(.run-dcard, .os-run-dcard).os-card { overflow: hidden; }
:is(.run-dcard--active, .os-run-dcard--active).os-card { border-color: var(--hairline-strong); }
:is(.run-dcard--pending, .os-run-dcard--pending).os-card { opacity: .6; }
:is(.run-dcard--pending, .os-run-dcard--pending) :is(.run-cardhead, .os-run-cardhead) { padding-bottom: 20px; }
:is(.run-dcard__lbl, .os-run-dcard__lbl) { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
:is(.run-dcard__lbl, .os-run-dcard__lbl) svg { flex: 0 0 auto; }
:is(.run-dcard__sea, .os-run-dcard__sea) { text-transform: none; letter-spacing: 0; margin-left: 2px; }
/* Done-stop reopen — flush details block below the card head (its own hairline
   band, top-only divider — no nested box). */
:is(.run-dcard__reopen, .os-run-dcard__reopen) { border-top: 1px solid var(--hairline-2, var(--hairline)); margin-top: 14px; }
/* Flat, hairline-divided row list — flush to the card gutter, no border/radius
   box of its own (replaces the old bordered .run-list inside a card). */
:is(.run-divlist, .os-run-divlist) {
  display: flex; flex-direction: column;
  margin-left: calc(var(--space-6) * -1);
  margin-right: calc(var(--space-6) * -1);
  border-top: 1px solid var(--hairline);
}
:is(.run-divlist, .os-run-divlist) > * { padding-left: var(--space-6); padding-right: var(--space-6); }
/* Progress meter — bodies back of the number that splashed. */
:is(.run-meter, .os-run-meter) { display: flex; align-items: center; gap: 11px; padding: 2px 0 4px; }
:is(.run-meter__n, .os-run-meter__n) { font-family: var(--font-mono); font-weight: 600; font-size: var(--text-xs); color: var(--ink); flex: 0 0 auto; }
:is(.run-meter__bar, .os-run-meter__bar) { flex: 1; height: 7px; border-radius: 999px; background: var(--surface-alt); overflow: hidden; }
:is(.run-meter__bar, .os-run-meter__bar) > span { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
/* Diver row — full-row link into the detail drawer (avatar + name/sub left,
   quiet status badge + chevron right). ≥58px tap target. The name/sub never
   wrap mid-word (ellipsis) so the log affordance can't squeeze them. */
:is(.run-diverrow, .os-run-diverrow) {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 16px; min-height: 58px;
  border-top: 1px solid var(--hairline-2, var(--hairline));
  text-decoration: none; color: inherit;
  /* rows are <button>s, which centre text by default */
  text-align: start;
}
:is(.run-diverrow, .os-run-diverrow):first-child { border-top: 0; }
:is(.run-diverrow, .os-run-diverrow):hover { background: var(--hover-warm); }
:is(.run-diverrow, .os-run-diverrow) > .os-avatar { flex: 0 0 auto; }
:is(.run-diverrow__m, .os-run-diverrow__m) { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
:is(.run-diverrow__nm, .os-run-diverrow__nm) { font-weight: 600; font-size: var(--text-sm); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.run-diverrow__sub, .os-run-diverrow__sub) { font-size: var(--text-xs); color: var(--muted-2); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.run-diverrow__sub, .os-run-diverrow__sub).is-active { color: var(--accent-strong, var(--accent)); }
:is(.run-diverrow__guide, .os-run-diverrow__guide) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.run-diverrow, .os-run-diverrow) > .os-badge { flex: 0 0 auto; }
:is(.run-diverrow__chev, .os-run-diverrow__chev) { color: var(--muted-2); display: grid; place-items: center; width: 20px; flex: 0 0 auto; }
/* Mobile (≤640) — give the name/sub the row width. The whole row is the tap
   target opening the drawer (trailing chevron); the status badge is redundant
   with the sub line there, so it drops out to prevent the name being squeezed. */
@media (max-width: 640px) {
  :is(.run-diverrow, .os-run-diverrow) > .os-badge { display: none; }
}
/* Check-in "select all" — a light header row above the guest list. */
:is(.run-checkin-selectall, .os-run-checkin-selectall) { display: flex; align-items: center; gap: 10px; padding: 2px 14px 10px; }
:is(.run-checkin-selectall__lbl, .os-run-checkin-selectall__lbl) { font-size: var(--text-xs); font-weight: 600; color: var(--muted); }
/* Portrait tablet (641–900): the 7-col grid bottoms out at ~640px and crushes
   the last column (Back) off-screen. Switch to a flex row that keeps the DESKTOP
   order (select · name · depth · min · bar · gas · Back) but lets the NAME
   shrink/truncate so the fixed fields — including Back — always fit. The phone
   grid below (≤640) then takes over for the one-line depth/min/bar layout. */
@media (max-width: 900px) {
  :is(.run-logrow, .os-run-logrow) { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
  :is(.run-logrow__who, .os-run-logrow__who) { flex: 1 1 150px; min-width: 0; }
  :is(.run-logrow, .os-run-logrow) :is(.diveos-input, .os-input), :is(.run-logrow, .os-run-logrow) > [data-controller="dv-select"] { flex: 0 1 auto; width: 72px; }
  :is(.run-logrow, .os-run-logrow) > label:last-child { flex: 0 0 auto; }
}
/* Phones (≤640): a two-tier grid so depth/min/bar stay on ONE line instead of
   each stacking full-width. Row 1: checkbox + name. Row 2: the three number
   inputs, equal thirds. Row 3: gas mix (spans) + Back. Column 1 is the checkbox
   gutter. Overrides the ≤900 flex above so the phone layout wins. */
@media (max-width: 640px) {
  :is(.run-logrow, .os-run-logrow) {
    display: grid;
    grid-template-columns: 22px 1fr 1fr 1fr;
    grid-template-areas:
      "chk who who  who"
      "gut dep dur  bar"
      "gut gas gas  back";
    align-items: center;
    -moz-column-gap: 8px;
         column-gap: 8px;
    row-gap: 10px;
    padding: 14px 12px;
  }
  :is(.run-logrow, .os-run-logrow) > :is(.diveos-check, .os-field-check):first-child { grid-area: chk; }
  :is(.run-logrow__who, .os-run-logrow__who) { grid-area: who; min-width: 0; }
  :is(.run-logrow, .os-run-logrow) > input:is(.diveos-input, .os-input):nth-of-type(1) { grid-area: dep; }
  :is(.run-logrow, .os-run-logrow) > input:is(.diveos-input, .os-input):nth-of-type(2) { grid-area: dur; }
  :is(.run-logrow, .os-run-logrow) > input:is(.diveos-input, .os-input):nth-of-type(3) { grid-area: bar; }
  :is(.run-logrow, .os-run-logrow) > [data-controller="dv-select"] { grid-area: gas; min-width: 0; }
  :is(.run-logrow, .os-run-logrow) > :is(.diveos-check, .os-field-check):last-child { grid-area: back; justify-self: end; }
  :is(.run-logrow, .os-run-logrow) > input:is(.diveos-input, .os-input) { width: 100%; text-align: center; }
}
/* ═══ #345 · Return bulk-fill panel ═══
   Group-values bar + rows. The rows reuse .run-logrow but drop the checkbox +
   Back columns, so .run-fillrow overrides the grid template to align
   name · depth · min · bar · gas. */
:is(.run-fillbar, .os-run-fillbar) {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  padding: 14px;
  margin-bottom: 16px;
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
}
:is(.run-fillbar__hint, .os-run-fillbar__hint) { flex: 1 0 100%; margin: 0 0 2px; }
:is(.run-fillbar__inputs, .os-run-fillbar__inputs) {
  display: grid;
  grid-template-columns: repeat(4, minmax(84px, 1fr));
  gap: 10px;
  flex: 1 1 320px;
}
:is(.run-fillbar__apply, .os-run-fillbar__apply) { flex: 0 0 auto; align-self: flex-end; }
:is(.run-fillgroup__label, .os-run-fillgroup__label) { margin: 0 0 6px; }
:is(.run-fillrow, .os-run-fillrow) {
  grid-template-columns: minmax(120px, 1.6fr) 84px 84px 84px 104px;
}
/* Keep the fill rows as a grid at ≤900 (the .run-logrow flex override there is
   for the Back/checkbox layout the fill panel doesn't have). */
@media (max-width: 900px) {
  :is(.run-fillrow, .os-run-fillrow) {
    display: grid;
    grid-template-columns: minmax(110px, 1.4fr) 1fr 1fr 1fr 100px;
  }
}
@media (max-width: 640px) {
  :is(.run-fillbar__inputs, .os-run-fillbar__inputs) { grid-template-columns: repeat(2, 1fr); }
  :is(.run-fillbar__apply, .os-run-fillbar__apply) { flex: 1 0 100%; }
  :is(.run-fillrow, .os-run-fillrow) {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-areas:
      "who who who"
      "dep dur bar"
      "gas gas gas";
  }
  :is(.run-fillrow, .os-run-fillrow) > :is(.run-logrow__who, .os-run-logrow__who) { grid-area: who; }
  :is(.run-fillrow, .os-run-fillrow) > input:is(.diveos-input, .os-input):nth-of-type(1) { grid-area: dep; }
  :is(.run-fillrow, .os-run-fillrow) > input:is(.diveos-input, .os-input):nth-of-type(2) { grid-area: dur; }
  :is(.run-fillrow, .os-run-fillrow) > input:is(.diveos-input, .os-input):nth-of-type(3) { grid-area: bar; }
  :is(.run-fillrow, .os-run-fillrow) > [data-controller="dv-select"] { grid-area: gas; min-width: 0; }
}
/* #345 — Return override disclosure (quiet secondary path). */
:is(.run-return-override, .os-run-return-override) { margin-top: 16px; }
:is(.run-return-override__summary, .os-run-return-override__summary) {
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--muted);
  list-style: none;
}
:is(.run-return-override__summary, .os-run-return-override__summary)::-webkit-details-marker { display: none; }
:is(.run-return-override__summary, .os-run-return-override__summary):hover { color: var(--ink); }
:is(.run-return-override__body, .os-run-return-override__body) {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
}
:is(.run-return-override__body, .os-run-return-override__body) :is(.dv-btn, .os-btn) { align-self: flex-start; }
/* ═══ Dive · left stops rail (desktop ≥1132) ═══
   Detached floating card in the reserved rail column; states mirror the cards.
   The mobile .run-pills below take over ≤1131 (see the media query). */
:is(.run-rail__stopswrap, .os-run-rail__stopswrap) {
  align-self: start;
  width: 100%;
  background: var(--surface);
  border-radius: var(--radius-lg);
  /* Single elevation: --shadow-card already paints a 1px hairline ring
     (0 0 0 1px var(--hairline)), so a separate `border` doubled the edge to
     ~2px — the "thicker borders" defect. One surface = the shadow ring OR a
     border, never both. */
  box-shadow: var(--shadow-card);
  padding: 12px 10px;
}
:is(.run-rail__stops-hd, .os-run-rail__stops-hd) {
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted-2); padding: 4px 8px 8px;
}
:is(.run-rail__stops, .os-run-rail__stops) { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
:is(.run-rail__stop-link, .os-run-rail__stop-link) {
  display: flex; align-items: center; gap: 10px; padding: 9px 8px;
  border-radius: var(--radius-md); text-decoration: none; color: var(--muted);
  transition: background .12s;
}
:is(.run-rail__stop-link, .os-run-rail__stop-link):hover { background: var(--hover-warm); }
:is(.run-rail__stop-num, .os-run-rail__stop-num) {
  width: 24px; height: 24px; flex-shrink: 0; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: 700;
  background: var(--gray-100); color: var(--muted);
}
:is(.run-rail__stop-body, .os-run-rail__stop-body) { display: flex; flex-direction: column; min-width: 0; }
:is(.run-rail__stop-site, .os-run-rail__stop-site) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); white-space: normal; overflow-wrap: anywhere; }
:is(.run-rail__stop-cap, .os-run-rail__stop-cap) { font-size: var(--text-2xs); color: var(--muted); font-family: var(--font-mono); }
:is(.run-rail__stop--done, .os-run-rail__stop--done) :is(.run-rail__stop-num, .os-run-rail__stop-num) { background: var(--confirmed); color: var(--surface); }
:is(.run-rail__stop--active, .os-run-rail__stop--active) :is(.run-rail__stop-link, .os-run-rail__stop-link) { background: var(--accent-soft); }
:is(.run-rail__stop--active, .os-run-rail__stop--active) :is(.run-rail__stop-num, .os-run-rail__stop-num) { background: var(--accent); color: var(--surface); }
:is(.run-rail__stop--active, .os-run-rail__stop--active) :is(.run-rail__stop-site, .os-run-rail__stop-site) { color: var(--accent); }
:is(.run-rail__stop--pending, .os-run-rail__stop--pending) :is(.run-rail__stop-site, .os-run-rail__stop-site) { color: var(--muted); }
/* ═══ Dive · stops pills (mobile ≤1131 — the rail's counterpart) ═══
   Jump-nav over the stop cards: done = confirmed tint + check, current =
   accent fill, pending = muted. Anchors only — no client stop state. */
:is(.run-pills, .os-run-pills) {
  display: none;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
:is(.run-pill, .os-run-pill) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  transition: border-color .12s, color .12s, background .12s;
}
:is(.run-pill, .os-run-pill):hover { border-color: var(--accent-border); color: var(--ink); }
:is(.run-pill, .os-run-pill).is-done { color: var(--confirmed); border-color: var(--confirmed-border); background: var(--confirmed-bg); }
:is(.run-pill, .os-run-pill).is-current { color: var(--surface); background: var(--accent); border-color: var(--accent); }
/* ═══ Responsive — tablet → phone ═════════════════════════════════════════
   ≤1515: drop the summary tray (keep rail + stage).
   ≤1131: drop the rail (single stage); stepper stops sticking.
   ≤640:  mobile Focus Flow — app-bar chrome replaces sidebar/focusbar/stepper. */
@media (max-width: 1515px) {
  /* Tray drops here — hand the freed width to the stage instead of leaving a
     dead margin (tablet full-screen). Rail stays; stage grows to fill. The
     content inside caps at --run-stage-cap so the log columns don't sprawl. */
  :is(.run-tray, .os-run-tray) { display: none; }
  :is(.run-shell, .os-run-shell) { grid-template-columns: 260px minmax(0, 1fr); justify-content: stretch; }
}
@media (min-width: 1132px) and (max-width: 1515px) {
  /* #461 (1132–1515 only; ≤1131 the rail column is already dropped) — the rail is [hidden] on every step except live logging, but its 260px
     column stayed reserved, shoving the stage right. With no rail, collapse to one
     centred column at the desktop reading width (800px, matches ≥1516). Wide
     Return keeps its own full-width rule. */
  :is(.run-shell, .os-run-shell):not(.run-shell--wide):has(> :is(.run-rail, .os-run-rail)[hidden]) {
    grid-template-columns: minmax(0, 800px); justify-content: center;
  }
  :is(.run-shell, .os-run-shell):not(.run-shell--wide):has(> :is(.run-rail, .os-run-rail)[hidden]) > :is(.run-stage, .os-run-stage) { grid-column: 1; }
}
@media (max-width: 1131px) {
  :is(.run-shell, .os-run-shell) { grid-template-columns: minmax(0, 1fr); padding: 24px 32px 0; }
  :is(.run-rail, .os-run-rail) { display: none; }
  :is(.run-stage, .os-run-stage) { grid-column: 1; min-width: 0; }
  /* Keep the stepper pinned on tablet too (it's the primary Run device). The
     earlier `position: static` here unpinned the only sticky header, so the whole
     header scrolled away on a tablet mid-roster. Matches the desktop behaviour:
     focusbar scrolls off, stepper stays put at the top. */
  :is(.run-stepper, .os-run-stepper) { position: sticky; top: 0; }
  /* The rail is gone — the pills become the stops nav. */
  :is(.run-pills, .os-run-pills) { display: flex; }
}
@media (max-width: 640px) {
  :is(.run-appnav-shell, .os-run-appnav-shell) { display: none; }
  :is(.run-shell, .os-run-shell) { grid-template-columns: 1fr; padding: 0; }
  :is(.run-stage, .os-run-stage) { grid-column: 1; padding: 16px 16px 110px; }

  /* Focus bar IS the mobile top bar: back → Plan + trip title + status +
     Emergency. (Mockup shape — no hamburger; back covers app nav.) */
  :is(.run-focusbar, .os-run-focusbar) {
    position: sticky; top: 0; z-index: 40;
    gap: 10px; padding: 10px 12px; min-height: 0;
  }
  /* Back and Emergency share the bar's row, so they share one height: the
     md rung (40), with the back arrow a square icon button (#609 R2). */
  :is(.run-focusbar__back, .os-run-focusbar__back) {
    justify-content: center;
    width: var(--control-h-md); height: var(--control-h-md); padding: 0;
    background: var(--surface-alt); color: var(--muted);
  }
  :is(.run-focusbar__back, .os-run-focusbar__back) span { display: none; }
  :is(.run-focusbar__id, .os-run-focusbar__id) { flex: 1; gap: 8px; }
  :is(.run-focusbar__title, .os-run-focusbar__title) {
    font-size: var(--text-sm);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
  }
  :is(.run-focusbar__emg, .os-run-focusbar__emg) { height: var(--control-h-md); padding: 0 var(--space-3); }

  /* Numbered stepper-with-spine, mobile-sized — replaces the old text tabs.
     Reuses the shared stepper markup + the .run-stepper__inner .absolute spine
     geometry; only the wrapper padding/position shrinks for mobile. */
  :is(.run-stepper, .os-run-stepper) { display: none; }
  :is(.run-stepper--m, .os-run-stepper--m) {
    display: block; position: static; z-index: auto;
    padding: 12px 12px 10px;
    background: var(--surface);
  }
  /* Abbreviated labels stay on one line — no node grows taller than its peers. */
  :is(.run-stepper--m, .os-run-stepper--m) .os-eyebrow { white-space: nowrap; }

  /* Condensed trip-context strip. */
  :is(.run-ctx, .os-run-ctx) {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 14px;
    background: var(--surface-alt); border-bottom: 1px solid var(--hairline);
  }

  :is(.run-actionbar, .os-run-actionbar) { padding: 12px 16px; }
  :is(.run-actionbar__cta, .os-run-actionbar__cta) { min-width: 120px; min-height: 44px; }
}
/* ═══ Dive step — stop pills are the sticky anchor ═══
   On the Dive step the operator scrolls a long per-diver log; keep the stop
   switcher pinned so they can jump between stops without scrolling back up.
   The header (app-bar on mobile, stepper on tablet) scrolls away — ONLY the
   pills stick. This replaces the old app-bar collapse, which changed the
   app-bar's height on scroll and reflowed the document 87px each time it
   toggled (a persistent judder near the top + a flicker loop at the bottom). */
@media (max-width: 1131px) {
  :is(.run--dive, .os-run--dive) :is(.run-stepper, .os-run-stepper) { position: static; } /* tablet: don't pin the header */
  :is(.run--dive, .os-run--dive) :is(.run-pills, .os-run-pills) {
    position: sticky;
    top: 0;
    z-index: 16;
    /* match the surrounding form-section panel + bleed over its 16px side
       padding so the pinned strip spans the panel and masks cards scrolling
       under it. */
    background: var(--surface);
    margin: -2px -16px 14px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--hairline);
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  :is(.run--dive, .os-run--dive) :is(.run-pills, .os-run-pills)::-webkit-scrollbar { display: none; }
  :is(.run--dive, .os-run--dive) :is(.run-pill, .os-run-pill) { flex: 0 0 auto; }
}
@media (max-width: 640px) {
  :is(.run--dive, .os-run--dive) :is(.run-focusbar, .os-run-focusbar) { position: static; } /* mobile: header scrolls away */
}
/* ═══ Dive · per-diver detail sheet (.dv-sheet override) ═══
   Base .dv-sheet (components/sheet.css) provides the overlay + is-open (bottom
   sheet ≤767); here it becomes a right-side drawer ≥768. Big-target guide pills
   + fields + signature for wet-hand on-deck entry. Tokens only. */
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dv-sheet__panel, .os-sheet__panel) { display: flex; flex-direction: column; }
/* The lazy-load turbo-frame sits between the panel and its head/body/foot;
   display:contents lets those be direct flex children so the body's
   flex:1 + internal scroll works and the foot (Save log) stays pinned +
   reachable (else it can push off-screen on a phone with the keyboard up). */
:is(.run-detail-sheet, .os-run-detail-sheet) turbo-frame#run_detail { display: contents; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dv-sheet__body, .os-sheet__body) { flex: 1; overflow-y: auto; }
/* ≥641: full-height right-side drawer. Two fixes over the earlier version:
   - starts at 641 (not 768) so the 641–767 zone is a side drawer, not the base
     sheet's centered floating modal;
   - `max-height: none` overrides the base sheet's `max-height: 90vh` so the
     panel spans the FULL viewport height (it was short by 10vh before). */
@media (min-width: 641px) {
  :is(.run-detail-sheet, .os-run-detail-sheet):is(.dv-sheet, .os-sheet) { align-items: stretch; justify-content: flex-end; }
  :is(.run-detail-sheet, .os-run-detail-sheet) :is(.dv-sheet__panel, .os-sheet__panel) {
    width: 480px; max-width: 92vw; height: 100%; max-height: none; margin: 0;
    border-radius: 0; transform: translateX(100%);
  }
  :is(.run-detail-sheet, .os-run-detail-sheet).is-open :is(.dv-sheet__panel, .os-sheet__panel) { transform: translateX(0); }
  :is(.run-detail-sheet, .os-run-detail-sheet) :is(.dv-sheet__grip, .os-sheet__grip) { display: none; }
}
:is(.run-sheet__diver, .os-run-sheet__diver) { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
:is(.run-sheet__lbl, .os-run-sheet__lbl) { margin: 0 0 8px; color: var(--muted-2); }
:is(.run-sheet__guides, .os-run-sheet__guides) { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 20px; }
:is(.run-sheet__guide, .os-run-sheet__guide) {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline); background: var(--surface);
  font-size: var(--text-sm); font-weight: 600; color: var(--muted); cursor: pointer;
}
:is(.run-sheet__guide, .os-run-sheet__guide):has(input:checked) { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
:is(.run-sheet__fields, .os-run-sheet__fields) { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
:is(.run-field, .os-run-field) { display: block; }
:is(.run-field, .os-run-field) :is(.dv-eyebrow, .os-eyebrow) { display: block; color: var(--muted-2); margin-bottom: 6px; }
:is(.run-field__in, .os-run-field__in) { position: relative; display: flex; align-items: center; }
:is(.run-field__in, .os-run-field__in) input {
  width: 100%; padding: 14px 44px 14px 16px;
  font-size: var(--text-lg); font-weight: 700; font-family: var(--font-mono); text-align: center;
  border: 1px solid var(--input-border); border-radius: var(--radius-lg);
  background: var(--input-bg); color: var(--ink);
}
:is(.run-field__unit, .os-run-field__unit) { position: absolute; right: 16px; color: var(--muted-2); font-family: var(--font-mono); font-size: var(--text-sm); }
:is(.run-sign, .os-run-sign) { margin-top: 20px; }
:is(.run-sign__label, .os-run-sign__label) { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
/* Signature pad fills the drawer's remaining height — a big, stable target for
   a wet, unstable hand signing at sea (was a small ~120px box with dead space
   below it on the full-height drawer). Scoped to the run drawer so the waiver
   reuse of the same signature component is untouched. The signature controller
   uses a ResizeObserver, so the canvas re-measures when it grows. */
:is(.run-detail-sheet, .os-run-detail-sheet) #run-detail-form { display: flex; flex-direction: column; min-height: 100%; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.run-sign, .os-run-sign) { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"] {
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
}
/* The flex rule above is specificity (0,3,0) and would beat the .hidden utility
   (0,1,0), so switching to Type left the draw canvas visible ("Type doesn't
   change to typing"). This restores the toggle: .hidden must win here. */
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.dvsign-pad, .os-dvsign-pad) [data-signature-target="canvasWrapper"].hidden { display: none; }
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.sig-canvas-container, .os-sig-canvas-container) {
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 240px; max-width: none;
}
:is(.run-detail-sheet, .os-run-detail-sheet) :is(.sig-canvas, .os-sig-canvas) { flex: 1 1 auto; min-height: 0; height: auto; display: block; }
:is(.run-logrow__who, .os-run-logrow__who) { text-decoration: none; }
:is(.run-logrow__who, .os-run-logrow__who):hover { color: var(--accent); }
/* ═══ Focus-bar Emergency button + emergency sheet ═══ */
:is(.run-focusbar__emg, .os-run-focusbar__emg) {
  margin-left: auto; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px; border-radius: var(--radius-md);
  border: 1px solid var(--cancelled-border); background: var(--cancelled-bg); color: var(--cancelled);
  font: inherit; font-size: var(--text-xs); font-weight: 600; cursor: pointer;
  transition: border-color .12s, background .12s;
}
:is(.run-focusbar__emg, .os-run-focusbar__emg):hover { border-color: var(--cancelled); }
:is(.run-emg-sheet__head, .os-run-emg-sheet__head) { display: flex; align-items: flex-start; gap: 12px; }
:is(.run-emg-sheet__icon, .os-run-emg-sheet__icon) {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 50%;
  display: grid; place-items: center; background: var(--cancelled-bg); color: var(--cancelled);
}
:is(.run-emg-sheet__stack, .os-run-emg-sheet__stack) { display: flex; flex-direction: column; min-width: 0; }
:is(.run-emg-sheet__eyebrow, .os-run-emg-sheet__eyebrow) { color: var(--cancelled); }
:is(.run-emg-sheet__close, .os-run-emg-sheet__close) { margin-left: auto; }
:is(.run-emg-sheet__lead, .os-run-emg-sheet__lead) { font-size: var(--text-sm); color: var(--muted); margin: 12px 0 16px; line-height: 1.5; }
:is(.run-emg-sheet__optform, .os-run-emg-sheet__optform) { width: 100%; }
:is(.run-emg-sheet__opt, .os-run-emg-sheet__opt) {
  width: 100%; display: flex; align-items: flex-start; gap: 12px; text-align: left;
  padding: 14px; border-radius: var(--radius-lg);
  border: 1px solid var(--hairline); background: var(--surface); cursor: pointer;
  transition: border-color .12s;
}
:is(.run-emg-sheet__opt, .os-run-emg-sheet__opt):hover { border-color: var(--hairline-strong); }
:is(.run-emg-sheet__opt--danger, .os-run-emg-sheet__opt--danger) { border-color: var(--cancelled-border); background: var(--cancelled-bg); color: var(--cancelled); }
:is(.run-emg-sheet__opt-t, .os-run-emg-sheet__opt-t) { display: block; font-weight: 600; font-size: var(--text-sm); }
:is(.run-emg-sheet__opt-s, .os-run-emg-sheet__opt-s) { display: block; font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
:is(.run-emg-sheet__opt--danger, .os-run-emg-sheet__opt--danger) :is(.run-emg-sheet__opt-s, .os-run-emg-sheet__opt-s) { color: var(--cancelled); }
/* ═══ Return · per-stop close-out rows ═══ */
:is(.run-return-stops, .os-run-return-stops) {
  list-style: none; margin: 0; padding: 0;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius-lg); overflow: hidden;
}
:is(.run-return-stop, .os-run-return-stop) {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-top: 1px solid var(--hairline-2);
}
:is(.run-return-stop, .os-run-return-stop):first-child { border-top: 0; }
:is(.run-return-stop__t, .os-run-return-stop__t) { font-size: var(--text-sm); color: var(--ink); }
/* ═══ Stepper spine ═══
   The shared stepper_horizontal partial positions its connector line with
   arbitrary Tailwind (left-[calc(50%+20px)]) that never compiles in this build,
   so the spine vanished. Re-draw it here, scoped to the Run stepper: a 2px rule
   behind the 32px nodes. The partial already colors each DONE node's connector
   `bg-accent` and the rest `bg-hairline`, so the filled run reaches up to +
   including the current step; we only fix geometry. The connector is the sole
   absolutely-positioned child inside each step (the dots are relative z-10). */
:is(.run-stepper__inner, .os-run-stepper__inner) .absolute {
  top: 16px;
  left: calc(50% + 16px);
  right: calc(-50% + 16px);
  width: auto;
  height: 2px;
}
/* ═══ Pre-departure step — titled sibling cards ═══
   Page title on the canvas; Gear / Safety / Headcount each in their own
   os-card (border = single elevation, never border+shadow), titled in-card via
   .os-card__head (top-only padding → no divider under the eyebrow). */
:is(.run-pagehead, .os-run-pagehead) { display: flex; align-items: center; gap: 11px; margin-bottom: 16px; }
:is(.run-pagehead__ic, .os-run-pagehead__ic) {
  width: 34px; height: 34px; border-radius: 9px; flex: 0 0 auto;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center;
}
:is(.run-pagehead__ic, .os-run-pagehead__ic) svg { display: block; }
:is(.run-pagehead, .os-run-pagehead) p { margin: 2px 0 0; }
:is(.run-pcards, .os-run-pcards) { display: flex; flex-direction: column; gap: 16px; }
/* Fitting-body list — flush rows inside the gear card (os-drow supplies the row
   grammar; this just insets it to the card gutter under the head). */
:is(.run-fitlist, .os-run-fitlist) { padding: 6px 16px 2px; }
:is(.run-fitfoot, .os-run-fitfoot) {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 6px; padding: 14px var(--space-6);
  border-top: 1px solid var(--hairline-2, var(--hairline));
}
/* Plain in-card eyebrow header (mockup .mk-gchead): uppercase text label left,
   optional count right — NO leading icon, NO divider. Flows into the card body
   (top-only padding). Used by the Pre-departure sibling cards instead of
   .os-card__head, whose icon slot the mockup section labels don't want. */
:is(.run-cardhead, .os-run-cardhead) {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 20px var(--space-6) 0;
}
/* Depart-headcount grid — the headcount field carries no visible label (the
   card eyebrow titles it), while the override field does. TOP-align the cells
   and give the headcount field a one-line label-height spacer (rendered only
   when the override field is present, see the view) so BOTH cells start with a
   single label line — the two INPUTS then line up regardless of how the hints
   below them wrap (bottom-alignment failed because the hints differ in height).
   Scoped modifier — never touches the shared .field-grid. */
:is(.field-grid, .os-field-grid).run-depart-grid { align-items: start; }
/* The override cell is the 2nd .os-field; drop the stacked-field top margin so
   the grid alignment isn't offset by it. */
:is(.field-grid, .os-field-grid).run-depart-grid .os-field + .os-field { margin-top: 0; }
/* Headcount is a 1–2 digit number — it never needs half the row. Narrow its
   column so the free-text override-reason field (which benefits from length)
   takes the rest. When safety is complete (no override) the lone headcount just
   sits in the narrow first column. */
:is(.field-grid, .os-field-grid).run-depart-grid { grid-template-columns: minmax(0, 8rem) minmax(0, 1fr); }
/* Standalone (non-grid) headcount inputs — e.g. the read-only Return headcount —
   cap to the same narrow width instead of filling the whole card. */
:is(.run-hc-input, .os-run-hc-input) { max-width: 8rem; }
/* ─── Trip Roster tab — v4 (PR-C interactions) ───────────────────────────────
   Ported from the Trip v4 prototype roster surface (pt-* → dv-*): the two
   roster card heads, the guide chips row, the dense diver manifest row-list,
   and the add-diver sheet internals. The multi-select popover itself is the
   global component (components/popover.css). Token discipline only. */
/* ── Card head shared by the Dive guides + Divers cards ─────────────────── */
/* Head aligned to the os-ds form_section header (the interactive-form
   treatment): inline muted icon + title-case heading, NO divider — the
   "form shell" format the roster cards want, distinct from the info_card
   eyebrow used on the read-only Plan cards. Mirrors .form-section__header /
   __icon / __title (os-ds). */
:is(.dv-rcard__head, .os-rcard__head) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 18px 20px 10px;
}
:is(.dv-rcard__ic, .os-rcard__ic) {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; color: var(--muted);
}
:is(.dv-rcard__ttl, .os-rcard__ttl) { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 10px; }
:is(.dv-rcard__ttl, .os-rcard__ttl) h2 {
  font-family: var(--font-display);
  font-weight: 600; font-size: var(--text-md); letter-spacing: -0.01em;
  color: var(--ink); margin: 0;
}
:is(.dv-rcard__count, .os-rcard__count) { font-size: var(--text-sm); color: var(--muted); }
:is(.dv-rcard__count, .os-rcard__count) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.dv-rcard__body, .os-rcard__body) { padding: 18px 20px; }
/* ── Dive guides — chips row + popover anchor ───────────────────────────── */
:is(.dv-guides, .os-guides) {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  position: relative;
}
:is(.dv-guides__empty, .os-guides__empty) { font-size: var(--text-sm); color: var(--muted-2); }
/* The chips partial is stream-replaced wholesale; its wrapper must not break
   the flex row, so it renders as display:contents. */
:is(.dv-guides__chips, .os-guides__chips) { display: contents; }
/* ── Diver manifest — dense borderless row-list ─────────────────────────── */
:is(.dv-divers, .os-divers) { display: flex; flex-direction: column; }
:is(.dv-drow, .os-drow) {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 6px;
  border-top: 1px solid var(--hairline-2, var(--hairline));
  transition: background .12s;
}
:is(.dv-drow, .os-drow):first-child { border-top: 0; }
:is(.dv-drow, .os-drow):hover { background: var(--hover-warm); }
:is(.dv-drow__body, .os-drow__body) { flex: 1; min-width: 0; }
:is(.dv-drow__name, .os-drow__name) {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--text-sm); font-weight: 600; color: var(--ink);
}
:is(.dv-drow__name, .os-drow__name) a { color: inherit; text-decoration: none; }
:is(.dv-drow__name, .os-drow__name) a:hover { color: var(--accent); }
:is(.dv-drow__ref, .os-drow__ref) { font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: 400; color: var(--muted-2); }
:is(.dv-drow__sub, .os-drow__sub) { font-size: var(--text-2xs); color: var(--muted-2); margin-top: 2px; }
:is(.dv-drow__sub, .os-drow__sub) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.dv-drow__act, .os-drow__act) { display: flex; align-items: center; gap: 2px; opacity: 0; transition: opacity .12s; }
:is(.dv-drow, .os-drow):hover :is(.dv-drow__act, .os-drow__act), :is(.dv-drow, .os-drow):focus-within :is(.dv-drow__act, .os-drow__act) { opacity: 1; }
:is(.dv-drow__act, .os-drow__act) form { display: contents; }
:is(.dv-drow__x, .os-drow__x) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex-shrink: 0;
  border: 0; background: none; border-radius: var(--radius-pill);
  color: var(--muted-2); cursor: pointer; transition: background .12s, color .12s;
}
:is(.dv-drow__x, .os-drow__x):hover { background: var(--cancelled-bg); color: var(--cancelled); }
:is(.dv-drow__chev, .os-drow__chev) {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; color: var(--muted-2);
}
:is(.dv-drow__chev, .os-drow__chev):hover { color: var(--ink); }
/* ── Add-diver sheet (dv-sheet) internals ───────────────────────────────── */
:is(.dv-addsheet__title, .os-addsheet__title) {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 2px;
}
:is(.dv-addsheet__title, .os-addsheet__title) h2 { margin: 0; }
:is(.dv-addsheet, .os-addsheet) :is(.dv-sheet__body, .os-sheet__body) { padding-top: 16px; }
:is(.dv-addsearch, .os-addsearch) {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 12px;
  border: 1px solid var(--hairline-strong); border-radius: var(--radius-sm);
  background: var(--surface);
}
:is(.dv-addsearch, .os-addsearch):focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.dv-addsearch, .os-addsearch) :is(.lucide, .os-lucide) { color: var(--muted-2); flex-shrink: 0; }
:is(.dv-addsearch, .os-addsearch) input {
  flex: 1; border: 0; background: none; outline: none;
  font: inherit; font-size: var(--text-sm); color: var(--ink);
}
:is(.dv-addsearch, .os-addsearch) input::-moz-placeholder { color: var(--muted-2); }
:is(.dv-addsearch, .os-addsearch) input::placeholder { color: var(--muted-2); }
:is(.dv-addgroup, .os-addgroup) { margin-top: 14px; }
:is(.dv-addgroup__label, .os-addgroup__label) {
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted-2);
  padding: 0 4px 4px;
}
:is(.dv-addrow, .os-addrow) {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 8px; border-radius: var(--radius-sm);
}
:is(.dv-addrow, .os-addrow):hover { background: var(--hover-warm); }
:is(.dv-addrow__body, .os-addrow__body) { flex: 1; min-width: 0; }
:is(.dv-addrow__name, .os-addrow__name) {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--text-sm); font-weight: 600; color: var(--ink);
}
:is(.dv-addrow__sub, .os-addrow__sub) { font-size: var(--text-2xs); color: var(--muted-2); }
:is(.dv-addrow__sub, .os-addrow__sub) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.dv-addrow, .os-addrow).is-added :is(.dv-addrow__body, .os-addrow__body) { opacity: .5; }
:is(.dv-addrow, .os-addrow) form { display: contents; }
:is(.dv-addsheet__empty, .os-addsheet__empty) { padding: 20px; text-align: center; }
/* ─────────────────────────────────────────────────────────────────────
   Divers index — page-scoped components.

   Ported from the White-label-design benchmark (m3-divers.html). WL is the
   visual source of truth; tokens are remapped to Dive-Management's palette
   (tokens.css). Structure (page-header + dv-toolbar + dv-table-wrap) matches
   the benchmark; status badges use the synced `.status-pill` system, not WL's
   `.dv-badge`.
   ───────────────────────────────────────────────────────────────────── */
/* ── Page header / search box / table wrap ────────────────────────────
   Promoted to the shared component layer (components/header_band.css):
   `.dv-page-head`, `.search-wrap` (+ icon / input / placeholder / focus),
   `.dv-table-wrap` (+ table / thead / tbody / edge padding). Also consumed
   here via those named classes — no longer duplicated. The toolbar / chip /
   divider primitives live in the same shared sheet. */
/* Booking View Toggle Styles */
:is(.booking-view-toggle, .os-booking-view-toggle) {
  margin-bottom: 20px;
  display: flex;
  justify-content: flex-end;
}
:is(.toggle-group, .os-toggle-group) {
  display: flex;
  background-color: #f3f4f6;
  border-radius: 6px;
  padding: 4px;
  border: 1px solid #e5e7eb;
  gap: 4px;
}
:is(.toggle-btn, .os-toggle-btn) {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: none;
  background-color: transparent;
  color: #6b7280;
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.2s ease;
}
:is(.toggle-btn, .os-toggle-btn):hover {
  background-color: #e5e7eb;
  color: #374151;
}
:is(.toggle-btn, .os-toggle-btn):is(.active, .os-active) {
  background-color: white;
  color: #1f2937;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
/* Empty State — canonical definition lives in patterns.css
   (`.empty-state` + `.empty-state__icon` / `.empty-state__message`). The
   bookings empty states render via shared/patterns/_empty_state, so the
   page-scoped override (padding drift + hard-coded #6b7280) was redundant
   and has been removed. */
/* Responsive adjustments */
@media (max-width: 768px) {
  :is(.toggle-group, .os-toggle-group) {
    width: 100%;
    justify-content: space-between;
  }

  :is(.toggle-btn, .os-toggle-btn) {
    flex: 1;
    justify-content: center;
  }
}
/* ════════════════════════════════════════════════════════════════════════
   BOOKING DETAIL — m8 benchmark components (Phase 1)
   Ported from White-label m8-booking-detail.html (+ tokens.css). All rules
   are scoped under `.bk-detail` so they never collide with the global
   `.dv-badge` (trip_workflow.css), `.card-*` (public.css), or other pages.
   Tokens are DM-native (--surface, --hairline, --accent, etc.).
   ════════════════════════════════════════════════════════════════════════ */
/* ── Two-band header tab nav ──────────────────────────────────────────────
   `.page-tabs` / `.page-tab` / `.page-tab-count` were promoted (unscoped) to
   components/header_band.css so every detail header shares one tab component.
   `.bk-tabnav` (below) keeps the booking-specific sticky offset. */
/* ── Progress bar ─────────────────────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.dv-progress, .os-progress) {
  position: relative;
  width: 100%;
  height: 6px;
  background: var(--hairline);
  border-radius: 999px;
  overflow: hidden;
}
:is(.bk-detail, .os-bk-detail) :is(.dv-progress__fill, .os-progress__fill) {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  background: var(--accent);
  border-radius: 999px;
}
/* ── Badge family (scoped — square + dot variants) ────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.dv-badge, .os-badge) {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
}
:is(.bk-detail, .os-bk-detail) :is(.dv-badge-dot, .os-badge-dot) { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
:is(.bk-detail, .os-bk-detail) :is(.dv-badge--square, .os-badge--square) { border-radius: 5px; text-transform: uppercase; letter-spacing: 0.08em; font-size: var(--text-2xs); padding: 3px 8px; }
:is(.bk-detail, .os-bk-detail) :is(.dv-badge--confirmed, .os-badge--confirmed) { background: var(--confirmed-bg); border-color: var(--confirmed-border); color: var(--confirmed); }
:is(.bk-detail, .os-bk-detail) :is(.dv-badge--pending, .os-badge--pending)   { background: var(--pending-bg);   border-color: var(--pending-border);   color: var(--pending); }
:is(.bk-detail, .os-bk-detail) :is(.dv-badge--briefing, .os-badge--briefing)  { background: var(--briefing-bg);  border-color: var(--briefing-border);  color: var(--briefing); }
:is(.bk-detail, .os-bk-detail) :is(.dv-badge--cancelled, .os-badge--cancelled) { background: var(--cancelled-bg); border-color: var(--cancelled-border); color: var(--cancelled); }
/* ── Forked card shell (inline WL version) ────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.card, .os-card) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding: 0;
}
/* Cards hosting a datepicker popover must let it escape the card bounds —
   the default overflow:hidden clips the "Schedule onto" calendar dropdown. */
:is(.bk-detail, .os-bk-detail) :is(.card, .os-card):is(.bk-overflow-visible, .os-bk-overflow-visible) {
  overflow: visible;
}
:is(.bk-detail, .os-bk-detail) :is(.card-head, .os-card-head) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 24px 0;
}
:is(.bk-detail, .os-bk-detail) :is(.card-head-left, .os-card-head-left) {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}
:is(.bk-detail, .os-bk-detail) :is(.card-head-left, .os-card-head-left) i, :is(.bk-detail, .os-bk-detail) :is(.card-head-left, .os-card-head-left) svg { flex-shrink: 0; color: var(--muted-2); }
:is(.bk-detail, .os-bk-detail) :is(.card-head-right, .os-card-head-right) { display: flex; align-items: center; gap: 8px; }
:is(.bk-detail, .os-bk-detail) :is(.card-body, .os-card-body) { padding: 22px 24px; }
/* ── Guest hero card ──────────────────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-card, .os-guest-hero-card) {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  overflow: hidden;
}
:is(.bk-detail, .os-bk-detail) :is(.guest-hero, .os-guest-hero) { display: flex; align-items: flex-start; gap: 16px; padding: 24px 24px 20px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-avatar, .os-guest-hero-avatar) {
  flex-shrink: 0; width: 64px; height: 64px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent) 0%, var(--sky-900) 100%);
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: var(--text-xl); font-weight: 600; font-family: var(--font-display);
}
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-body, .os-guest-hero-body) { flex: 1; min-width: 0; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-name-row, .os-guest-hero-name-row) { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-name, .os-guest-hero-name) { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; color: var(--ink); letter-spacing: -0.02em; line-height: 1.1; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-edit-btn, .os-guest-hero-edit-btn) {
  display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px;
  border-radius: var(--radius); border: 1px solid var(--hairline); background: var(--surface);
  font-size: var(--text-xs); font-weight: 500; color: var(--ink); cursor: pointer; white-space: nowrap;
  flex-shrink: 0; text-decoration: none;
}
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-edit-btn, .os-guest-hero-edit-btn):hover { background: var(--canvas); }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-meta-row, .os-guest-hero-meta-row) { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 6px; font-size: var(--text-sm); color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-country, .os-guest-hero-country) { font-size: var(--text-sm); color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-cert, .os-guest-hero-cert) {
  display: inline-flex; align-items: center; padding: 3px 12px; border-radius: 999px;
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--confirmed-bg); color: var(--confirmed); border: 1px solid var(--confirmed-border);
}
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-contacts, .os-guest-hero-contacts) { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-contact-item, .os-guest-hero-contact-item) {
  display: inline-flex; align-items: center; gap: 5px; font-size: var(--text-sm); color: var(--muted);
  border: 1px solid var(--hairline); border-radius: 999px; padding: 4px 10px; background: var(--surface);
  text-decoration: none;
}
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-contact-item, .os-guest-hero-contact-item):hover { color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-strip, .os-guest-hero-stat-strip) { display: grid; grid-template-columns: repeat(5, 1fr); border-top: 1px solid var(--hairline); margin: 0 24px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-cell, .os-guest-hero-stat-cell) { padding: 14px 16px; border-right: 1px solid var(--hairline); }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-cell, .os-guest-hero-stat-cell):first-child { padding-left: 24px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-cell, .os-guest-hero-stat-cell):last-child { border-right: none; padding-right: 24px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-lbl, .os-guest-hero-stat-lbl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 4px; }
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-val, .os-guest-hero-stat-val) { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 500; color: var(--ink); letter-spacing: -0.02em; display: flex; align-items: baseline; gap: 3px; }
:is(.bk-detail, .os-bk-detail) :is(.stat-month, .os-stat-month) { font-size: var(--text-sm); font-weight: 400; color: var(--muted); font-family: var(--font-sans); }
/* Standalone trip stat band (no guest body above it) — drop the divider
   border/side-margins the integrated variant used; pad inside the card. */
:is(.bk-detail, .os-bk-detail) :is(.guest-hero-stat-strip--standalone, .os-guest-hero-stat-strip--standalone) { border-top: none; margin: 0; padding: 4px 0; }
/* ── Header contact line (Band 1) ─────────────────────────────────────── */
:is(.contact-line, .os-contact-line), :is(.bk-contact-line, .os-bk-contact-line) {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 8px; font-size: var(--text-sm); color: var(--muted);
}
:is(.bk-contact-id, .os-bk-contact-id) { font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
:is(.bk-contact-dot, .os-bk-contact-dot) { font-size: var(--text-xl); line-height: 0; color: var(--muted-2); }
:is(.bk-contact-item, .os-bk-contact-item) { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); }
:is(.bk-contact-item, .os-bk-contact-item) i, :is(.bk-contact-item, .os-bk-contact-item) svg { color: var(--muted-2); flex-shrink: 0; }
:is(.bk-contact-pref, .os-bk-contact-pref) { color: var(--accent); }
:is(.bk-contact-pref, .os-bk-contact-pref) i, :is(.bk-contact-pref, .os-bk-contact-pref) svg { color: var(--accent); }
/* ── Trip-plan strip ──────────────────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-strip, .os-trip-plan-strip) { display: grid; grid-template-columns: 130px 1fr 130px; align-items: center; gap: 20px; margin: 22px 0 22px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-track, .os-trip-plan-track) { position: relative; height: 116px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-rail, .os-trip-plan-rail) { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); height: 2px; background: var(--accent-border); border-radius: 2px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-totals, .os-trip-plan-totals) { position: absolute; left: 50%; top: 6px; transform: translateX(-50%); display: inline-flex; gap: 6px; align-items: center; z-index: 2; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-pill, .os-trip-plan-pill) { display: inline-block; padding: 4px 12px; border-radius: 999px; background: color-mix(in srgb, var(--accent) 8%, var(--surface)); color: var(--accent); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-end, .os-trip-plan-end) { text-align: center; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-end-dot, .os-trip-plan-end-dot) { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 12px; height: 12px; border-radius: 50%; background: var(--accent); z-index: 2; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-end-dot, .os-trip-plan-end-dot):is(.l, .os-l) { left: 0; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-end-dot, .os-trip-plan-end-dot):is(.r, .os-r) { right: 0; left: auto; transform: translate(50%, -50%); }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-pin, .os-trip-plan-pin) { position: absolute; top: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; z-index: 3; }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-pin-mark, .os-trip-plan-pin-mark) { width: 24px; height: 24px; border-radius: 50%; background: var(--surface); border: 1.5px solid var(--accent); display: flex; align-items: center; justify-content: center; color: var(--accent); box-shadow: 0 0 0 3px var(--surface); }
:is(.bk-detail, .os-bk-detail) :is(.trip-plan-pin-label, .os-trip-plan-pin-label) { font-family: var(--font-mono); font-size: 10.5px; color: var(--muted); position: absolute; top: 30px; left: 50%; white-space: nowrap; letter-spacing: 0.04em; transform: translateX(-50%); }
/* trip card def-list rows */
:is(.bk-detail, .os-bk-detail) :is(.lbl, .os-lbl) { font-size: var(--text-2xs); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-2); }
:is(.bk-detail, .os-bk-detail) :is(.tpc-d, .os-tpc-d) { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; color: var(--ink); letter-spacing: -0.018em; margin-top: 4px; line-height: 1; }
:is(.bk-detail, .os-bk-detail) :is(.tpc-ds, .os-tpc-ds) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); margin-top: 4px; }
/* ── Dive-only Trip timeline — D1 dot track (compact; no accommodation) ──
   logged dive = filled accent dot, upcoming = outline. Single dive collapses
   to a one-liner. Many dives collapse onto the dot row. */
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-solo, .os-trip-dive-solo) { display: flex; align-items: center; gap: 10px; padding: 6px 0 2px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-solo, .os-trip-dive-solo) :is(.dot, .os-dot) { width: 11px; height: 11px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); flex-shrink: 0; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-solo, .os-trip-dive-solo) :is(.dot, .os-dot):is(.done, .os-done) { background: var(--accent); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-solo, .os-trip-dive-solo) :is(.dot, .os-dot):is(.today, .os-today) { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-solo, .os-trip-dive-solo) :is(.t, .os-t) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-solo, .os-trip-dive-solo) :is(.s, .os-s) { font-size: var(--text-xs); color: var(--muted); font-family: var(--font-mono); margin-left: auto; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive, .os-trip-dive) { padding: 4px 0 2px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-h, .os-trip-dive-h) { display: flex; align-items: baseline; gap: 7px; margin-bottom: 12px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-h, .os-trip-dive-h) :is(.n, .os-n) { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-h, .os-trip-dive-h) :is(.l, .os-l) { font-size: var(--text-xs); color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-h, .os-trip-dive-h) :is(.r, .os-r) { margin-left: auto; font-size: 10.5px; font-family: var(--font-mono); color: var(--muted-2); text-transform: uppercase; letter-spacing: 0.05em; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-track, .os-trip-dive-track) { position: relative; height: 13px; margin: 6px 5px 0; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-line, .os-trip-dive-line) { position: absolute; left: 5px; right: 5px; top: 50%; height: 2px; background: var(--accent-border); transform: translateY(-50%); border-radius: 2px; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dots, .os-trip-dive-dots) { position: relative; display: flex; justify-content: space-between; align-items: center; height: 100%; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dot, .os-trip-dive-dot) { width: 11px; height: 11px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); box-shadow: 0 0 0 3px var(--surface); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dot, .os-trip-dive-dot):is(.done, .os-done) { background: var(--accent); }
/* Today = current dive: filled accent + a soft accent halo so "now" reads
   distinctly from past (solid) and future (empty). #26 state coloring. */
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dot, .os-trip-dive-dot):is(.today, .os-today) { background: var(--accent); box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--accent-soft); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-ends, .os-trip-dive-ends) { display: flex; justify-content: space-between; gap: 8px; margin-top: 9px; font-size: var(--text-xs); color: var(--muted); font-family: var(--font-mono); }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-ends, .os-trip-dive-ends) :is(.e, .os-e) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-ends, .os-trip-dive-ends) :is(.e, .os-e):is(.r, .os-r) { text-align: right; }
/* dive dot — hover tooltip: date (+ site when assigned) */
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dot, .os-trip-dive-dot) { position: relative; cursor: default; }
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dot, .os-trip-dive-dot):hover::after {
  content: attr(data-tip); position: absolute; bottom: 19px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: #fff; font-size: var(--text-xs); font-family: var(--font-mono);
  padding: 4px 8px; border-radius: 6px; white-space: nowrap; z-index: 30;
  box-shadow: 0 2px 8px rgba(17, 24, 39, 0.18); pointer-events: none;
}
:is(.bk-detail, .os-bk-detail) :is(.trip-dive-dot, .os-trip-dive-dot):hover::before {
  content: ""; position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
  border: 4px solid transparent; border-top-color: var(--ink); z-index: 30; pointer-events: none;
}
/* Booking-detail tab nav pins to the top on scroll (the identity band above
   scrolls away under it), so the tabs stay reachable on long panels. */
:is(.bk-tabnav, .os-bk-tabnav) { position: sticky; top: 0; z-index: 20; }
:is(.bk-detail, .os-bk-detail) :is(.dl-grid, .os-dl-grid) { display: grid; gap: 0; }
:is(.bk-detail, .os-bk-detail) :is(.dl-row-item, .os-dl-row-item) { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--hairline); font-size: var(--text-sm); }
:is(.bk-detail, .os-bk-detail) :is(.dl-row-item, .os-dl-row-item):last-child { border-bottom: none; }
:is(.bk-detail, .os-bk-detail) :is(.dl-row-item, .os-dl-row-item) dt { color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.dl-row-item, .os-dl-row-item) dd { color: var(--ink); font-weight: 500; text-align: right; margin: 0; }
/* ── Waivers & Documents rows ─────────────────────────────────────────── */
/* The row box, avatar, info/name/meta are the shared `.os-profile-row`
   component (os-ds v1.3.0, @imported from application.css). The local copy —
   `.bk-detail .waiver-diver-row` and its avatar/info/name/cert children — was
   deleted when the gem component was adopted; do NOT reintroduce it.
   What stays local below is the DiveOS-specific part: the `.dv-waiver-row`
   hook (is-last + the inline QR share wrap) and the waiver status vocabulary
   (`.waiver-badges` grid, `.wv-*`, `.waiver-send-link`). */
:is(.bk-detail, .os-bk-detail) .dv-waiver-row.is-last { border-bottom: none; }
:is(.bk-detail, .os-bk-detail) :is(.waiver-send-link, .os-waiver-send-link) { font-size: var(--text-xs); color: var(--accent); font-weight: 500; background: none; border: none; cursor: pointer; display: flex; align-items: center; gap: 4px; text-decoration: none; white-space: nowrap; }
/* Plan 003 — per-diver "Fit gear" action, separated from the waiver column. */
:is(.bk-detail, .os-bk-detail) :is(.waiver-fit-link, .os-waiver-fit-link) { flex-shrink: 0; margin-left: 4px; padding-left: 12px; border-left: 1px solid var(--hairline); white-space: nowrap; }
/* Two aligned columns inside .waiver-badges: status pill + trailing slot.
   Grid (not flex) so every row's columns snap to the same widths regardless
   of badge text length ("Signed" vs "Valid waiver on file" vs "Not signed"). */
:is(.bk-detail, .os-bk-detail) :is(.waiver-badges, .os-waiver-badges) { display: grid; grid-template-columns: 158px minmax(96px, max-content); align-items: center; gap: 0; flex-shrink: 0; }
:is(.bk-detail, .os-bk-detail) :is(.wv-status, .os-wv-status) { display: flex; justify-content: flex-end; }
:is(.bk-detail, .os-bk-detail) :is(.wv-trail, .os-wv-trail) { display: flex; align-items: center; justify-content: flex-end; padding-left: 8px; }
:is(.bk-detail, .os-bk-detail) :is(.wv-date, .os-wv-date) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); white-space: nowrap; }
/* No-email hint when a diver can't be emailed (share the QR/copy instead). #35 */
:is(.bk-detail, .os-bk-detail) :is(.waiver-no-email, .os-waiver-no-email) { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); color: var(--muted-2); white-space: nowrap; }
/* The inline QR/copy share (shared/waivers/_waiver_share) wraps to a full-width
   second line under the diver, indented past the 32px avatar + 12px gap. #35 */
:is(.bk-detail, .os-bk-detail) .dv-waiver-row { flex-wrap: wrap; }
:is(.bk-detail, .os-bk-detail) .dv-waiver-row > :is(.wv-share, .os-wv-share) { flex-basis: 100%; margin-left: 44px; }
/* ── Right rail: Balance card ─────────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.balance-card, .os-balance-card) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); overflow: hidden; }
:is(.bk-detail, .os-bk-detail) :is(.balance-head, .os-balance-head) { display: flex; align-items: center; justify-content: space-between; padding: 22px 20px 10px; }
:is(.bk-detail, .os-bk-detail) :is(.balance-head-label, .os-balance-head-label) { display: flex; align-items: center; gap: 6px; font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.balance-paid-pct, .os-balance-paid-pct) { font-size: var(--text-xs); font-weight: 500; color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.balance-body, .os-balance-body) { padding: 0 20px 20px; }
:is(.bk-detail, .os-bk-detail) :is(.balance-amount, .os-balance-amount) { display: flex; align-items: baseline; gap: 2px; margin-bottom: 12px; }
:is(.bk-detail, .os-bk-detail) :is(.balance-dollars, .os-balance-dollars) { font-family: var(--font-display); font-size: 36px; font-weight: 500; color: var(--ink); letter-spacing: -0.03em; line-height: 1; }
:is(.bk-detail, .os-bk-detail) :is(.balance-cents, .os-balance-cents) { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 500; color: var(--muted); letter-spacing: -0.02em; }
:is(.bk-detail, .os-bk-detail) :is(.balance-due, .os-balance-due) { font-size: var(--text-sm); color: var(--muted); margin-left: 6px; }
:is(.bk-detail, .os-bk-detail) :is(.balance-sub, .os-balance-sub) { display: flex; justify-content: space-between; font-size: var(--text-xs); color: var(--muted); margin-bottom: 16px; margin-top: 12px; }
:is(.bk-detail, .os-bk-detail) :is(.balance-sub, .os-balance-sub) span:first-child { color: var(--accent); font-weight: 500; }
:is(.bk-detail, .os-bk-detail) :is(.balance-cta, .os-balance-cta) { display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%; height: 38px; border-radius: var(--radius); background: var(--accent); color: #fff; font-size: var(--text-sm); font-weight: 600; border: none; cursor: pointer; text-decoration: none; }
:is(.bk-detail, .os-bk-detail) :is(.balance-cta, .os-balance-cta):hover { background: var(--accent-strong); }
/* ── Right rail: Booking Summary grid ─────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-grid, .os-bk-sum-grid) { display: grid; grid-template-columns: 1fr 1fr; }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-cell, .os-bk-sum-cell) { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-right: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); border-top: 1px solid var(--hairline); }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-cell, .os-bk-sum-cell):nth-child(even) { border-right: none; }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-cell, .os-bk-sum-cell):nth-child(n+3) { border-bottom: none; }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-cell, .os-bk-sum-cell):nth-child(-n+2) { border-top: none; }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-icon, .os-bk-sum-icon) { width: 32px; height: 32px; border-radius: var(--radius); background: var(--sky-100); display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--accent); }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-body, .os-bk-sum-body) { display: flex; flex-direction: column; gap: 3px; }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-lbl, .os-bk-sum-lbl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-2); }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-val, .os-bk-sum-val) { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 500; color: var(--ink); letter-spacing: -0.02em; line-height: 1; }
:is(.bk-detail, .os-bk-detail) :is(.bk-sum-val, .os-bk-sum-val).is-text { font-size: var(--text-md); font-weight: 500; letter-spacing: -0.02em; }
/* ── Right rail: Access & Sharing toggles ─────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.sharing-row, .os-sharing-row) { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--hairline); }
:is(.bk-detail, .os-bk-detail) :is(.sharing-row, .os-sharing-row):last-child { border-bottom: none; }
:is(.bk-detail, .os-bk-detail) :is(.sharing-label, .os-sharing-label) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.sharing-desc, .os-sharing-desc) { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
/* .dv-toggle removed (#16) — booking toggles now use shared/components/_toggle_switch. */
/* ════════════════════════════════════════════════════════════════════════
   BOOKING DETAIL — m8 benchmark components (Phase 2 — tab left columns)
   Invoices (inv-acc accordion + line-items table + fin totals).
   Ported 1:1 from design/booking-detail branch. All scoped under `.bk-detail`.
   ════════════════════════════════════════════════════════════════════════ */
/* ── Invoices: accordion ──────────────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.inv-acc, .os-inv-acc) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); overflow: hidden; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-header, .os-inv-acc-header) { display: flex; align-items: center; gap: 10px; padding: 14px 18px; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; user-select: none; transition: background 0.1s; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-header, .os-inv-acc-header):hover { background: var(--canvas); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-chevron, .os-inv-acc-chevron) { color: var(--muted-2); flex-shrink: 0; transition: transform 0.2s ease; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc, .os-inv-acc).is-open :is(.inv-acc-chevron, .os-inv-acc-chevron) { transform: rotate(0deg); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc, .os-inv-acc):not(.is-open) :is(.inv-acc-chevron, .os-inv-acc-chevron) { transform: rotate(-90deg); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-id, .os-inv-acc-id) { font-size: var(--text-sm); font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-sep, .os-inv-acc-sep) { color: var(--muted-2); font-size: var(--text-xs); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-date, .os-inv-acc-date) { font-size: var(--text-xs); color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-spacer, .os-inv-acc-spacer) { flex: 1; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-total, .os-inv-acc-total) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
/* Phones: number · type · date · status · total don't fit one line; wrap
   (each part whole) instead of squeezing the date and clipping the total. */
@media (max-width: 640px) {
  :is(.bk-detail, .os-bk-detail) :is(.inv-acc-header, .os-inv-acc-header) { flex-wrap: wrap; row-gap: var(--space-1); }
  :is(.bk-detail, .os-bk-detail) :is(.inv-acc-header, .os-inv-acc-header) > * { white-space: nowrap; }
  :is(.bk-detail, .os-bk-detail) :is(.inv-acc-total, .os-inv-acc-total) { margin-left: auto; }
  /* The gap separates the parts; a "·" could otherwise start or end a line. */
  :is(.bk-detail, .os-bk-detail) :is(.inv-acc-sep, .os-inv-acc-sep, .inv-acc-spacer, .os-inv-acc-spacer) { display: none; }
}
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-body, .os-inv-acc-body) { display: none; border-top: 1px solid var(--hairline); }
/* Phones: the Invoices tab reads as cards, not tables (muf, !656).
   Line items: the gem's stacked table gave every line a tall label/value card
   (Unit / Qty / Total rows). Each line is a compact row instead — description,
   then "2 × $90.00" with the line total on the right; Remove (drafts) under it.
   Payments: each payment row becomes a card — amount + status, method +
   reference, date + Refund — and the footer reads "Total received … $540". */
@media (max-width: 640px) {
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack { padding: 0 var(--space-4); }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody tr {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    -moz-column-gap: var(--space-1);
         column-gap: var(--space-1);
    row-gap: var(--space-1);
    align-items: baseline;
    padding: var(--space-3) 0;
    border: 0;
    border-top: 1px solid var(--hairline);
    border-radius: 0;
    background: transparent;
  }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody tr:first-child { border-top: 0; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody tr + tr { margin-top: 0; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td { display: block; padding: 0; text-align: left; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td::before { content: none; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(1) { grid-column: 1 / -1; font-weight: 600; padding-bottom: 0; border-bottom: 0; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(3) { grid-row: 2; grid-column: 1; color: var(--muted); font-weight: 400; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(3)::after { content: " ×"; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(2) { grid-row: 2; grid-column: 2; color: var(--muted); font-weight: 400; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(4) { grid-row: 2; grid-column: 4; text-align: right; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(5) { grid-column: 1 / -1; text-align: right; }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td:nth-child(5) button { min-height: var(--control-h-touch); }
  :is(.bk-detail, .os-bk-detail) .inv-table-wrap.os-table-wrap--stack tbody td.inv-empty { font-weight: 400; color: var(--muted); }

  :is(.bk-detail, .os-bk-detail) .bk-pay-table { border: 0; border-radius: 0; overflow: visible; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table :is(table, tbody, tfoot) { display: block; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table thead { display: none; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody { display: flex; flex-direction: column; gap: var(--space-3); }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "amount status" "method method" "date action";
    -moz-column-gap: var(--space-3);
         column-gap: var(--space-3);
    row-gap: var(--space-1);
    align-items: center;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    background: var(--surface);
  }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td { padding: 0; text-align: left; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(1) { grid-area: date; color: var(--muted); font-size: var(--text-xs); }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(2) { grid-area: method; font-size: var(--text-xs); color: var(--muted); }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(2) .os-table__sub { display: inline; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(2) .os-table__sub::before { content: " · "; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(3) { grid-area: status; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(4) { grid-area: amount; font-size: var(--text-lg); font-weight: 600; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(5) { grid-area: action; text-align: right; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tbody > tr > td:nth-child(5) :is(button, a) { min-height: var(--control-h-touch); }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tfoot { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--hairline); background: transparent; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tfoot tr { display: flex; justify-content: space-between; align-items: baseline; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tfoot td { padding: 0; }
  :is(.bk-detail, .os-bk-detail) .bk-pay-table tfoot td:empty { display: none; }
}
:is(.bk-detail, .os-bk-detail) :is(.inv-acc, .os-inv-acc).is-open :is(.inv-acc-body, .os-inv-acc-body) { display: block; }
/* ── Invoices: line-items table ───────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) { overflow-x: auto; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) table { width: 100%; min-width: 100%; border-collapse: collapse; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) thead tr { background: var(--canvas); border-bottom: 1px solid var(--hairline); }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) thead th { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gray-600); padding: 10px 0; text-align: left; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) thead th:first-child { padding-left: 18px; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) thead th:last-child { padding-right: 18px; text-align: right; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) thead th:is(.col-num, .os-col-num) { text-align: right; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) tbody tr { border-bottom: 1px solid var(--hairline-2); }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) tbody tr:last-child { border-bottom: none; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) tbody td { padding: 13px 0; font-size: var(--text-sm); color: var(--ink); vertical-align: middle; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) tbody td:first-child { padding-left: 18px; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) tbody td:last-child { padding-right: 18px; text-align: right; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) :is(.li-desc, .os-li-desc) { font-weight: 500; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) :is(.li-qty, .os-li-qty) { color: var(--muted); font-size: var(--text-xs); text-align: right; font-family: var(--font-mono); }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) :is(.li-unit, .os-li-unit) { color: var(--muted); font-size: var(--text-xs); font-family: var(--font-mono); text-align: right; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) :is(.li-amount, .os-li-amount) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500; text-align: right; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) :is(.li-remove, .os-li-remove) { text-align: right; }
:is(.bk-detail, .os-bk-detail) :is(.inv-table-wrap, .os-inv-table-wrap) :is(.li-desc, .os-li-desc):is(.inv-empty, .os-inv-empty) { color: var(--muted); font-weight: 400; text-align: center; padding: 22px 18px; }
:is(.bk-detail, .os-bk-detail) :is(.inv-li-remove, .os-inv-li-remove) { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); font-weight: 500; color: var(--muted-2); transition: color 0.12s; }
:is(.bk-detail, .os-bk-detail) :is(.inv-li-remove, .os-inv-li-remove):hover { color: var(--cancelled); }
/* ── Invoices: ancillary blocks ───────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.inv-add-form-wrap, .os-inv-add-form-wrap) { padding: 14px 18px 0; }
/* ── Invoices: stacked summary (inside accordion body) ───────────────── */
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) { border-top: 1px solid var(--hairline); padding: 12px 18px 14px; background: var(--surface); margin-top: 14px; }
:is(.bk-detail, .os-bk-detail) :is(.fin-row, .os-fin-row) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 7px 0; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row) + :is(.fin-row, .os-fin-row) { border-top: 1px solid var(--hairline-2); }
:is(.bk-detail, .os-bk-detail) :is(.fin-lbl, .os-fin-lbl) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted-2); }
:is(.bk-detail, .os-bk-detail) :is(.fin-val, .os-fin-val) { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 400; color: var(--muted); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.semantic, .os-semantic) :is(.fin-lbl, .os-fin-lbl) { color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.semantic, .os-semantic) :is(.fin-val, .os-fin-val) { font-size: var(--text-md); font-weight: 500; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.semantic, .os-semantic) :is(.fin-val, .os-fin-val):is(.paid, .os-paid) { color: var(--confirmed); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.semantic, .os-semantic) :is(.fin-val, .os-fin-val):is(.outstanding, .os-outstanding) { color: var(--briefing); font-weight: 600; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.total, .os-total) { padding-top: 11px; }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.total, .os-total) :is(.fin-lbl, .os-fin-lbl) { color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.inv-acc-summary, .os-inv-acc-summary) :is(.fin-row, .os-fin-row):is(.total, .os-total) :is(.fin-val, .os-fin-val) { color: var(--ink); font-size: var(--text-md); font-weight: 600; }
/* ── Invoices: payment method pills + actions ─────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.inv-controls, .os-inv-controls) { padding: 14px 18px; border-top: 1px solid var(--hairline); }
:is(.bk-detail, .os-bk-detail) :is(.inv-controls-label, .os-inv-controls-label) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
:is(.bk-detail, .os-bk-detail) :is(.inv-pm-row, .os-inv-pm-row) { display: flex; flex-wrap: wrap; gap: 8px; }
:is(.bk-detail, .os-bk-detail) :is(.inv-pm-pill, .os-inv-pm-pill) { display: inline-flex; align-items: center; height: 32px; padding: 0 12px; font-size: var(--text-xs); font-weight: 500; border-radius: var(--radius); border: 1px solid var(--hairline); background: var(--surface); color: var(--ink); transition: background 0.12s, border-color 0.12s, color 0.12s; cursor: pointer; }
:is(.bk-detail, .os-bk-detail) :is(.inv-pm-pill, .os-inv-pm-pill):hover { background: var(--canvas); }
:is(.bk-detail, .os-bk-detail) :is(.inv-pm-pill, .os-inv-pm-pill).is-active { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent); }
:is(.bk-detail, .os-bk-detail) :is(.inv-pm-note, .os-inv-pm-note) { margin-top: 8px; font-size: var(--text-xs); color: var(--briefing); }
:is(.bk-detail, .os-bk-detail) :is(.inv-actions, .os-inv-actions) { display: flex; flex-wrap: wrap; gap: 8px; padding: 14px 18px; border-top: 1px solid var(--hairline); }
/* ── Invoices: grand-total fin-card (WL .fin-card--c2r) ────────────────── */
/* Confirmed-green translucent wash (6% fill / 18% lines) + 3px top rule.
   Semantic rows: .paid = green, .outstanding = amber. Total = large + green. */
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) {
  --fin-bg: color-mix(in srgb, var(--confirmed) 6%, transparent);
  --fin-border: color-mix(in srgb, var(--confirmed) 18%, transparent);
  background: var(--fin-bg);
  border: 1px solid var(--fin-border);
  border-top: 3px solid var(--confirmed);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  padding: 18px 20px 16px;
  display: flex; flex-direction: column;
}
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row) + :is(.fin-row, .os-fin-row) { border-top: 1px solid var(--fin-border); }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row) { padding: 10px 0; }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.secondary, .os-secondary) :is(.fin-lbl, .os-fin-lbl) { color: var(--muted-2); }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.secondary, .os-secondary) :is(.fin-val, .os-fin-val) { color: var(--muted); font-size: var(--text-sm); font-weight: 400; }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.semantic, .os-semantic) :is(.fin-lbl, .os-fin-lbl) { color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.semantic, .os-semantic) :is(.fin-val, .os-fin-val) { font-size: var(--text-md); font-weight: 500; }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-val, .os-fin-val):is(.paid, .os-paid) { color: var(--confirmed); }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-val, .os-fin-val):is(.outstanding, .os-outstanding) { color: var(--briefing); font-weight: 600; }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.total, .os-total) { border-top: 1px solid var(--fin-border); margin-top: 4px; padding-top: 14px; }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.total, .os-total) :is(.fin-lbl, .os-fin-lbl) { color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.fin-card--c2r, .os-fin-card--c2r) :is(.fin-row, .os-fin-row):is(.total, .os-total) :is(.fin-val, .os-fin-val) { color: var(--confirmed); font-size: var(--text-2xl); font-weight: 700; }
/* (Admin note: #493 retired the .bk-admin-note lookalike — both booking
   surfaces render the canonical .os-callout--info.) */
/* ── Booking quick-look drawer body — rendered inside the shared
   shared/patterns/_side_panel shell (#58). These rules style ONLY the body
   content (stat row + price breakdown); the panel chrome (width, scrim,
   slide animation, close X) comes from the shared .side-panel / .side-drawer
   CSS. Scoped under .side-panel__body so they never leak onto other
   surfaces. ─────────────────────────────────────────────────────────────── */
:is(.side-panel__body, .os-side-panel__body) :is(.bk-stat-row, .os-bk-stat-row) {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  padding: 2px 0 16px;
  border-bottom: 1px solid var(--hairline);
}
:is(.side-panel__body, .os-side-panel__body) :is(.bk-price-row, .os-bk-price-row) {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  font-size: var(--text-sm);
}
:is(.side-panel__body, .os-side-panel__body) :is(.bk-price-row, .os-bk-price-row) :is(.v, .os-v) { font-variant-numeric: tabular-nums; }
/* Single rule per separation — never two stacked hairlines (WL panel). */
:is(.side-panel__body, .os-side-panel__body) :is(.bk-price-row--rule, .os-bk-price-row--rule) {
  border-top: 1px solid var(--hairline);
  margin-top: 4px;
  padding-top: 8px;
}
/* Front office desk — the day pager at the right of the Bookings tab strip.
   On a touch screen its steps and label take the touch-target height (DF6,
   Fitts's Law); with a mouse it keeps os-pager's 34px so the strip stays one
   slim band, like the arena-ops front office. */
@media (pointer: coarse) {
  .fo-date-tools .os-pager__step { width: var(--control-h-touch); height: var(--control-h-touch); }
  .fo-date-tools .os-pager__date { height: var(--control-h-touch); }
}
/* Front-office desk (Bookings › Arrivals / In-house / …).
   Tokens only — no raw hex, no palette utilities. */
/* A group: its .section-label heading, then the cards or the table. */
.fo-group + .fo-group { margin-top: var(--space-8); }
/* The day pager, in the head actions beside New booking. */
.fo-date-tools {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
/* The pager's date label opens the date picker: the date input lies
   transparent over the label (date-jump controller). */
.fo-date-pick {
  position: relative;
  cursor: pointer;
}
.fo-date-pick:hover { background: var(--accent-soft); }
.fo-date-pick:focus-within { box-shadow: var(--shadow-focus); }
.fo-date-pick__short { display: none; }
.fo-date-pick__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
/* The tab band — the tabs, then (on tabs that have one) the Cards / Table
   toggle at its right end. os-ds stretches a .page-tabs group flush to the
   band; the 64px floor is the toggle's band height, so the band is one height
   on every tab (Reservations, table-only tabs) and never collapses to the text
   height. The tabs shrink and scroll sideways before the toggle wraps. */
.os-page-tools > .fo-tabs.page-tabs {
  flex: 1 1 auto;
  min-width: 0;
}
.fo-tabs > .page-tab { min-height: var(--space-16); }
/* #621 — one toggle on screen. It belongs on the tab band (it switches what's
   under the tabs), which holds tabs + toggle from a 920px pane; below 960px
   (headroom for counts and translations) the tabs need the whole band, so the
   toggle moves up beside New booking. Phones keep it on the band, labels
   dropped (below). The pane is the .os-shell-main query container. */
.fo-view-toggle--head { display: none; }
@media (min-width: 641px) {
  @container (max-width: 959px) {
    .fo-view-toggle--head { display: inline-flex; }
    .fo-view-toggle--tools,
    .fo-tabs ~ .os-spacer { display: none; }
  }
}
/* Phones: the pager collapses to its date chip ("Today", "Sat 18") so it
   fits the head row beside the + action; the chip opens the picker. The
   toggle drops its labels (each option keeps an aria-label). */
@media (max-width: 640px) {
  .fo-date-tools .os-pager__step,
  .fo-date-tools .os-today-tag { display: none; }
  .fo-date-tools .fo-date-pick {
    border: none;
    height: var(--space-10);
    padding: 0 var(--space-3);
  }
  .fo-date-pick__full { display: none; }
  .fo-date-pick__short { display: inline; }
  .fo-tabs ~ .os-view-toggle .os-view-toggle__opt > span { display: none; }
}
/* Phones: seven tabs share the band with the toggle, and a tab clipped at the
   toggle ("Trips") read as cut off rather than scrollable. The tabs fade out at
   their end edge so the clip reads as "more this way"; the end padding lets the
   last tab scroll clear of the fade. Once the strip is scrolled, the start edge
   fades too (scroll-driven: --fo-tabs-fade-start grows from 0 over the first
   stretch of scroll). Browsers without scroll timelines keep the end fade only. */
@property --fo-tabs-fade-start { syntax: "<length>"; inherits: false; initial-value: 0px; }
@keyframes fo-tabs-fade-start {
  from { --fo-tabs-fade-start: 0px; }
  10%, to { --fo-tabs-fade-start: var(--space-10); }
}
@media (max-width: 640px) {
  .fo-tabs {
    --fo-tabs-fade: linear-gradient(var(--fo-tabs-fade-dir, to right), transparent, black var(--fo-tabs-fade-start, 0px), black calc(100% - var(--space-10)), transparent);
    padding-inline-end: var(--space-10);
    -webkit-mask-image: var(--fo-tabs-fade);
    mask-image: var(--fo-tabs-fade);
  }
  /* Only where scroll timelines exist: elsewhere the animation would run as a
     zero-length time animation and hold its end state (a permanent start fade
     over the first tab). */
  @supports (animation-timeline: scroll()) {
    .fo-tabs {
      animation: fo-tabs-fade-start linear both;
      animation-timeline: scroll(self inline);
    }
  }
  [dir="rtl"] .fo-tabs { --fo-tabs-fade-dir: to left; }
  .fo-tabs ~ .os-view-toggle { margin-inline-start: var(--space-2); }
}
/* Desk cards — as many 320px (--width-xs)+ columns as fit; one column on a phone.
   auto-fill keeps a lone card card-sized. */
.fo-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--width-xs), 1fr));
  gap: var(--space-6);
  align-items: stretch;
}
@media (max-width: 639px) {
  .fo-card-grid { grid-template-columns: 1fr; }
}
/* The card — the arena-ops `.hos-card` grammar: eyebrow · name · status
   pills · stay strip · journey, then a tinted balance band. */
.fo-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: box-shadow var(--t-fast, 0.15s) ease, transform var(--t-fast, 0.15s) ease;
}
.fo-card.os-card--interactive:hover {
  background-color: var(--surface);
  box-shadow: 0 0 0 1px var(--accent-border), var(--shadow-md);
  transform: translateY(-2px);
}
.fo-card__in {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: var(--space-4) var(--space-5);
}
.fo-card__eyerow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}
.fo-card__ref {
  min-width: 0;
  font-family: var(--font-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fo-card__pax {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  flex: none;
}
/* The head is the guest's name only — no padding of its own (the card's
   inner padding frames it). */
.fo-card__head {
  padding: 0;
  gap: var(--space-2);
}
.fo-card .os-card__title {
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-md);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
}
.fo-card .os-card__title a { color: var(--ink); text-decoration: none; }
.fo-card:hover .os-card__title a { color: var(--accent); }
.fo-card__chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
/* Stay strip — start → nights → end. */
.fo-dates {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
.fo-dates__end { display: flex; flex-direction: column; gap: 2px; }
.fo-dates__end--r { align-items: flex-end; text-align: right; }
.fo-dates__head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: 2px; }
.fo-dates__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--space-6);
  height: var(--space-6);
  flex: none;
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  color: var(--muted);
}
.fo-dates__icon--in { background: var(--accent-soft); color: var(--accent-strong); }
.fo-dates__day {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.fo-dates__end:first-child .fo-dates__day { color: var(--accent-strong); }
.fo-dates__day--empty { color: var(--muted-2); }
.fo-dates__conn {
  display: flex;
  align-items: center;
  flex: 1;
  gap: var(--space-2);
  min-width: var(--space-10);
}
.fo-dates__line { flex: 1; height: 1px; background: var(--hairline); }
.fo-dates__nights {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: none;
  /* 56px: wide enough that the NIGHTS eyebrow sits inside the circle. */
  width: calc(var(--space-12) + var(--space-2));
  height: calc(var(--space-12) + var(--space-2));
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  line-height: 1;
}
.fo-dates__nights .os-figure { font-size: var(--text-md); font-weight: 600; }
.fo-dates__nights .os-eyebrow { margin-top: var(--space-0-5); letter-spacing: 0.04em; }
/* Journey — Stay → Dives, nodes joined by a rail. */
.fo-journey {
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}
.fo-journey__step {
  position: relative;
  display: flex;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
}
.fo-journey__step:last-child { padding-bottom: 0; }
.fo-journey__step::before {
  content: "";
  position: absolute;
  left: calc((var(--space-8) - 2px) / 2);
  top: var(--space-8);
  bottom: -2px;
  width: 2px;
  background: var(--hairline);
}
.fo-journey__step:last-child::before { display: none; }
.fo-journey__node {
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--space-8);
  height: var(--space-8);
  border: 1.5px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--muted-2);
}
.fo-journey__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding-top: 1px;
}
.fo-journey__value {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
}
.fo-journey__value .os-figure { font-weight: 600; }
/* Balance band — the card's one number, with the action at its right, on
   the accent wash (sky-50), no rule — the tint alone sets it off. */
.fo-card__foot {
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--space-16);
  padding: var(--space-3) var(--space-5);
  background: var(--accent-soft);
}
/* Readiness + diver-apart chips in the table rows. */
.fo-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* Branding settings — asset previews.
   The invoice logo is a light-on-dark mark shown on the invoice PDF's ink
   header tile, so preview it against a matching dark swatch (var(--ink)) rather
   than the white settings card, where a white logo would be invisible. */
:is(.branding-logo-preview, .os-branding-logo-preview) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border-radius: var(--radius-md);
  background: var(--ink);
}
/* Accent colour swatch — a native color input beside the hex field. It sits
   in the field's row, so it takes the field height (46) as a square, not the
   40px it had (#609 R2). */
:is(.branding-swatch, .os-branding-swatch) {
  flex: none;
  width: var(--control-h-field);
  height: var(--control-h-field);
  padding: var(--space-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
}
/* #413 MR 4 — Settings → Waivers builder (design 19A / 20A).
   The document editor needs room for Markdown + preview side by side, so the
   side drawer widens while it holds one. Below 1024px the panes stack behind
   Write / Preview tabs (the waiver-document-editor controller toggles
   .is-hidden-narrow). */
/* Phones keep the shell's full-screen drawer (<640px). */
@media (min-width: 640px) {
  :is(.side-drawer, .os-side-drawer):has(.waiver-doc-editor) {
    width: 1040px;
    max-width: 96vw;
  }
}
.waiver-doc-editor__text {
  font-family: var(--font-mono);
  min-height: 22rem;
}
.waiver-doc-editor__preview {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  padding: var(--space-4);
  max-height: 32rem;
  overflow-y: auto;
}
.waiver-doc-editor__pane.is-hidden-narrow {
  display: none;
}
@media (min-width: 1024px) {
  .waiver-doc-editor__tabs {
    display: none;
  }

  .waiver-doc-editor__panes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-5);
  }

  .waiver-doc-editor__pane.is-hidden-narrow {
    display: block;
  }
}
/* B4.4 (18A) — the preview drawer: the draft in an iframe at phone width
   (390px, framed) or the drawer's full width. */
@media (min-width: 640px) {
  :is(.side-drawer, .os-side-drawer):has(.waiver-preview) {
    width: 1040px;
    max-width: 96vw;
  }
}
.waiver-preview__stage {
  display: flex;
  justify-content: center;
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.waiver-preview__frame {
  display: block;
  height: 72vh;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-lg);
  background: var(--canvas);
}
.waiver-preview__frame--phone {
  width: 390px;
  max-width: 100%;
}
.waiver-preview__frame--desktop {
  width: 100%;
}
/* ============================================================
   account/booking_detail.css — Booking detail Overview redesign.

   Page-scoped components for the redesigned Overview tab: the sky
   "trip card" hero (header + layered waveband + vertical stay+dive
   timeline), the 2×2 booking summary, the paid-in-full / due balance
   card, the access & sharing toggles and the internal note.

   Ported 1:1 from the finalized Design/booking-detail prototype
   (booking_detail_components.css + booking_detail_timeline.css) but
   re-expressed entirely on DM's semantic tokens (var(--*)) — no raw
   Tailwind palette, no dark: variants. All numbers/money are Geist
   Mono (var(--font-mono)); headings are Inter (var(--font-display)).

   Scoped under .bk-detail so it never bleeds into other surfaces.
   ============================================================ */
/* Card body copy sits at the design-system 16px base. */
:is(.bk-detail, .os-bk-detail) :is(.card-body, .os-card-body) { font-size: var(--text-md); }
/* ── Trip card (dive schedule, editorial sky) ────────────── */
/* Special hero card: no card-head title — the sky date band is its title. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip, .os-bd2-trip) { position: relative; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-head, .os-bd2-trip-head) { position: relative; background: var(--sky-50); padding: 28px 24px 18px; overflow: hidden; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
/* NOTE: .diver / .bedart load external SVGs via <img>, so CSS `color`/`fill`
   can't reach them — the colour is baked into the .svg files themselves
   (app/assets/images/diveos/illustrations/{diver,bed}.svg, currently #CFF0FF).
   Edit the SVG to recolour. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-head, .os-bd2-trip-head) :is(.diver, .os-diver) { position: absolute; top: -10px; right: 22px; width: 150px; height: 130px; transform-origin: top right; pointer-events: none; z-index: 1; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-head, .os-bd2-trip-head) :is(.bedart, .os-bedart) { position: absolute; width: 110px; height: 105px; transform-origin: top right; pointer-events: none; z-index: 1; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-art, .os-bd2-art) { display: block; width: 100%; height: 100%; }
/* Hero date title = DM Display/H1 (Inter 28/600, -0.025em). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-title, .os-bd2-trip-title) { position: relative; z-index: 2; font-family: var(--font-display); font-weight: 600; font-size: var(--text-3xl); letter-spacing: -0.025em; color: var(--ink); line-height: 1.2; margin: 0; }
/* Hero subtitle = DM Body/Sub-Copy (Inter 13.5/Text-Muted). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-sub, .os-bd2-trip-sub) { position: relative; z-index: 2; font-size: var(--text-sm); color: var(--muted); margin-top: 8px; }
/* Layered sky waveband — static (locked: wavelength 72 / amplitude 16 /
   line-spacing 10 → height 73px). SVG is fully percent-encoded (no raw
   quotes) so it's valid CSS and never leaks into markup. Sky colours mirror
   tokens.css --sky-200…600 + --sky-100 sea fill. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-waves, .os-bd2-trip-waves) { height: 73px; background-color: var(--sky-50); background-repeat: repeat-x; background-position: center top; background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2772%27%20height%3D%2773%27%20viewBox%3D%270%200%2072%2073%27%3E%3Cpath%20d%3D%27M0%2051%20q18.0%20-16%2036.0%200%20t36.0%200%20V73%20H0%20Z%27%20fill%3D%27%23E0F2FE%27%2F%3E%3Cg%20fill%3D%27none%27%20stroke-width%3D%272.5%27%20stroke-linecap%3D%27round%27%3E%3Cpath%20d%3D%27M0%2011%20q18.0%20-16%2036.0%200%20t36.0%200%27%20stroke%3D%27%23BAE6FD%27%2F%3E%3Cpath%20d%3D%27M0%2021%20q18.0%20-16%2036.0%200%20t36.0%200%27%20stroke%3D%27%237DD3FC%27%2F%3E%3Cpath%20d%3D%27M0%2031%20q18.0%20-16%2036.0%200%20t36.0%200%27%20stroke%3D%27%2338BDF8%27%2F%3E%3Cpath%20d%3D%27M0%2041%20q18.0%20-16%2036.0%200%20t36.0%200%27%20stroke%3D%27%230EA5E9%27%2F%3E%3Cpath%20d%3D%27M0%2051%20q18.0%20-16%2036.0%200%20t36.0%200%27%20stroke%3D%27%230284C7%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-body, .os-bd2-trip-body) { background: var(--sky-100); padding: 18px 18px 32px; display: flex; flex-direction: column; gap: 14px; }
/* lodging room line under the summary (only with a stay) */
/* Lodging line = DM Body/Default (Inter 14) on Text/Secondary. */
:is(.bk-detail, .os-bk-detail) :is(.stay-headroom, .os-stay-headroom) { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: 8px; margin-top: 10px; font-size: var(--text-sm); color: var(--text-secondary); }
:is(.bk-detail, .os-bk-detail) :is(.stay-headroom, .os-stay-headroom) :is(.i, .os-i) { color: var(--accent); display: inline-flex; }
:is(.bk-detail, .os-bk-detail) :is(.stay-headroom, .os-stay-headroom) b { font-weight: 600; color: var(--ink); }
/* empty state when no dives scheduled */
/* Empty state = DM Body/SM (Inter 13). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-trip-empty, .os-bd2-trip-empty) { font-size: var(--text-sm); color: var(--muted-2); padding: 6px 2px; }
/* ── Vertical stay + dive timeline (inside the trip card) ──────
   Inter-row spacing lives on the ROW (padding-bottom), not the card
   margin, so each grid track height == the card height. That lets us
   vertically centre the node/date against the card precisely. The
   connector bar bridges the gap by extending --tl-gap into the next row. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) { --tl-gap: 14px; padding: 2px 0 0; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) { display: grid; grid-template-columns: 48px 44px minmax(0, 1fr); -moz-column-gap: 14px; column-gap: 14px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):not(:last-child) { padding-bottom: var(--tl-gap); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) { text-align: right; line-height: 1; }
/* Date number = DM display stat scale (Inter 22/600, -0.02em — matches .tpc-d / .guest-hero-stat-val). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) :is(.d, .os-d) { display: block; font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl); letter-spacing: -0.02em; color: var(--ink); line-height: 1; }
/* Month = DM Label/Stat-Card scale, in mono (10/600, 0.12em UPPER, Text/Muted). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) :is(.m, .os-m) { display: block; font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-top: 4px; }
/* Weekday = DM Mono/Count (11, tabular). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) :is(.dow, .os-dow) { display: block; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted-2); margin-top: 4px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail) { position: relative; display: flex; justify-content: center; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail)::before { content: ''; position: absolute; left: 50%; transform: translateX(-50%); width: 2px; background: var(--hairline); top: 0; bottom: calc(-1 * var(--tl-gap)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):last-child :is(.rail, .os-rail)::before { bottom: 0; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):only-child :is(.rail, .os-rail)::before { display: none; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.node, .os-node) { position: relative; z-index: 1; width: 40px; height: 40px; border-radius: 50%; background: var(--surface); border: 1.5px solid var(--hairline-strong); display: grid; place-items: center; color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.node, .os-node) svg { display: block; }
/* Node alignment — BASE = TOP: node + date flush with the card's top edge. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail) { align-items: flex-start; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) { padding-top: 13px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):first-child :is(.rail, .os-rail)::before { top: 20px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):last-child :is(.rail, .os-rail)::before { top: 0; height: 20px; bottom: auto; }
/* CENTER: node centred against the card; date gutter anchored to the
   node's TOP edge (height-independent: node half-height = 20px). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail) { align-items: center; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) { align-self: center; padding-top: 0; transform: translateY(calc(50% - 20px)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row):first-child :is(.rail, .os-rail)::before { top: 50%; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row):last-child :is(.rail, .os-rail)::before { top: 0; height: 50%; bottom: auto; }
/* Single-line card (Check-out): centre its node, cap the connector at node centre. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) :is(.stay-tl-row, .os-stay-tl-row):is(.single, .os-single) :is(.rail, .os-rail) { align-items: center; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) :is(.stay-tl-row, .os-stay-tl-row):is(.single, .os-single) :is(.g, .os-g) { align-self: center; padding-top: 0; transform: translateY(calc(50% - 20px)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) :is(.stay-tl-row, .os-stay-tl-row):is(.single, .os-single):last-child :is(.rail, .os-rail)::before { top: 0; height: 50%; bottom: auto; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) :is(.stay-tl-row, .os-stay-tl-row):is(.single, .os-single):first-child :is(.rail, .os-rail)::before { top: 50%; height: auto; bottom: calc(-1 * var(--tl-gap)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):is(.dive, .os-dive) :is(.node, .os-node) { color: var(--accent); border-color: var(--accent-border); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):is(.lodge, .os-lodge) :is(.node, .os-node) { color: var(--accent); border-color: var(--accent-border); background: var(--sky-50); }
/* Mini card = DM card shell (Surface/Base, 1px Border/Hairline, radius-lg). No bespoke
   shadow — DM stat-cards rest on the border alone. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-lg); padding: 13px 18px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row):is(.lodge, .os-lodge) :is(.cardc, .os-cardc) { background: var(--sky-50); border-color: var(--accent-border); }
/* Eyebrow = DM Label/Stat-Card scale in mono (11/600, 0.12em UPPER, Text/Muted). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.ey, .os-ey) { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
/* Card title = DM tab-stat number role (Inter 15/600, -0.01em — the next display
   step below Panel-Title for in-card titling). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.ti, .os-ti) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); letter-spacing: -0.01em; color: var(--ink); margin-top: 5px; }
/* Detail = DM Mono/Numeric scale (Geist Mono 12, Text/Muted-2). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de) { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted-2); margin-top: 5px; }
/* sky-coloured timeline — connector / node ring / card border */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.sky, .os-sky) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail)::before { background: var(--sky-300); }
/* Opaque node interior + a halo that masks the connector line behind the node
   (clean "break in the line"). The halo MUST match the surface the timeline
   sits on: sky-100 inside the Overview trip body (default), or the card surface
   when placed on a plain card (.on-surface, e.g. the Scheduled Dives tab). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.sky, .os-sky) :is(.stay-tl-row, .os-stay-tl-row) :is(.node, .os-node) { border-color: var(--sky-300); background: var(--sky-50); box-shadow: 0 0 0 3px var(--tl-halo, var(--sky-100)); z-index: 2; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.on-surface, .os-on-surface) { --tl-halo: var(--surface); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.sky, .os-sky) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) { border-color: var(--sky-400); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.sky, .os-sky) :is(.stay-tl-row, .os-stay-tl-row):is(.lodge, .os-lodge) :is(.node, .os-node) { border-color: var(--sky-300); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.sky, .os-sky) :is(.stay-tl-row, .os-stay-tl-row):is(.lodge, .os-lodge) :is(.cardc, .os-cardc) { border-color: var(--sky-400); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.sky, .os-sky) :is(.stay-tl-row, .os-stay-tl-row) :is(.g, .os-g) :is(.dow, .os-dow) { color: var(--sky-500); }
/* #512 design pass (A) — the stay's one Edit action sits in a header row above
   the timeline; with no stay, a dashed placeholder bookend holds the button. */
:is(.bk-detail, .os-bk-detail) .stay-tl-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: calc(-1 * var(--space-1)); }
:is(.bk-detail, .os-bk-detail) .stay-tl-head .section-label { margin: 0; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) .stay-tl-row.is-placeholder .cardc { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-2) var(--space-3); background: transparent; border-style: dashed; border-color: var(--sky-300); color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl) .stay-tl-row.is-placeholder .node { color: var(--muted-2); border-style: dashed; }
/* Stateful timeline (Scheduled Dives only — Overview omits .stateful):
   past = logged (green node + check + dimmed card), today = live (accent ring),
   future = default sky. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful) :is(.stay-tl-row, .os-stay-tl-row).is-past :is(.node, .os-node) { border-width: 2px; border-color: var(--confirmed); background: color-mix(in srgb, var(--confirmed) 12%, var(--surface)); color: var(--confirmed); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful) :is(.stay-tl-row, .os-stay-tl-row).is-past :is(.cardc, .os-cardc) { border-color: var(--confirmed-border); background: color-mix(in srgb, var(--confirmed) 4%, var(--surface)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful) :is(.stay-tl-row, .os-stay-tl-row).is-past :is(.g, .os-g) :is(.d, .os-d) { color: var(--muted-2); }
/* accent-light (sky-100) is OPAQUE — accent-soft was 8% alpha, which let the
   connector line show straight through the node. Opaque so the node masks it. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful) :is(.stay-tl-row, .os-stay-tl-row).is-today :is(.node, .os-node) { border-width: 2px; border-color: var(--accent); background: var(--accent-light); color: var(--accent); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful) :is(.stay-tl-row, .os-stay-tl-row).is-today :is(.cardc, .os-cardc) { border-color: var(--accent-border); box-shadow: 0 0 0 1px var(--accent-border); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful) :is(.stay-tl-row, .os-stay-tl-row).is-today :is(.g, .os-g) :is(.dow, .os-dow) { color: var(--accent); font-weight: 600; }
/* Stateful connector — split into an incoming half (::before, above the node)
   and an outgoing half (::after, below the node), divided at the node centre so
   the (opaque) node masks the junction and each LEG takes its SOURCE node's
   state colour. Scoped to .stateful so the Overview trip card is untouched.
   A leg from a PAST node is green: the past row's outgoing + the next row's
   incoming (marked .prev-past) both go green; everything else stays sky. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail)::before, :is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail)::after {
  content: ''; position: absolute; left: 50%; transform: translateX(-50%); width: 2px; background: var(--sky-300); z-index: 0;
}
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail)::before { top: 0; height: auto; bottom: 50%; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row) :is(.rail, .os-rail)::after  { top: 50%; height: auto; bottom: calc(-1 * var(--tl-gap)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row):first-child :is(.rail, .os-rail)::before { display: none; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row):last-child :is(.rail, .os-rail)::after { display: none; }
/* Past leg — desaturated sage: confirmed green cut with gray (not white) so it reads
   muted, not the neon emerald of the raw green ramp. More present than the node fill. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row).is-past :is(.rail, .os-rail)::after { background: color-mix(in srgb, var(--green-700) 38%, var(--gray-300)); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl, .os-stay-tl):is(.stateful, .os-stateful):is(.tl-center, .os-tl-center) :is(.stay-tl-row, .os-stay-tl-row):is(.prev-past, .os-prev-past) :is(.rail, .os-rail)::before { background: color-mix(in srgb, var(--green-700) 38%, var(--gray-300)); }
/* Scheduled Dives card content — TIME is the hero (mono, large), site the
   subtitle, dive # the eyebrow, guide/gas a muted meta line. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) :is(.sched-time, .os-sched-time) { font-family: var(--font-mono); font-size: var(--text-2xl); font-weight: 600; letter-spacing: -0.01em; color: var(--ink); line-height: 1.05; margin-top: 3px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) :is(.ti, .os-ti):is(.site, .os-site) { font-size: var(--text-sm); margin-top: 3px; }
/* Guide/gas trails the site on ONE line — muted mono, middot-separated, so the
   site stays prominent and we don't burn a whole row on the guide. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) :is(.ti, .os-ti):is(.site, .os-site) :is(.site-guide, .os-site-guide) { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-mono); font-weight: 400; font-size: var(--text-xs); color: var(--muted); letter-spacing: 0; vertical-align: baseline; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) :is(.ti, .os-ti):is(.site, .os-site) :is(.site-guide, .os-site-guide)::before { content: "·"; margin-right: 2px; color: var(--muted-2); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) :is(.ti, .os-ti):is(.site, .os-site) :is(.site-guide, .os-site-guide) svg { color: var(--muted-2); flex-shrink: 0; }
/* Card-as-link: no underline, inherit the component's text colours, subtle
   sky hover border to signal it opens the trip. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) a:is(.cardc, .os-cardc) { text-decoration: none; transition: border-color 0.12s ease; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) a:is(.cardc, .os-cardc):hover { border-color: var(--sky-600); }
/* ── 2×2 booking summary ─────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) { display: grid; grid-template-columns: 1fr 1fr; margin-top: 16px; border-top: 1px solid var(--hairline-2); }
/* #493 (muf) — horizontal padding snaps to the card's 24px content inset. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.q, .os-q) { padding: 18px var(--space-6); border-top: 1px solid var(--hairline-2); border-left: 1px solid var(--hairline-2); display: flex; align-items: center; gap: 13px; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.q, .os-q):nth-child(-n+2) { border-top: 0; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.q, .os-q):nth-child(odd) { border-left: 0; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.tile, .os-tile) { width: 40px; height: 40px; border-radius: var(--radius); background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; }
/* Summary label = DM Label/Stat-Card (10/600, 0.12em UPPER, Text/Muted). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.k, .os-k) { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
/* Summary value = DM Mono/Stat-Value (Geist Mono 22/600, 0 tabular, Text/Primary). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.v, .os-v) { font-family: var(--font-mono); font-weight: 600; font-size: var(--text-xl); letter-spacing: 0; color: var(--ink); margin-top: 3px; line-height: 1.05; font-feature-settings: "tnum"; }
/* Non-numeric value = DM tab-stat number (Inter 15/600, -0.01em). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-sum, .os-bd2-sum) :is(.v, .os-v):is(.sm, .os-sm) { font-family: var(--font-sans); font-size: var(--text-md); font-weight: 600; letter-spacing: -0.01em; }
/* ── Balance card (paid-in-full / due) ───────────────────── */
/* Percentage chip = DM Caption (12) emphasized; status colour from semantic tokens. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-pct, .os-bd2-bal-pct) { font-size: var(--text-xs); font-weight: 600; color: var(--confirmed); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-pct, .os-bd2-bal-pct):is(.partial, .os-partial) { color: var(--accent); }
/* Balance hero figure = DM Mono/KPI-Value (Geist Mono 28, -0.02em, tabular). cents step
   down to DM Mono/Stat-Value (22). Label = DM Body/Default (14, Text/Muted). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt) { line-height: 1; font-family: var(--font-mono); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt) :is(.d, .os-d) { font-family: var(--font-mono); font-weight: 600; font-size: var(--text-3xl); letter-spacing: -0.02em; color: var(--ink); font-feature-settings: "tnum"; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt) :is(.cents, .os-cents) { color: var(--muted-2); font-size: var(--text-xl); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt) :is(.lbl, .os-lbl) { font-family: var(--font-sans); font-size: var(--text-sm); color: var(--muted); margin-left: 8px; }
/* Paid in full: the whole amount goes green (the bar stays green too) to
   reinforce the settled state. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt):is(.paid, .os-paid) :is(.d, .os-d), :is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt):is(.paid, .os-paid) :is(.cents, .os-cents), :is(.bk-detail, .os-bk-detail) :is(.bd2-bal-amt, .os-bd2-bal-amt):is(.paid, .os-paid) :is(.lbl, .os-lbl) { color: var(--confirmed); }
/* Paid CTA is a quiet text link (not a button) — there's nothing to collect. */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-link, .os-bd2-bal-link) { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-sm); font-weight: 600; color: var(--accent); text-decoration: none; background: none; border: none; padding: 0; cursor: pointer; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-link, .os-bd2-bal-link):hover { text-decoration: underline; }
/* Progress bar = DM .dv-progress treatment (track Border/Hairline, radius-pill). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-bar, .os-bd2-bal-bar) { height: 8px; border-radius: var(--radius-pill); background: var(--hairline); margin-top: 18px; overflow: hidden; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-bar, .os-bd2-bal-bar) :is(.fill, .os-fill) { height: 100%; border-radius: var(--radius-pill); background: var(--confirmed); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-bar, .os-bd2-bal-bar) :is(.fill, .os-fill):is(.partial, .os-partial) { background: var(--accent); }
/* Paid / of row = DM Body/Sub-Copy (13.5). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-row, .os-bd2-bal-row) { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 12px; font-size: var(--text-sm); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-row, .os-bd2-bal-row) :is(.paid, .os-paid) { font-family: var(--font-mono); font-weight: 600; color: var(--confirmed); white-space: nowrap; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-row, .os-bd2-bal-row) :is(.of, .os-of) { color: var(--muted); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-row, .os-bd2-bal-row) :is(.of, .os-of) :is(.mono, .os-mono) { font-family: var(--font-mono); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-cta, .os-bd2-bal-cta) { margin-top: 16px; }
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-cta, .os-bd2-bal-cta) :is(.dv-btn, .os-btn) { width: 100%; }
/* Empty figure = DM display stat scale (Inter 22/600). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-bal-empty, .os-bd2-bal-empty) { font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl); color: var(--muted-2); margin-top: 14px; }
/* ── Access toggles ──────────────────────────────────────── */
:is(.bk-detail, .os-bk-detail) :is(.bd2-acc-row, .os-bd2-acc-row) { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 13px 0; border-top: 1px solid var(--hairline-2); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-acc-row, .os-bd2-acc-row):first-of-type { border-top: 0; }
/* Toggle title = DM Body/Medium (14/500, Text/Primary). Sub = DM Caption (12, Text/Muted). */
:is(.bk-detail, .os-bk-detail) :is(.bd2-acc-row, .os-bd2-acc-row) :is(.t, .os-t) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.bk-detail, .os-bk-detail) :is(.bd2-acc-row, .os-bd2-acc-row) :is(.s, .os-s) { font-size: var(--text-xs); color: var(--muted); margin-top: 1px; }
/* ── Header: inline Certified badge ──────────────────────── */
:is(.bk-detail-cert, .os-bk-detail-cert) { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border: 1px solid var(--accent-border); border-radius: var(--radius-pill); font-size: var(--text-xs); font-weight: 600; color: var(--accent); background: var(--accent-softer); white-space: nowrap; }
:is(.bk-detail-cert, .os-bk-detail-cert) svg { display: block; }
/* ── Booked-dive card (Step 1) ───────────────────────────── */
/* The dive identity is the title; qty rides alongside it. Schedule lines
   (site · time) are additive enrichment beneath the title. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.cardc, .os-cardc) :is(.ti, .os-ti) :is(.qty, .os-qty) { font-family: var(--font-mono); font-weight: 600; font-size: var(--text-sm); color: var(--muted-2); margin-left: 6px; letter-spacing: 0; }
/* Scheduled enrichment row — attributes grouped with 8px between each.
   Each .de-attr spans one attribute (icon + label); 4px within, 8px between. */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de):is(.sched, .os-sched) { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; color: var(--accent); }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de):is(.sched, .os-sched) + :is(.de, .os-de):is(.sched, .os-sched) { margin-top: 3px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de):is(.sched, .os-sched) :is(.de-attr, .os-de-attr) { display: inline-flex; align-items: center; gap: 4px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de):is(.sched, .os-sched) svg { display: block; flex-shrink: 0; }
/* Not-scheduled state — quieter still (Text/Muted-2, no icon). */
/* "Not scheduled yet" reads as a quiet dashed status tag (clock + label). */
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de):is(.unsched, .os-unsched) { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); font-style: normal; border: 1px dashed var(--hairline-strong); border-radius: var(--radius-pill); padding: 3px 10px; }
:is(.bk-detail, .os-bk-detail) :is(.stay-tl-row, .os-stay-tl-row) :is(.de, .os-de):is(.unsched, .os-unsched) svg { display: block; flex-shrink: 0; }
/* ── Waivers & Documents (WL "Waiver card") ──────────────── */
/* button_to wraps the link in a <form class="inline">;
   `display: contents` removes the form from the layout box tree so the
   <button> becomes a direct grid child of .waiver-badges and sits inline. */
:is(.bk-detail, .os-bk-detail) :is(.waiver-badges, .os-waiver-badges) :is(.inline, .os-inline) { display: contents; }
:is(.bk-detail, .os-bk-detail) :is(.waiver-send-link, .os-waiver-send-link) svg { display: block; }
/* ── Body 2-col grid (tab panels + shared rail) ──────────────
   Desktop: fluid main + fixed 336px rail. Collapses to a single
   column at the 880px breakpoint (timeline first, then the rail's
   Balance / Booking summary / Access & sharing cards). */
:is(.bk-detail-grid, .os-bk-detail-grid) {
  display: grid;
  grid-template-columns: 1fr 336px;
  -moz-column-gap: 24px;
       column-gap: 24px;
  row-gap: 16px;
  align-items: start;
}
/* ── Responsive: narrow pane (≤880px) ────────────────────────
   Body collapses to one column (timeline then rail); tab nav scrolls; the
   header stacks. CONTAINER query, not viewport: the page sits in the
   .diveos-main pane (viewport − 240px sidebar), so it must react to pane
   width. At a ~1024px window the pane is only ~784px — the 4-button action
   row crammed against the title — yet a viewport `max-width:880` never fired. */
@container (max-width: 880px) {
  :is(.bk-detail-grid, .os-bk-detail-grid) { grid-template-columns: 1fr; }

  /* Header stacks: identity block on top, actions wrap below (in flow — the
     FIXED phone bar stays a viewport ≤767 concern so it never spans under the
     sidebar). */
  :is(.dv-page-band, .os-page-band) :is(.bk-hero-row, .os-bk-hero-row) { flex-direction: column; align-items: stretch; gap: 12px; }
  /* Stacked, the identity block's `basis-96` (24rem) becomes a HEIGHT and left
     a ~210px blank under the guest name; size it to its content instead. */
  :is(.bk-hero-row, .os-bk-hero-row) > .basis-96 { flex-basis: auto; }
  :is(.bk-hero-actions, .os-bk-hero-actions) { flex-wrap: wrap; }
  :is(.bk-detail, .os-bk-detail) :is(.bk-contact-line, .os-bk-contact-line) { flex-wrap: wrap; }

  :is(.bk-detail, .os-bk-detail):is(.bk-tabnav, .os-bk-tabnav) :is(.page-tabs, .os-page-tabs), :is(.bk-detail, .os-bk-detail) :is(.bk-tabnav, .os-bk-tabnav) :is(.page-tabs, .os-page-tabs) {
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  :is(.bk-detail, .os-bk-detail):is(.bk-tabnav, .os-bk-tabnav) :is(.page-tabs, .os-page-tabs)::-webkit-scrollbar { display: none; }
  :is(.bk-detail, .os-bk-detail):is(.bk-tabnav, .os-bk-tabnav) :is(.page-tab, .os-page-tab) { flex-shrink: 0; white-space: nowrap; }
}
/* (The tab-nav 72px-top-gap fix now lives generically on `nav.dv-page-band` in
   components/header_band.css — it covers this page's .bk-tabnav too.) */
/* ── Sticky action bar (≤768px — phones + tablet portrait) ────
   The 4 actions leave the header and pin to the bottom of the viewport, thumb-
   reachable while scrolling the long detail. "Send waiver" (primary) fills the
   row; Edit/Share collapse to icon buttons; Cancel stays a compact danger
   button. Mirrors the run/wizard/sheet sticky-footer pattern (safe-area aware).
   768px and up keeps the desktop inline row (tablets included). */
@media (max-width: 767px) {
  /* Header keeps only the identity block; actions move to the bar. */
  :is(.dv-page-band, .os-page-band) :is(.bk-hero-row, .os-bk-hero-row) { flex-direction: column; align-items: stretch; gap: 12px; }
  :is(.bk-detail, .os-bk-detail) :is(.bk-contact-line, .os-bk-contact-line) { flex-wrap: wrap; }

  :is(.bk-hero-actions, .os-bk-hero-actions) {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    background: var(--surface);
    border-top: 1px solid var(--hairline);
    box-shadow: 0 -6px 16px -10px rgba(2, 6, 23, 0.18);
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
    gap: 8px;
    flex-wrap: nowrap;
  }
  /* Drop the removable labels → Edit/Share icon-only, Cancel keeps "Cancel". */
  :is(.bk-hero-actions, .os-bk-hero-actions) :is(.bk-act-label, .os-bk-act-label) { display: none; }
  /* Every button in the bar centres its content (the dv-btn default is
     flex-start, which left-aligns the icon in a square button and the label in
     the wide primary). */
  :is(.bk-hero-actions, .os-bk-hero-actions) :is(.dv-btn, .os-btn) { justify-content: center; }
  /* The bar is [⋯ More] [Mark arrived / departed] [Send waiver]: Cancel, Edit
     and Share live in the More sheet (show.html.erb .bk-more). Every target
     is 44px. */
  :is(.bk-hero-actions, .os-bk-hero-actions) .bk-act--overflow { display: none; }
  :is(.bk-hero-actions, .os-bk-hero-actions) .bk-more { display: flex; flex: 0 0 auto; }
  :is(.bk-hero-actions, .os-bk-hero-actions) .bk-more__btn { width: var(--control-h-touch); padding-left: 0; padding-right: 0; }
  :is(.bk-hero-actions, .os-bk-hero-actions) > :is(.os-btn, .bk-more__btn),
  :is(.bk-hero-actions, .os-bk-hero-actions) :is(.inline, .os-inline) > .os-btn,
  :is(.bk-hero-actions, .os-bk-hero-actions) .bk-more__btn { min-height: var(--control-h-touch); }
  :is(.bk-hero-actions, .os-bk-hero-actions) > [id$="_arrival"], :is(.bk-hero-actions, .os-bk-hero-actions) > [id$="_departure"] { flex: 0 0 auto; }
  /* Cancel (button_to → .inline form): compact danger, natural width. */
  :is(.bk-hero-actions, .os-bk-hero-actions) :is(.inline, .os-inline):not(:is(.bk-primary-action, .os-bk-primary-action)) { flex: 0 0 auto; display: flex; }
  /* Send waiver (primary form): fills the remaining width. */
  :is(.bk-hero-actions, .os-bk-hero-actions) :is(.bk-primary-action, .os-bk-primary-action) { flex: 1 1 auto; display: flex; }
  :is(.bk-hero-actions, .os-bk-hero-actions) :is(.bk-primary-action, .os-bk-primary-action) :is(.dv-btn, .os-btn) { width: 100%; }

  /* Clear the fixed bar so the last content isn't hidden behind it. Scope to the
     content <main> only — `.bk-detail` is ALSO a shared scoping class on the
     contact line + tab nav, so a bare `.bk-detail` padding-bottom would balloon
     those (the header gap bug). */
  main:is(.bk-detail, .os-bk-detail) { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
}
/* ⋯ More sheet (phones only — wider panes keep the inline action row). */
.bk-more { display: none; }
.bk-more__list { display: flex; flex-direction: column; gap: var(--space-2); }
.bk-more__list > .os-btn { justify-content: flex-start; min-height: var(--space-12); }
/* ─── Status dot strip ──────────────────────────────────────────────── */
/* Small row of colored dots inside each day card, one per trip.
   Color maps to the trip's status_presentation key. */
:is(.dv-dot-strip, .os-dot-strip) {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--hairline);
  background: var(--canvas);
}
:is(.dv-status-dot, .os-status-dot) {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="confirmed"] {
  background: var(--status-confirmed-bg);
  border: 1.5px solid var(--status-confirmed-border);
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="briefing"] {
  background: var(--status-briefing-bg);
  border: 1.5px solid var(--status-briefing-border);
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="in_water"] {
  background: var(--status-in-water-bg);
  border: 1.5px solid var(--status-in-water-border);
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="returning"] {
  background: var(--status-returning-bg);
  border: 1.5px solid var(--status-returning-border);
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="completed"] {
  background: var(--status-completed-bg);
  border: 1.5px solid var(--status-completed-border);
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="cancelled"] {
  background: var(--status-cancelled-bg);
  border: 1.5px solid var(--status-cancelled-border);
}
:is(.dv-status-dot, .os-status-dot)[data-status-key="pending"] {
  background: var(--status-pending-bg);
  border: 1.5px solid var(--status-pending-border);
}
/* ─── Stops timeline ─────────────────────────────────────────────────── */
:is(.dv-timeline, .os-timeline) {
  list-style: none;
  margin: 0;
  padding: 0 16px;
}
:is(.dv-timeline__node, .os-timeline__node) {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  min-height: 48px;
}
:is(.dv-timeline__marker-col, .os-timeline__marker-col) {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  width: 24px;
  padding-top: 2px;
}
:is(.dv-timeline__number, .os-timeline__number) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1.5px solid var(--accent-border);
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: 600;
  flex-shrink: 0;
}
/* Board node — stop zero of the itinerary (departure). Muted, not
   accent: it's context, not a logged dive. */
:is(.dv-timeline__number--board, .os-timeline__number--board) {
  background: var(--surface-alt);
  border-color: var(--hairline-strong);
  color: var(--muted);
}
:is(.dv-timeline__line, .os-timeline__line) {
  width: 1.5px;
  flex: 1;
  min-height: 16px;
  background: var(--hairline);
  margin-top: 4px;
}
:is(.dv-timeline__content, .os-timeline__content) {
  flex: 1;
  min-width: 0;
  padding-bottom: 20px;
}
:is(.dv-timeline__node--last, .os-timeline__node--last) :is(.dv-timeline__content, .os-timeline__content) {
  padding-bottom: 8px;
}
:is(.dv-timeline__link, .os-timeline__link) {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-decoration: none;
  color: inherit;
}
:is(.dv-timeline__link, .os-timeline__link):hover :is(.dv-timeline__title, .os-timeline__title) {
  color: var(--accent);
}
:is(.dv-timeline__link, .os-timeline__link):focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
  border-radius: var(--radius-sm, 6px);
}
:is(.dv-timeline__title, .os-timeline__title) {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.4;
  transition: color 0.12s;
}
:is(.dv-timeline__meta, .os-timeline__meta) {
  font-size: var(--text-xs);
  color: var(--muted);
}
/* ─── Divers roster ──────────────────────────────────────────────────── */
:is(.dv-roster, .os-roster) {
  padding: 0 16px;
}
:is(.dv-roster-group, .os-roster-group) {
  margin-bottom: 12px;
}
:is(.dv-roster-group__header, .os-roster-group__header) {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0 6px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 4px;
}
:is(.dv-roster-group__label, .os-roster-group__label) {
  flex: 1;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
:is(.dv-roster-group__count, .os-roster-group__count) {
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}
/* Over the guide's max_diver_ratio — soft warning by design (D2):
   trust the instructor; warn, never block. */
:is(.dv-roster-group__count--over, .os-roster-group__count--over) {
  color: var(--briefing);
}
:is(.dv-roster-group__placeholder, .os-roster-group__placeholder) {
  margin: 0;
  padding: 8px 0;
  font-size: var(--text-xs);
  font-style: italic;
  color: var(--muted-2);
}
:is(.dv-roster-row--draggable, .os-roster-row--draggable) {
  cursor: grab;
}
:is(.dv-roster-row--draggable, .os-roster-row--draggable):active {
  cursor: grabbing;
}
:is(.dv-roster-row, .os-roster-row) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--hairline);
}
:is(.dv-roster-row, .os-roster-row):last-child {
  border-bottom: none;
}
:is(.dv-roster-row__info, .os-roster-row__info) {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
:is(.dv-roster-row__name, .os-roster-row__name) {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
:is(.dv-roster-row__cert, .os-roster-row__cert) {
  font-size: var(--text-xs);
  color: var(--muted);
}
:is(.dv-roster-row__actions, .os-roster-row__actions) {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
:is(.dv-roster-row__checked-in, .os-roster-row__checked-in) {
  color: var(--confirmed);
  display: flex;
}
:is(.dv-roster-guide-form, .os-roster-guide-form) {
  margin: 0;
}
:is(.dv-roster-guide-select, .os-roster-guide-select) {
  height: 28px;
  padding: 0 8px;
  font-size: var(--text-xs);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm, 6px);
  background: var(--surface);
  cursor: pointer;
}
:is(.dv-roster-guide-select, .os-roster-guide-select):hover {
  border-color: var(--hairline-strong);
}
:is(.dv-roster-guide-select, .os-roster-guide-select):focus-visible {
  border-color: var(--input-border-focus);
  box-shadow: 0 0 0 3px var(--focus-ring);
  outline: none;
}
/* 44px touch target on coarse pointers (DESIGN.md kept deviation —
   the ops lead runs this on an iPad at the dock). */
@media (pointer: coarse) {
  :is(.dv-roster-guide-select, .os-roster-guide-select) {
    min-height: 44px;
  }
}
/* ═══ Gear-return board · overall progress (PR-E1, prototype return.css) ═══ */
:is(.dv-return-bar, .os-return-bar) {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  overflow: hidden;
}
:is(.dv-return-bar, .os-return-bar) > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--confirmed);
  transition: width .28s ease;
}
/* ═══ Return tab · full-width ═══
   End-of-trip gear check-in is not planning, so the Return tab drops the
   Plan/Roster right rail and the board spans the full width (matching the
   prototype). Keyed on the Return panel being the visible one (the tab-panel
   controller toggles [hidden]); :has re-evaluates live on tab switch. Only
   engages at lg+ where the two-column rail exists. */
@media (min-width: 1024px) {
  :is(.trip-body, .os-trip-body):has([data-tab="return"][data-tab-panel-target="panel"]:not([hidden])) {
    grid-template-columns: 1fr;
  }
  :is(.trip-body, .os-trip-body):has([data-tab="return"][data-tab-panel-target="panel"]:not([hidden])) :is(.trip-rail, .os-trip-rail) {
    display: none;
  }
}
/* ═══ Plan rail · trip-equipment loadout card (PR-B1, prototype .pt-equip) ═══ */
/* info_card's .os-card clips (overflow:hidden) and exposes no overflow hook; the
   add-item .os-pop popover drops below the card, so relax the wrapper's card
   here rather than forking the os-ds partial. */
.os-equip-card > .os-card { overflow: visible; }
:is(.dv-equip, .os-equip) { display: flex; flex-direction: column; gap: 12px; }
:is(.dv-equip__row, .os-equip__row) { display: flex; align-items: center; gap: 10px; }
:is(.dv-equip__ic, .os-equip__ic) {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  color: var(--muted);
  flex-shrink: 0;
}
:is(.dv-equip__txt, .os-equip__txt) { flex: 1; min-width: 0; }
:is(.dv-equip__name, .os-equip__name) { font-size: var(--text-sm); font-weight: 500; color: var(--ink); }
:is(.dv-equip__sub, .os-equip__sub) { font-size: var(--text-xs); color: var(--muted); }
/* Checklist toggle — a check square at the row end (checked = loaded), same
   visual language as the popover's .dv-optcheck. Replaces the badge-as-button
   (pressing "PENDING" to load read as inverted). */
:is(.dv-equip__check, .os-equip__check) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; flex-shrink: 0;
  border: 1.5px solid var(--hairline-strong); border-radius: 6px;
  background: var(--surface); color: var(--surface);
  cursor: pointer;
  transition: background .1s, border-color .1s, box-shadow .1s;
}
:is(.dv-equip__check, .os-equip__check) :is(.lucide, .os-lucide) { opacity: 0; transition: opacity .1s; }
:is(.dv-equip__check, .os-equip__check):hover { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
:is(.dv-equip__check, .os-equip__check):hover :is(.lucide, .os-lucide) { opacity: .45; color: var(--accent); }
:is(.dv-equip__check, .os-equip__check).is-on { background: var(--confirmed); border-color: var(--confirmed); }
:is(.dv-equip__check, .os-equip__check).is-on :is(.lucide, .os-lucide) { opacity: 1; color: var(--surface); }
:is(.dv-equip__check, .os-equip__check).is-on:hover { box-shadow: 0 0 0 3px var(--confirmed-bg); }
:is(.dv-equip__check--static, .os-equip__check--static) { cursor: default; }
:is(.dv-equip__check--static, .os-equip__check--static):hover { border-color: var(--hairline-strong); box-shadow: none; }
:is(.dv-equip__check--static, .os-equip__check--static):hover :is(.lucide, .os-lucide) { opacity: 0; }
:is(.dv-equip__check--static, .os-equip__check--static).is-on:hover :is(.lucide, .os-lucide) { opacity: 1; color: var(--surface); }
/* Hybrid link: identifier link-out on a linked row's detail line. */
:is(.dv-equip__sub, .os-equip__sub) a { color: var(--muted); text-decoration: none; }
:is(.dv-equip__sub, .os-equip__sub) a:hover { color: var(--accent); }
/* Hover ✕ remove — same affordance as the roster row-list. */
:is(.dv-equip__row, .os-equip__row) form { display: contents; }
:is(.dv-equip__x, .os-equip__x) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex-shrink: 0;
  border: 0; background: none; border-radius: var(--radius-pill);
  color: var(--muted-2); cursor: pointer;
  opacity: 0; transition: opacity .12s, background .12s, color .12s;
}
:is(.dv-equip__row, .os-equip__row):hover :is(.dv-equip__x, .os-equip__x), :is(.dv-equip__row, .os-equip__row):focus-within :is(.dv-equip__x, .os-equip__x) { opacity: 1; }
:is(.dv-equip__x, .os-equip__x):hover { background: var(--cancelled-bg); color: var(--cancelled); }
/* Add-item foot: ghost trigger anchoring the .dv-pop picker. */
:is(.dv-equip__foot, .os-equip__foot) { margin-top: 2px; }
:is(.dv-equip__custom, .os-equip__custom) {
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 12px; border-top: 1px solid var(--hairline);
}
:is(.dv-equip__custom, .os-equip__custom) input {
  border: 1px solid var(--hairline-strong); border-radius: var(--radius-sm);
  background: var(--surface); padding: 7px 10px;
  font: inherit; font-size: var(--text-sm); color: var(--ink);
}
:is(.dv-equip__custom, .os-equip__custom) input::-moz-placeholder { color: var(--muted-2); }
:is(.dv-equip__custom, .os-equip__custom) input::placeholder { color: var(--muted-2); }
:is(.dv-equip__custom-actions, .os-equip__custom-actions) { display: flex; justify-content: flex-end; }
/* ═══ Gear-return board · per-row status menu (PR-E2) ═══
   The status badge doubles as a <details> menu of the row's LEGAL moves.
   No JS: native details; the panel floats over the row. */
:is(.dv-tag-menu, .os-tag-menu) { position: relative; display: inline-flex; }
:is(.dv-tag-menu__summary, .os-tag-menu__summary) {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
:is(.dv-tag-menu__summary, .os-tag-menu__summary)::-webkit-details-marker { display: none; }
:is(.dv-tag-menu__panel, .os-tag-menu__panel) {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 20;
  min-width: 150px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md, 0 4px 12px rgb(0 0 0 / 0.08));
  display: flex;
  flex-direction: column;
  gap: 2px;
}
:is(.dv-tag-menu__opt, .os-tag-menu__opt), :is(.dv-tag-menu__panel, .os-tag-menu__panel) form { display: flex; width: 100%; }
:is(.dv-tag-menu__opt, .os-tag-menu__opt) {
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
:is(.dv-tag-menu__opt, .os-tag-menu__opt):hover { background: var(--surface-alt); }
/* ═══ Generic slim progress bar (PR-B2 — Guest-fitting rail card) ═══ */
:is(.dv-progress, .os-progress) {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  overflow: hidden;
}
:is(.dv-progress, .os-progress) > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width .28s ease;
}
/* ═══ Finalize pre-flight (PR-B3, prototype .pt-finalize/.pt-check) ═══ */
:is(.dv-preflight, .os-preflight) { max-width: 560px; margin: 8px auto 0; }
:is(.dv-preflight__rows, .os-preflight__rows) { display: flex; flex-direction: column; gap: 12px; margin: 24px 0; }
:is(.dv-preflight__row, .os-preflight__row) {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
:is(.dv-preflight__row, .os-preflight__row).is-warn { border-color: var(--pending-border); background: var(--pending-bg); }
:is(.dv-preflight__ic, .os-preflight__ic) {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-soft);
  color: var(--accent);
}
:is(.dv-preflight__row, .os-preflight__row).is-warn :is(.dv-preflight__ic, .os-preflight__ic) { background: var(--surface); color: var(--pending); }
:is(.dv-preflight__txt, .os-preflight__txt) { flex: 1; min-width: 0; }
:is(.dv-preflight__foot, .os-preflight__foot) { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
:is(.dv-preflight__foot, .os-preflight__foot) :is(.note, .os-note) { flex: 1; min-width: 200px; font-size: var(--text-xs); color: var(--muted); line-height: 1.45; }
/* Tab-bar divider before Run (v4 prototype .pt-tab-div). */
:is(.dv-tab__div, .os-tab__div) {
  width: 1px;
  align-self: center;
  height: 18px;
  background: var(--hairline-strong);
  margin: 0 6px;
}
/* ─── Trip form (#632) ──────────────────────────────────────────────── */
/* os-field-grid is two columns at every width, and two time pickers side by
   side overflow a phone. Below 640px the trip form stacks to one column.
   Scoped modifier — never touches the shared grid. */
/* The seats stepper keeps its own width; a grid cell would stretch it. */
.trip-form__grid .os-qty { justify-self: start; }
@media (max-width: 639px) {
  .trip-form__grid.os-field-grid { grid-template-columns: minmax(0, 1fr); }
  /* One column: os-ds still treats the second cell as sharing row 1 and
     zeroes its top margin + padding (!important in the built CSS). Open the
     gap from the first cell's bottom instead, which nothing else sets. */
  .trip-form__grid.os-field-grid > .field-grid__field:first-child:not(.field-grid__field--span-2):has(+ :not(.field-grid__field--span-2)) { padding-bottom: var(--space-4); }
}
/* Trips are planned on a tablet or phone at the dock: up to 1024px, or on any
   touch screen, the form takes the os-ds touch trio (48px targets) — the
   .os-density--touch values, scoped by media query since density is a class. */
@media (max-width: 1024px), (pointer: coarse) {
  .trip-form {
    --control-h:     var(--control-h-touch);
    --control-pad-x: var(--control-pad-x-touch);
    --control-fs:    var(--control-fs-touch);
    /* The submit/cancel buttons and the segmented options size from the
       field height (46px), not --control-h: lift it to the touch height. */
    --control-h-field: var(--control-h-touch);
  }
  /* The stepper's 48px is its outer box; its buttons sit inside the 1px
     border. Grow the box so the buttons themselves are 48px targets. */
  .trip-form .os-qty { height: calc(var(--control-h) + 2px); }
  /* A segmented option sizes from padding around its label (46px here) and
     the phone action bar pins buttons to 44px+: floor both at 48px. */
  .trip-form .os-segmented--field .os-segmented__option,
  .trip-form .os-form-actions .os-field-button { min-height: var(--control-h-touch); }
  /* In the drawer (1024px on a tablet) the submit lives in the panel footer. */
  .side-panel:has(.trip-form) .side-panel__action-bar .os-btn { --control-h: var(--control-h-touch); }
}
/* ─────────────────────────────────────────────────────────────────────
   Team (dive_instructors) — staff drawer, page-scoped primitives.

   The staff drawer (app/views/account/dive_instructors/_drawer.html.erb +
   drawer/*_tab.html.erb) renders inside the layout's `side_drawer`
   turbo-frame via the shared `shared/patterns/_side_panel` shell. The tab
   bodies are token-clean (semantic utilities only); the one primitive they
   need that the shared layer does NOT provide is the in-body section heading.

   Historically the drawer carried a page-local `.dv-field-title` that
   shadowed the canonical `.dv-field-title` in tokens.css. That collision is
   resolved by NOT redefining any `dv-*` name here: the tabs use the
   non-colliding `.field-section-title`, defined once below. It mirrors the
   canonical `.section-label` / `.side-panel__eyebrow` treatment (patterns.css)
   so drawer section heads read identically to the rest of the design system.
   ───────────────────────────────────────────────────────────────────── */
/* ── Drawer section heading ───────────────────────────────────────────
   Small uppercase label that separates field groups inside a drawer tab
   (Person / Availability / Certifications / Add certification / Recent
   assignments / Team notes). Matches .section-label, but the first heading
   in a tab body sits flush to the top (the side-panel body already supplies
   its own top padding). */
:is(.field-section-title, .os-field-section-title) {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  line-height: 1.4;
  margin: 20px 0 8px;
}
:is(.side-panel__body, .os-side-panel__body) > :is(.field-section-title, .os-field-section-title):first-child, :is(.field-section-title, .os-field-section-title):first-child {
  margin-top: 0;
}
/* ── Overview summary — polished detail header + key/value rows ────────
   The Overview tab leads with a read-only SUMMARY (avatar + name + role +
   availability pill, then grouped key/value rows) before exposing the edit
   form. These primitives mirror the booking drawer (.bk-drawer-head /
   .bk-price-row) and divers/show (.dl-grid / .dl-row-item) so the staff
   drawer reads identically to the rest of the design system. Page-scoped to
   the staff drawer; named `tm-*` to avoid colliding with the `.bk-detail`-
   scoped card primitives in account/bookings.css. */
/* Identity header: avatar + name/role stack + availability pill */
:is(.tm-summary-head, .os-tm-summary-head) {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--hairline);
}
:is(.tm-summary-avatar, .os-tm-summary-avatar) {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--text-md);
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.01em;
  background: linear-gradient(135deg, var(--accent), var(--sky-900));
}
:is(.tm-summary-id, .os-tm-summary-id) { min-width: 0; flex: 1; }
:is(.tm-summary-name, .os-tm-summary-name) {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--ink);
}
:is(.tm-summary-role, .os-tm-summary-role) {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}
/* Key/value rows — single hairline per separation (WL panel rule) */
:is(.tm-dl, .os-tm-dl) { display: grid; gap: 0; }
:is(.tm-dl-row, .os-tm-dl-row) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--hairline);
  font-size: var(--text-sm);
}
:is(.tm-dl-row, .os-tm-dl-row):last-child { border-bottom: none; }
:is(.tm-dl-row, .os-tm-dl-row) dt {
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 8px;
}
:is(.tm-dl-row, .os-tm-dl-row) dd {
  color: var(--ink);
  font-weight: 500;
  text-align: right;
  margin: 0;
  min-width: 0;
}
/* Collapsible edit form — keeps edit affordances without the tab reading
   as a bare form. The <summary> is the trigger; native marker is hidden. */
:is(.tm-edit, .os-tm-edit) { margin-top: 20px; }
:is(.tm-edit, .os-tm-edit) > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--accent);
  padding: 6px 0;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
:is(.tm-edit, .os-tm-edit) > summary::-webkit-details-marker { display: none; }
:is(.tm-edit, .os-tm-edit) > summary:hover { color: var(--accent-strong); }
:is(.tm-edit, .os-tm-edit) > summary :is(.tm-edit-chevron, .os-tm-edit-chevron) { transition: transform 0.15s ease; }
:is(.tm-edit, .os-tm-edit)[open] > summary :is(.tm-edit-chevron, .os-tm-edit-chevron) { transform: rotate(180deg); }
:is(.tm-edit, .os-tm-edit)[open] > summary { margin-bottom: 4px; }
/* Leads — Side panel drawer body (#194).
   The drawer chrome (header eyebrow/title/status, sticky action bar, slide
   animation, close X) is inherited from the shared .side-panel / .side-drawer
   substrate. These rules only style the lead-specific body: the contact-first
   channel row, dense fact list, and notes block — matching
   Design/mockups/194-leads-modal/mockup-drawer.html. Tokens only. */
/* Identity chip row (avatar + email/phone). */
:is(.lead-drawer__ident, .os-lead-drawer__ident) {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
:is(.lead-drawer__avatar, .os-lead-drawer__avatar) {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: var(--text-md);
  flex: none;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
:is(.lead-drawer__contact, .os-lead-drawer__contact) {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
/* 3-up tap-to-act channel row. */
:is(.lead-drawer__channels, .os-lead-drawer__channels) {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin: 16px 0 18px;
}
:is(.lead-drawer__chan, .os-lead-drawer__chan) {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 8px;
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 0;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
:is(.lead-drawer__chan, .os-lead-drawer__chan) span {
  font-size: var(--text-xs);
  font-weight: 600;
}
:is(.lead-drawer__chan, .os-lead-drawer__chan) small {
  font-size: var(--text-xs);
  color: var(--muted);
  font-weight: 400;
  line-height: 1.2;
  max-width: 100%;
}
:is(.lead-drawer__chan, .os-lead-drawer__chan):hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
:is(.lead-drawer__chan, .os-lead-drawer__chan).is-preferred {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
:is(.lead-drawer__chan, .os-lead-drawer__chan).is-empty {
  color: var(--muted-2);
  cursor: default;
}
:is(.lead-drawer__chan, .os-lead-drawer__chan).is-empty:hover {
  border-color: var(--border);
  background: transparent;
  color: var(--muted-2);
}
/* Dense fact list — spacing only; the rows are the .dv-desclist component. */
:is(.lead-drawer__facts, .os-lead-drawer__facts) {
  margin: 0 0 18px;
}
/* Notes block. */
:is(.lead-drawer__notes, .os-lead-drawer__notes) {
  padding: 12px 14px;
  background: var(--surface-alt);
  border-radius: 10px;
}
:is(.lead-drawer__notes, .os-lead-drawer__notes) :is(.dv-eyebrow, .os-eyebrow) {
  display: block;
  margin-bottom: 6px;
}
/* #194 — whole-card click opens the lead drawer (stretched link). The name
   link's ::after covers the entire card; the action row (Edit/Delete) is
   raised above it so those stay independently clickable. Native HTML5 drag on
   the kanban card is unaffected — the browser suppresses the click after a drag. */
:is(.lead-card-clickable, .os-lead-card-clickable) { position: relative; }
:is(.lead-card-clickable__link, .os-lead-card-clickable__link)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
:is(.lead-card-clickable__action, .os-lead-card-clickable__action) { position: relative; z-index: 2; }
/* The name is the stretched link but must read as plain card text — no link
   colour/underline. The whole card carries the hover affordance instead. */
:is(.lead-card-clickable__link, .os-lead-card-clickable__link), :is(.lead-card-clickable__link, .os-lead-card-clickable__link):hover, :is(.lead-card-clickable__link, .os-lead-card-clickable__link):focus {
  color: inherit;
  text-decoration: none;
}
/* The whole-card hover tint is the os-ds `.os-kanban-card.is-clickable` state
   (#354); the card carries both classes. */
/* #194 — inline email capture: the Email fact row becomes a labelled field for
   emailless leads; the footer's disabled Convert button submits it. Sits with
   the fact list (hairline separator matches .dv-desclist row rhythm). */
:is(.lead-drawer__email-capture, .os-lead-drawer__email-capture) {
  margin-bottom: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}
:is(.lead-drawer__email-capture__label, .os-lead-drawer__email-capture__label) {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: 1.4;
  margin-bottom: 2px;
}
:is(.lead-drawer__email-capture, .os-lead-drawer__email-capture) p { margin: 0 0 8px; }
/* #394 — the party affordance: a guest's email, linked to the board filtered
   down to everyone who registered with it. Reads as muted card text until
   hovered, because the address is information first and a control second; the
   count badge beside it is what signals there is something to click.
   On the kanban card this link ALSO carries .lead-card-clickable__action, which
   is what lifts it above the stretched ::after overlay (see above) — without
   that the click opens the drawer instead of filtering. */
.lead-party-link { color: inherit; text-decoration: none; }
.lead-party-link:hover .os-meta,
.lead-party-link:focus-visible .os-meta { color: var(--accent); text-decoration: underline; }
.lead-party-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
/* ─────────────────────────────────────────────────────────────────────
   account/quotes.css — the staff quote detail page (#583) and the
   package-first builder (#584), #572 designs A and B2. Layout only: every
   surface, type role and control is an os-ds component; this file places
   them (state card row, package block, facts, rail stack).
   ───────────────────────────────────────────────────────────────────── */
.quote-detail { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
/* One state card: icon · what happened · that state's action. */
.quote-state { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); padding: var(--space-4) var(--space-5); }
.quote-state__icon { flex-shrink: 0; }
.quote-state__text { flex: 1 1 var(--measure-display); min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.quote-state__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.quote-state__actions form { display: contents; }
/* Package block (read-only, mirrors the builder). */
.quote-block { display: flex; flex-direction: column; gap: var(--space-4); }
/* Title row: the package icon inline with the name, the diver chip and the
   remove button centred on that line; the subtitle under it, flush with the
   card's content edge like every section below. */
.quote-block__titles { display: flex; flex-direction: column; gap: var(--space-1); }
.quote-block__head { display: flex; align-items: center; gap: var(--space-3); }
.quote-block__name { display: flex; align-items: center; gap: var(--space-2); flex: 1; min-width: 0; }
.quote-block__name > svg { flex-shrink: 0; }
.quote-facts .info-strip { margin-bottom: 0; }
.quote-fact__value { display: flex; flex-direction: column; }
.quote-facts .info-strip__cell > span:last-child { display: flex; flex-direction: column; gap: 2px; }
.quote-block__foot { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3);
  padding-top: var(--space-4); border-top: 1px solid var(--hairline-2); }
.quote-block__foot > p { flex: 1 1 auto; min-width: 0; }
.quote-block__amount { white-space: nowrap; }
.quote-block__pp, .quote-block__amount { font-weight: 600; }
/* Rail stack. */
.quote-rail { display: flex; flex-direction: column; gap: var(--space-4); }
.quote-rail .os-stat-card-value { font-size: var(--text-2xl); }
.quote-rail__link { display: flex; flex-direction: column; gap: var(--space-2); }
.quote-rail__link .os-link { display: inline-flex; align-items: center; gap: var(--space-1); }
/* ── Builder (#584, B2): main column + sticky Quote rail, one width. ── */
.quote-builder { display: grid; grid-template-columns: minmax(0, 1fr) var(--quote-rail-w, 348px); gap: var(--space-6);
  align-items: start; max-width: var(--page-wide); margin: 0 auto; padding-block: var(--space-6) var(--space-12); }
.quote-builder__main { display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
.quote-builder__rail { position: sticky; top: var(--space-6); display: flex; flex-direction: column; gap: var(--space-4); }
@media (max-width: 1024px) {
  .quote-builder { grid-template-columns: minmax(0, 1fr); }
  .quote-builder__rail { position: static; }
}
/* Party bar. */
.quote-party { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-6); padding: var(--space-4) var(--space-5); }
.quote-party__customer { display: flex; flex-direction: column; gap: var(--space-2); flex: 1 1 0; min-width: 0; }
.quote-party__who { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-h-field); }
.quote-party__contact > summary { list-style: none; cursor: pointer; display: flex; flex-direction: column; }
.quote-party__contact > summary::-webkit-details-marker { display: none; }
.quote-party__name { font-weight: 600; }
.quote-party__fields { display: grid; gap: var(--space-3); margin-top: var(--space-3); }
.quote-party__item { display: flex; flex-direction: column; gap: var(--space-2); flex: none; }
/* The calendar field sizes to its date, not the bar. */
.quote-party__item .date-input { width: calc(var(--space-12) * 4); }
/* Package block (builder side). */
.quote-builder__blocks { display: flex; flex-direction: column; gap: var(--space-6); }
.quote-builder__add-block { align-self: flex-start; }
.quote-block .os-label + .stay-tiles { margin-top: var(--space-2); }
.quote-grid__add .os-field + .os-field { margin-top: 0; }
.quote-block__confirm-body { display: flex; flex-direction: column; gap: var(--space-2); }
.quote-block__confirm-actions { display: flex; gap: var(--space-2); }
.quote-block .bk2-stay-row { cursor: pointer; }
/* Who holds the package: the label, then a chip per diver (the checkbox
   inside is visually hidden, so its focus shows on the chip). */
.quote-block__who { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.quote-block__who .os-label { margin: 0; }
.quote-block__who .os-chip { cursor: pointer; height: var(--space-10); padding: 0 var(--space-4) 0 var(--space-3); gap: var(--space-2); }
.quote-block__who .os-chip:has(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Extra dives grid. */
.quote-grid__head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
.quote-grid__cell { display: inline-flex; align-items: center; min-height: var(--control-h); }
.quote-grid__actions, .quote-grid__add-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
.quote-grid__add { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: flex-end; margin-top: var(--space-4); }
.quote-grid__add .quote-grid__add-actions { margin-top: 0; }
/* Quote rail. */
.quote-rail__lines { display: flex; flex-direction: column; }
.quote-rail__line { display: flex; justify-content: space-between; gap: var(--space-3); padding-block: var(--space-2);
  border-top: 1px solid var(--hairline-2); }
.quote-rail__line:first-child { border-top: 0; }
.quote-rail__total { display: flex; flex-direction: column; gap: var(--space-1); padding-top: var(--space-4); margin-top: var(--space-2);
  border-top: 1px solid var(--hairline); }
.quote-rail__amount { font-size: var(--text-2xl); }
.quote-rail__foot { display: flex; flex-direction: column; gap: var(--space-2); text-align: center; }
.quote-rail__save { width: 100%; justify-content: center; }
/* Customer view (collapsed by default). */
.quote-cv > summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; }
.quote-cv > summary::-webkit-details-marker { display: none; }
.quote-cv__label { display: inline-flex; align-items: center; gap: var(--space-2); }
.quote-cv__hide, .quote-cv[open] .quote-cv__show { display: none; }
.quote-cv[open] .quote-cv__hide { display: inline; }
.quote-cv__body { display: flex; flex-direction: column; gap: var(--space-3); padding-top: 0; }
.quote-cv__mini { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3) var(--space-4);
  border: 1px solid var(--hairline); border-radius: var(--radius); background: var(--surface); }
.quote-cv__line { display: flex; justify-content: space-between; gap: var(--space-2); }
.quote-cv__total { padding-top: var(--space-2); border-top: 1px solid var(--hairline-2); }
/* Package card in the funnel's grammar (#616): Package dates beside Nights. */
/* One row: Package dates · Nights · Dives, each label / control / hint. */
/* The trip row: the dates, then the steppers with their unit inside, on one
   line that wraps; the span and extension cost read under it. */
.quote-block__trip { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.quote-block__date { flex: 1 1 calc(var(--space-12) * 4); max-width: calc(var(--space-12) * 6); }
.quote-block__trip + .os-hint { margin-top: var(--space-2); }
.quote-qty--unit .os-qty__input { width: calc(var(--control-h) * 0.7); text-align: right; }
.quote-qty__unit { padding: 0 var(--space-3) 0 var(--space-1); }
/* One control height across the builder: steppers, dates and the add-row
   buttons all sit at the canonical field height, so a row's labels, controls
   and hints line up. */
.quote-builder .os-qty { --control-h: var(--control-h-field); }
/* The New quote page's package picker and empty grid. */
.quote-picker-list { display: flex; flex-direction: column; gap: var(--space-2); }
.quote-picker-list .os-option-card + .os-option-card { margin-top: 0; }
.quote-grid__empty { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); margin-top: 0;
  padding: var(--space-3) var(--space-4); border: 1px dashed var(--hairline-strong); border-radius: var(--radius); }
.quote-grid__empty > .os-small { margin-right: auto; }
/* Phone (muf, 2026-10-26): pair what fits side by side instead of stacking
   every control. Party beside Valid until; the Who chips on one line with
   "Jonas is on …" as a caption; the date across, Nights and Dives sharing
   the next line; each extra-dive date as a row (date and dive, then the
   ticks naming their diver, then the amount); the total and Save on the
   os-ds pinned footer in place of the rail's own. */
.quote-phonebar, .quote-block__who-note, .quote-grid__name { display: none; }
@media (max-width: 640px) {
  .quote-party { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--space-4) var(--space-3); padding-inline: var(--space-4); }
  .quote-party .os-qty__input { width: calc(var(--control-h) * 0.7); }
  .quote-party__customer { grid-column: 1 / -1; }
  #quote-builder-divers { display: contents; }
  .quote-party__item .date-input { width: 100%; }

  .quote-block__who-meta { display: none; }
  .quote-block__who-note { display: block; flex-basis: 100%; margin: 0; }

  .quote-block__date { flex: 1 1 100%; max-width: none; }
  .quote-block__trip .os-qty { flex: 1 1 0; min-width: 0; justify-content: space-between; }

  .quote-grid thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
  .quote-grid, .quote-grid tbody { display: block; }
  .quote-grid tr { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-3); padding: var(--space-2) var(--space-4); }
  .quote-grid tr + tr { border-top: 1px solid var(--hairline); }
  .quote-grid tr::after { content: ""; flex-basis: 100%; order: 2; }
  .quote-grid td { display: block; padding: 0; border: 0; }
  .quote-grid td:nth-child(2) { flex: 1 1 0; min-width: 0; }
  .quote-grid td:last-child { order: 1; }
  .quote-grid td:has(.quote-grid__cell) { order: 3; }
  .quote-grid td[id$="-amount"] { order: 4; margin-left: auto; }
  .quote-grid__cell { gap: var(--space-2); }
  .quote-grid__name { display: inline; }

  .quote-rail__foot { display: none; }
  .quote-phonebar { display: block; }
}
/* ── Quotes list A2 (index) ────────────────────────────────────────────
   Desktop is the plain os-table. On phone the os-ds card stack would give
   every quote a five-row labelled card; A2 folds a row into three lines
   instead: name · pill / ref · party · dates / Reply by · total. The quote
   cell and its stack become `contents` so the link and the reference are
   grid items of the row. */
@media (max-width: 639px) {
  .quotes-list tbody tr {
    display: grid;
    grid-template-columns: auto auto 1fr auto;
    grid-template-areas:
      "name  name  name  status"
      "ref   party dates dates"
      "reply reply reply total";
    align-items: baseline;
    -moz-column-gap: 0;
         column-gap: 0;
    row-gap: var(--space-1);
  }
  .quotes-list tbody td {
    display: block;
    padding: 0 !important;
    margin: 0;
    border: 0;
    text-align: left;
    justify-content: flex-start;
    white-space: nowrap;
    overflow-wrap: normal;
    color: var(--muted);
    font-size: var(--text-sm);
  }
  .quotes-list tbody td::before { content: none; }
  /* The os-ds stack labels a cell in its ::before (uppercase, bold); the
     separators and "Reply by" below reuse it as plain inline text. */
  .quotes-list tbody td.quotes-list__party::before,
  .quotes-list tbody td.quotes-list__dates::before,
  .quotes-list tbody td.quotes-list__reply::before {
    flex: none; font: inherit; color: var(--muted); letter-spacing: normal; text-transform: none;
  }
  .quotes-list tbody td.quotes-list__party,
  .quotes-list tbody td.quotes-list__dates,
  .quotes-list tbody td.quotes-list__reply { display: flex; align-items: baseline; gap: 0; white-space: nowrap; }
  .quotes-list__party .os-table__stack { display: contents; }

  .quotes-list tbody td.quotes-list__quote,
  .quotes-list__quote .os-table__stack { display: contents; }
  .quotes-list__quote .os-table__primary { grid-area: name; font-size: var(--text-md); }
  .quotes-list__quote .os-table__sub { grid-area: ref; margin: 0; white-space: nowrap; }

  .quotes-list tbody td.quotes-list__status { grid-area: status; justify-self: end; align-self: center; }
  .quotes-list tbody td.quotes-list__party { grid-area: party; }
  .quotes-list__contents { display: none; }
  .quotes-list tbody td.quotes-list__dates { grid-area: dates; }
  .quotes-list tbody td.quotes-list__party::before,
  .quotes-list tbody td.quotes-list__dates::before { content: "·"; margin: 0 var(--space-2); }
  .quotes-list tbody td.quotes-list__total { grid-area: total; justify-self: end; color: var(--ink); }

  .quotes-list tbody td.quotes-list__reply { grid-area: reply; }
  .quotes-list tbody td.quotes-list__reply::before { content: "Reply by"; margin-right: var(--space-1); }
  .quotes-list__reply .os-table__stack { flex-direction: row; align-items: baseline; }
  .quotes-list__reply .os-table__sub { margin: 0; font-size: inherit; }
  .quotes-list__reply .os-table__sub::before { content: "·"; margin: 0 var(--space-1); color: var(--muted); }
  .quotes-list tbody td.quotes-list__quiet { display: none; }
}
/* ── Org (multi-outlet) dashboard ─────────────────────────────────────────
   Aggregate hero (oversized portfolio totals) + full-bleed per-outlet strip.
   Numerics use .dv-figure (Geist Mono); all colour via semantic tokens. */
:is(.org-hero, .os-org-hero) {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
@media (min-width: 640px) {
  :is(.org-hero, .os-org-hero) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  :is(.org-hero, .os-org-hero) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
:is(.org-hero__figure, .os-org-hero__figure) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  font-size: var(--text-3xl);
  line-height: 1.05;
  letter-spacing: -0.01em;
}
/* Per-outlet strip. Full-bleed rows, hairline-separated. */
/* One contained card holding every outlet as a hairline-separated row —
   reads as a structured list, not a set of floating cards (a single outlet no
   longer looks like it's drifting next to a left-hand label). */
:is(.org-outlets, .os-org-outlets) { margin-top: var(--space-5); }
:is(.org-outlets__list, .os-org-outlets__list) {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
}
:is(.org-outlet-row, .os-org-outlet-row) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  /* Rows of a list card sit at the card's 24px inset, like table cells in a
     card (muf, 2026-10-07; #610 crawl gate). */
  padding: var(--space-4) var(--space-6);
  text-decoration: none;
  transition: background 0.12s ease;
}
:is(.org-outlet-row, .os-org-outlet-row) + :is(.org-outlet-row, .os-org-outlet-row) { border-top: 1px solid var(--hairline); }
:is(.org-outlet-row, .os-org-outlet-row):hover { background: var(--surface-alt); }
:is(.org-outlet-row__id, .os-org-outlet-row__id) { min-width: 0; }
:is(.org-outlet-row__name, .os-org-outlet-row__name) {
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Right cluster: KPI list + open-pill + chevron. */
:is(.org-outlet-row__right, .os-org-outlet-row__right) {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
:is(.org-outlet-row__kpis, .os-org-outlet-row__kpis) {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  text-align: right;
  margin: 0;
}
:is(.org-outlet-row__kpi-value, .os-org-outlet-row__kpi-value) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}
/* ── Cockpit: controls ─────────────────────────────────────────────────── */
:is(.cockpit-controls, .os-cockpit-controls) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
:is(.cockpit-controls__right, .os-cockpit-controls__right) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
:is(.cockpit-presets, .os-cockpit-presets) {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  background: var(--surface-alt);
  border: 1px solid var(--hairline);
  border-radius: 999px;
}
:is(.cockpit-preset, .os-cockpit-preset) {
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}
:is(.cockpit-preset, .os-cockpit-preset):hover { color: var(--ink); }
:is(.cockpit-preset, .os-cockpit-preset).is-active {
  background: var(--surface);
  color: var(--accent);
  box-shadow: var(--shadow-xs, 0 1px 2px rgba(15, 23, 42, 0.06));
}
:is(.cockpit-range, .os-cockpit-range) {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
:is(.cockpit-range__date, .os-cockpit-range__date) { width: auto; }
/* Phones (#609 R1): nothing scrolls the page sideways. The presets scroll in
   their own track, the range sits on a 2-up date grid with Apply below it, and
   the outlet filter wraps onto its own line. */
@media (max-width: 767px) {
  :is(.cockpit-controls, .os-cockpit-controls),
  :is(.cockpit-controls__right, .os-cockpit-controls__right) { width: 100%; min-width: 0; }
  :is(.cockpit-presets, .os-cockpit-presets) {
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
  }
  :is(.cockpit-preset, .os-cockpit-preset) { flex: none; white-space: nowrap; }
  :is(.cockpit-range, .os-cockpit-range) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    width: 100%;
  }
  :is(.cockpit-range, .os-cockpit-range) > .os-btn { grid-column: 1 / -1; }
  :is(.cockpit-range__date, .os-cockpit-range__date) { width: 100%; min-width: 0; }
}
/* ── Cockpit: KPI grid ─────────────────────────────────────────────────── */
:is(.cockpit-kpis, .os-cockpit-kpis) {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
@media (min-width: 768px) {
  :is(.cockpit-kpis, .os-cockpit-kpis) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
:is(.cockpit-kpi__figure, .os-cockpit-kpi__figure) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  font-size: var(--text-2xl);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin-top: var(--space-1);
}
:is(.cockpit-kpi__foot, .os-cockpit-kpi__foot) {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
:is(.cockpit-delta, .os-cockpit-delta) {
  font-size: var(--text-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius-sm);
}
:is(.cockpit-delta--up, .os-cockpit-delta--up)   { color: var(--confirmed); background: var(--confirmed-bg); }
:is(.cockpit-delta--down, .os-cockpit-delta--down) { color: var(--cancelled); background: var(--cancelled-bg); }
:is(.cockpit-delta--flat, .os-cockpit-delta--flat) { color: var(--text-muted); background: var(--surface-alt); }
/* ── Cockpit: charts grid ──────────────────────────────────────────────── */
:is(.cockpit-charts, .os-cockpit-charts) {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
@media (min-width: 1024px) {
  :is(.cockpit-charts, .os-cockpit-charts) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* A chart's canvas sizes to its card; without this a grid item's min-width
   (auto = the canvas width) pushes the card past a phone viewport. */
:is(.cockpit-charts, .os-cockpit-charts) > * { min-width: 0; }
/* Customer stat trio (3-up on desktop). */
@media (min-width: 768px) {
  :is(.cockpit-kpis--trio, .os-cockpit-kpis--trio) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* ── Cockpit: source table (inside a chart card) ───────────────────────────── */
:is(.cockpit-table-wrap, .os-cockpit-table-wrap) { overflow-x: auto; }
:is(.cockpit-table, .os-cockpit-table) {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
:is(.cockpit-table, .os-cockpit-table) th, :is(.cockpit-table, .os-cockpit-table) td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--hairline);
  white-space: nowrap;
}
:is(.cockpit-table, .os-cockpit-table) th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
:is(.cockpit-table, .os-cockpit-table) td { color: var(--ink); }
:is(.cockpit-table, .os-cockpit-table) :is(.num, .os-num) {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
:is(.cockpit-table, .os-cockpit-table) tbody tr:last-child td { border-bottom: none; }
/* Phones: an outlet row stacks — name, then the KPI strip wrapping under it —
   instead of clipping the KPIs off the card's right edge. */
@media (max-width: 767px) {
  :is(.org-outlet-row, .os-org-outlet-row) { flex-wrap: wrap; }
  :is(.org-outlet-row__right, .os-org-outlet-row__right) { flex: 1 1 100%; min-width: 0; justify-content: space-between; }
  :is(.org-outlet-row__kpis, .os-org-outlet-row__kpis) { flex-wrap: wrap; gap: var(--space-3) var(--space-5); text-align: left; }
}
/* ─────────────────────────────────────────────────────────────────────
   Settings shell — page container + phone master → detail (#636).

   The os-ds grid (.settings-grid, patterns.css) stacks the sub-nav ABOVE the
   content once the pane is ≤640px, so on a phone a tapped section loaded below
   a ~700px list, off-screen. At that same container breakpoint the page now
   splits into two screens instead (view: account/settings/show):
     · landing (bare /settings, .settings-page--landing) → the section list only,
       as full-width 48px rows with a chevron;
     · a section → its own screen, nav hidden.
   Both screens head with the canonical list_page_header (title on the
   hamburger's row, `‹ Settings` crumb under it) in place of the desktop intro.
   Wider panes keep the side-by-side split untouched.
   ───────────────────────────────────────────────────────────────────── */
.settings-page {
  max-width: var(--page-wide);
  margin-inline: auto;
  padding: var(--space-6) var(--space-10);
}
/* Phone-only furniture, hidden on the split layout. */
.settings-page__phone-head,
.settings-subnav__chev { display: none; }
@container (max-width: 640px) {
  /* The shell already pads the pane with --gutter; the desktop 40px inset on
     top of it left a phone ~260px of content width. */
  .settings-page { padding: 0; }

  /* Both screens: the phone page head replaces the desktop intro. */
  .settings-page__intro { display: none; }
  .settings-page__phone-head { display: block; }
  /* The head is wrapped, so os-ds's `.os-page-head + *` 2rem gap (header_band)
     can't reach the grid; give it the same gap every list page gets. */
  .settings-grid { margin-top: var(--space-8); }

  /* Section screen: the content replaces the list. */
  .settings-page:not(.settings-page--landing) .settings-subnav { display: none; }
  /* `‹ Settings` sits under the title with a 48px hit area: the os-ds phone
     page head (v1.41.0), no local rule. */

  /* Landing screen: the list alone, as tappable full-width rows. */
  .settings-page--landing .settings-grid > section { display: none; }
  .settings-page--landing .settings-subnav { border-bottom: 0; padding-bottom: 0; }
  .settings-page--landing .settings-subnav__group { margin-bottom: var(--space-5); }
  .settings-page--landing .settings-subnav__items { flex-direction: column; flex-wrap: nowrap; gap: 0; }
  .settings-page--landing .settings-subnav__items > li + li { border-top: 1px solid var(--hairline); }
  .settings-page--landing .os-settings-nav__item {
    min-height: var(--space-12);
    padding-inline: var(--space-3);
  }
  /* No section is open on the list, so nothing reads as selected. */
  .settings-page--landing .os-settings-nav__item.is-active {
    background: transparent;
    color: var(--ink);
    font-weight: 500;
  }
  .settings-page--landing .os-settings-nav__item.is-active svg { color: var(--muted); }
  .settings-page--landing .settings-subnav__current { display: none; }
  .settings-page--landing .settings-subnav__chev { display: inline-flex; margin-left: auto; }
}
/* auth_shell.css — the platform-host auth/onboarding shell (layouts/devise).
   Tenant-neutral, DiveOS-branded: one centered card with the DiveOS wordmark.
   Moved out of the layout's inline <style> block and tokenized (2026-10-08).
   The heading/body come from themes/light/workflow/_box (app override). */
.os-auth {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--canvas);
  font-family: var(--font-sans);
  color: var(--ink);
  padding: var(--space-6);
  -webkit-font-smoothing: antialiased;
}
.os-auth__card {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-10) var(--space-8) var(--space-8);
  box-shadow: var(--shadow-md);
}
.os-auth__brand {
  text-align: center;
  margin-bottom: var(--space-8);
}
.os-auth__logo {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
}
.os-auth__brand .os-eyebrow {
  margin-top: var(--space-1);
}
.os-auth__heading {
  margin: 0 0 var(--space-6);
}
/* Replaces the gem workflow box's `space-y-5`. */
.os-auth__body > * + * {
  margin-top: var(--space-5);
}
.os-auth__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
/* "Or" row between alternative actions (themes/light/_decision_line fork):
   hairline rules either side of an eyebrow label. */
.os-decision-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
/* auth_ocean.css — the full-bleed ocean auth shell (layouts/auth_ocean:
   sign-in, password reset, sign-up, trial signup). Moved out of the layout's
   inline <style> block and tokenized (2026-10-08). The look is unchanged: the
   `--ocean-*` layer below is the theme's own palette, but every value is now
   seeded from os-ds primitives/semantics — deep water is a sky ramp step mixed
   toward black, glass/overlay alphas are `color-mix(… N%, transparent)`.
   The ambience JS (rays, bubbles, snow, videos, perf-lite, password reveal)
   stays inline in the layout; it only toggles the classes styled here. */
/* This file ships in the app-wide bundle. The custom properties, html/body
   rules, box-sizing and the tab-hidden pause are scoped to body.auth-ocean;
   the .ao-* selectors rely on the unique `ao-` prefix instead (enforced by
   test/lint/auth_ocean_class_gate_test.rb). */
.auth-ocean, .auth-ocean *, .auth-ocean *::before, .auth-ocean *::after { box-sizing: border-box; }
@property --whale-fade { syntax: '<number>'; inherits: false; initial-value: 0; }
/* ════ OCEAN THEME ════ */
.auth-ocean {
  /* Water column, surface → floor. Each stop is the nearest sky-ramp mix to
     the original hand-picked gradient (ΔRGB ≤ ~10 per stop). */
  --ocean-surface:  color-mix(in srgb, var(--sky-400) 97%, white);
  --ocean-shallow:  color-mix(in srgb, var(--sky-500) 97%, var(--sky-900));
  --ocean-mid:      color-mix(in srgb, var(--sky-500) 50%, var(--sky-700));
  --ocean-deep:     color-mix(in srgb, var(--sky-500) 64%, black);
  --ocean-deeper:   color-mix(in srgb, var(--sky-500) 31%, var(--sky-950));
  --ocean-twilight: color-mix(in srgb, var(--sky-900) 84%, black);
  --ocean-midnight: color-mix(in srgb, var(--sky-900) 59%, black);
  --ocean-abyss-floor: color-mix(in srgb, var(--sky-800) 23%, black);
  --ocean-bg: linear-gradient(180deg, var(--ocean-surface) 0%, var(--ocean-shallow) 14%, var(--ocean-mid) 30%, var(--ocean-deep) 46%, var(--ocean-deeper) 60%, var(--ocean-twilight) 74%, var(--ocean-midnight) 86%, var(--ocean-abyss-floor) 100%);

  /* Named darks reused by glass, fields, shadows. */
  --ocean-abyss:  color-mix(in srgb, var(--sky-950) 69%, black);  /* pills, solid-button ink */
  --ocean-trench: color-mix(in srgb, var(--sky-950) 40%, black);  /* field + alert wells */
  --ocean-floor:  color-mix(in srgb, var(--sky-950) 31%, black);  /* card base, text shadows */
  --ocean-night:  color-mix(in srgb, var(--sky-950) 18%, black);  /* vignette */
  /* Named lights for the light-play layers. */
  --ocean-glow:   color-mix(in srgb, var(--sky-300) 96%, var(--sky-950));
  --ocean-bloom:  color-mix(in srgb, var(--sky-50) 77%, var(--sky-300));
  --ocean-haze:   color-mix(in srgb, var(--sky-200) 89%, var(--sky-500));
  --ocean-beam:   color-mix(in srgb, var(--sky-100) 87%, var(--sky-500));
  --ocean-chevron: color-mix(in srgb, var(--sky-800) 43%, white);

  --ocean-ink: var(--on-accent);
  --ocean-dim: color-mix(in srgb, var(--ocean-ink) 76%, transparent);
  --ocean-faint: color-mix(in srgb, var(--ocean-ink) 52%, transparent);
  --ocean-accent: var(--sky-300);
  --ocean-accent-strong: var(--sky-200);
  --ocean-pill-border: color-mix(in srgb, var(--ocean-ink) 22%, transparent);
  --ocean-pill-bg: color-mix(in srgb, var(--ocean-abyss) 62%, transparent);
  --ocean-pill-bg-h: color-mix(in srgb, var(--ocean-abyss) 78%, transparent);

  --btn-solid-bg: var(--sky-400);
  --btn-solid-fg: var(--ocean-abyss);
  --btn-solid-shadow: 0 0 0 1px color-mix(in srgb, var(--sky-400) 50%, transparent), 0 10px 34px -8px color-mix(in srgb, var(--sky-400) 70%, transparent);
  --btn-solid-bg-h: var(--sky-300);

  --card-top: var(--sky-900);
  --card-bot: var(--ocean-floor);
  --card-tint: 54%;
  --card-blur: 14px;
  --glass-bg: linear-gradient(160deg, color-mix(in srgb, var(--card-top) var(--card-tint), transparent), color-mix(in srgb, var(--card-bot) calc(var(--card-tint) + 5%), transparent));
  --glass-border: color-mix(in srgb, var(--sky-300) 22%, transparent);
  --glass-shadow: 0 40px 100px -30px color-mix(in srgb, black 72%, transparent), 0 0 80px -34px color-mix(in srgb, var(--sky-400) 50%, transparent), inset 0 1px 0 color-mix(in srgb, var(--ocean-ink) 8%, transparent);

  --field-bg: color-mix(in srgb, var(--ocean-trench) 42%, transparent);
  --field-border: color-mix(in srgb, var(--sky-300) 20%, transparent);
  --field-border-h: color-mix(in srgb, var(--sky-300) 40%, transparent);
  --field-border-f: color-mix(in srgb, var(--sky-400) 90%, transparent);
  --field-ring: 0 0 0 3px color-mix(in srgb, var(--sky-400) 16%, transparent);
  --hairline-soft: color-mix(in srgb, var(--ocean-ink) 12%, transparent);

  --title-color: color-mix(in srgb, var(--ocean-ink) 84%, transparent);
  --text-glow: color-mix(in srgb, var(--ocean-floor) 50%, transparent);
}
html:has(> body.auth-ocean), body.auth-ocean { height: 100%; }
body.auth-ocean {
  margin: 0;
  min-height: 100vh;      /* fallback for browsers without dvh */
  min-height: 100dvh;     /* mobile URL-bar-safe viewport height */
  /* NOTE: no `fixed` background-attachment (mobile Safari/Chrome repaint
     jank). The full-bleed ocean gradient is painted by the fixed
     `.ao-creatures::before` layer instead; this is a static fallback. */
  background: var(--ocean-bg);
  color: var(--ocean-ink);
  font-family: var(--font-sans);
  font-feature-settings: var(--font-features);
  font-size: var(--text-sm); line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
.auth-ocean a { text-decoration: none; color: inherit; }
/* ════ BACKGROUND FX ════ */
.ao-bg { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.ao-surfglow { position: absolute; left: 0; top: 0; width: 100%; height: 46%; mix-blend-mode: screen;
  background: radial-gradient(120% 90% at 50% -28%, color-mix(in srgb, var(--ocean-glow) 50%, transparent), color-mix(in srgb, var(--ocean-glow) 16%, transparent) 38%, transparent 66%); }
.ao-vign { position: absolute; inset: 0; background: radial-gradient(130% 100% at 60% -10%, transparent 52%, color-mix(in srgb, var(--ocean-night) 50%, transparent)); }
/* god rays — pure CSS, tuned to read like slow-motion underwater shafts.
   The stepped feel of a naive version comes from `alternate` + a single
   ease-in-out sway: every beam halts at both extremes in lockstep with
   nothing else moving. Fixes here:
     1. Seamless loops (0% == 100%, no `alternate`) → no reversal snap.
     2. Each beam runs TWO loops on independent properties + periods:
        `aoBeamMotion` (transform: drift/sway/breathe) and `aoBeamShimmer`
        (opacity). Different durations → the brightness keeps moving even
        while a beam is at a positional turnaround, so it never freezes.
     3. Per-beam durations/phases (set in JS) keep beams out of sync, so
        the field shimmers organically instead of pulsing as one block. */
/* soft pulsing bloom at the surface source — a big blurred radial glow
   that gently breathes, so the rays read as emerging from diffuse light
   rather than a hard column. */
.ao-raybloom { position: absolute; left: 50%; top: -20%; width: 64vw; max-width: 860px; height: 72%;
  transform: translateX(-50%); pointer-events: none; mix-blend-mode: screen; filter: blur(36px);
  background: radial-gradient(52% 64% at 50% 4%, color-mix(in srgb, var(--ocean-bloom) 42%, transparent), color-mix(in srgb, var(--ocean-haze) 16%, transparent) 42%, transparent 72%);
  animation: aoBloomPulse 6s ease-in-out infinite; will-change: opacity, transform; }
@keyframes aoBloomPulse {
  0%, 100% { opacity: 0.5;  transform: translateX(-50%) scale(1); }
  50%      { opacity: 0.92; transform: translateX(-50%) scale(1.07); }
}
.ao-rays { position: absolute; left: 0; top: -14%; width: 100%; height: 132%; overflow: hidden; mix-blend-mode: screen;
  transform-origin: 50% 0%; animation: aoRaysDrift 34s ease-in-out infinite; will-change: transform;
  -webkit-mask-image: linear-gradient(180deg, black 0%, color-mix(in srgb, black 90%, transparent) 28%, color-mix(in srgb, black 42%, transparent) 60%, transparent 84%);
  mask-image: linear-gradient(180deg, black 0%, color-mix(in srgb, black 90%, transparent) 28%, color-mix(in srgb, black 42%, transparent) 60%, transparent 84%); }
@keyframes aoRaysDrift {
  0%   { transform: translateX(-1.4%) skewX(-0.9deg); }
  50%  { transform: translateX(1.4%) skewX(0.9deg); }
  100% { transform: translateX(-1.4%) skewX(-0.9deg); }
}
/* Each beam is hot at the very top and fades down (its own vertical mask),
   so when the opacity shimmer pulses, the visible flicker is strongest at
   the surface and diffuses toward the bottom. */
/* Beams cluster near top-center and pivot from their tops, so the field
   RADIATES from the bright surface source and fans out to the sides
   (--ba grows with distance from center). The per-beam top-bright mask
   makes each shaft hottest at the convergence and diffusing toward its
   fanned-out tip. --bi is the per-beam intensity (a unitless 0–1 the JS
   sets), turned into a color-mix percentage here. */
.ao-rays .ao-beam { position: absolute; top: -8%; left: var(--bx); width: var(--bw, 110px); height: 205%; transform-origin: top center;
  background: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--ocean-beam) calc(var(--bi, 0.10) * 100%), transparent) 34%, color-mix(in srgb, var(--sky-100) calc(var(--bi, 0.10) * 150%), transparent) 50%, color-mix(in srgb, var(--ocean-beam) calc(var(--bi, 0.10) * 100%), transparent) 66%, transparent 100%);
  filter: blur(var(--bblur, 16px)); backface-visibility: hidden;
  -webkit-mask-image: linear-gradient(180deg, black 0%, color-mix(in srgb, black 98%, transparent) 18%, color-mix(in srgb, black 55%, transparent) 55%, transparent 88%);
  mask-image: linear-gradient(180deg, black 0%, color-mix(in srgb, black 98%, transparent) 18%, color-mix(in srgb, black 55%, transparent) 55%, transparent 88%);
  animation: aoBeamMotion var(--mdur, 17s) ease-in-out var(--mdel, 0s) infinite,
             aoBeamShimmer var(--sdur, 6s) ease-in-out var(--sdel, 0s) infinite;
  will-change: transform, opacity; }
/* sway is pure rotation about the top pivot (keeps the fan apex fixed) +
   a width breathe; ease-in-out on each leg glides the turnarounds. */
@keyframes aoBeamMotion {
  0%   { transform: rotate(var(--ba, 0deg)) scaleX(1); }
  34%  { transform: rotate(calc(var(--ba, 0deg) + 1.6deg)) scaleX(1.1); }
  67%  { transform: rotate(calc(var(--ba, 0deg) - 1.2deg)) scaleX(0.92); }
  100% { transform: rotate(var(--ba, 0deg)) scaleX(1); }
}
/* irregular stops + deep min → a brighter, twinklier flicker than a plain sine */
@keyframes aoBeamShimmer {
  0%   { opacity: calc(var(--bo, 0.85) * 0.28); }
  22%  { opacity: calc(var(--bo, 0.85) * 0.92); }
  44%  { opacity: var(--bo, 0.85); }
  60%  { opacity: calc(var(--bo, 0.85) * 0.5); }
  80%  { opacity: calc(var(--bo, 0.85) * 0.78); }
  100% { opacity: calc(var(--bo, 0.85) * 0.28); }
}
/* caustics */
.ao-caustics { position: absolute; inset: -22%; mix-blend-mode: screen; opacity: 0.9;
  background:
    radial-gradient(36% 30% at 22% 16%, color-mix(in srgb, var(--sky-200) 18%, transparent), transparent 60%),
    radial-gradient(30% 26% at 68% 30%, color-mix(in srgb, var(--sky-300) 14%, transparent), transparent 62%),
    radial-gradient(40% 30% at 46% 66%, color-mix(in srgb, var(--sky-100) 11%, transparent), transparent 64%),
    radial-gradient(26% 22% at 84% 72%, color-mix(in srgb, var(--sky-200) 10%, transparent), transparent 62%);
  animation: aoCaustic 24s ease-in-out infinite alternate; will-change: transform; }
@keyframes aoCaustic {
  0%   { transform: translateX(0) scale(1); }
  50%  { transform: translateX(2.5%) scale(1.09); }
  100% { transform: translateX(-2%) scale(1.04); }
}
/* bubbles + marine snow */
.ao-bubbles, .ao-snow { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.ao-bubble { position: absolute; bottom: -24px; border-radius: 50%; background: color-mix(in srgb, var(--sky-200) 16%, transparent); box-shadow: inset 0 0 4px color-mix(in srgb, var(--ocean-ink) 25%, transparent); animation: aoRise linear infinite; will-change: transform, opacity; }
@keyframes aoRise { 0% { transform: translateY(0) translateX(0) scale(0.7); opacity: 0; } 12% { opacity: 0.5; } 100% { transform: translateY(-105vh) translateX(var(--dx,20px)) scale(1.1); opacity: 0; } }
.ao-flake { position: absolute; top: -6vh; border-radius: 50%; background: color-mix(in srgb, var(--sky-100) 50%, transparent); box-shadow: 0 0 3px color-mix(in srgb, var(--sky-200) 40%, transparent); animation: aoSnow linear infinite; will-change: transform, opacity; }
@keyframes aoSnow { 0% { transform: translateY(0) translateX(0); opacity: 0; } 12% { opacity: 0.7; } 88% { opacity: 0.5; } 100% { transform: translateY(118vh) translateX(var(--dx, 14px)); opacity: 0; } }
/* ════ SEA LIFE — manta (upper) + whale shark (lower), lighten-blended ════ */
.ao-creatures { position: fixed; inset: 0; width: 100vw; height: 100vh; height: 100dvh; z-index: 0; pointer-events: none; overflow: hidden; }
.ao-creatures::before { content: ''; position: absolute; inset: 0; background: var(--ocean-bg); }
.ao-manta { position: absolute; left: 0; top: 0; width: 230px; max-width: 52vw; max-height: 42vh; -o-object-fit: contain; object-fit: contain; mix-blend-mode: lighten;
  -webkit-mask-image: radial-gradient(66% 48% at 50% 40%, black 34%, transparent 76%); mask-image: radial-gradient(66% 48% at 50% 40%, black 34%, transparent 76%);
  animation: aoMantaSwim 60s ease-in-out infinite; will-change: left, top, transform; }
@keyframes aoMantaSwim {
  0%   { left: -12vw; top: 9vh;  transform: rotate(-5deg); }
  14%  { left: 8vw;   top: 22vh; transform: rotate(4deg); }
  28%  { left: 22vw;  top: 8vh;  transform: rotate(-3deg); }
  42%  { left: 8vw;   top: 24vh; transform: rotate(5deg); }
  56%  { left: 70vw;  top: 11vh; transform: rotate(-2deg); }
  70%  { left: 84vw;  top: 26vh; transform: rotate(5deg); }
  85%  { left: 64vw;  top: 14vh; transform: rotate(-4deg); }
  100% { left: -12vw; top: 9vh;  transform: rotate(-5deg); }
}
@media (prefers-reduced-motion: reduce) { .ao-manta { animation: none; left: 6vw; top: 14vh; } }
.ao-whale { position: absolute; left: 0; top: 0; width: 560px; max-width: 80vw; max-height: 60vh; -o-object-fit: contain; object-fit: contain; mix-blend-mode: lighten;
  -webkit-mask-image: radial-gradient(58% 50% at 50% 46%, black 36%, transparent 80%); mask-image: radial-gradient(58% 50% at 50% 46%, black 36%, transparent 80%);
  transform-origin: center; opacity: var(--whale-fade); animation: aoWhaleSwim 96s linear infinite; will-change: left, top, transform, opacity; }
@keyframes aoWhaleSwim {
  0%   { left: 100vw; top: 62vh; transform: scale(0.55) rotate(3deg);  --whale-fade: 0; }
  10%  { --whale-fade: 0.55; }
  20%  { left: 66vw;  top: 56vh; transform: scale(0.8) rotate(-2deg); --whale-fade: 0.9; }
  46%  { left: 30vw;  top: 66vh; transform: scale(1.32) rotate(2deg);  --whale-fade: 1; }
  72%  { left: -2vw;  top: 58vh; transform: scale(0.95) rotate(-3deg); --whale-fade: 0.85; }
  90%  { left: -34vw; top: 64vh; transform: scale(0.65) rotate(2deg);  --whale-fade: 0.4; }
  100% { left: -60vw; top: 66vh; transform: scale(0.55) rotate(3deg);  --whale-fade: 0; }
}
@media (prefers-reduced-motion: reduce) { .ao-whale { animation: none; left: 12vw; top: 58vh; transform: scale(1.05); --whale-fade: 0.9; } }
/* ════ NAV (bare, top) ════ */
.ao-topnav { position: fixed; top: 0; left: 0; right: 0; z-index: 30; display: flex; align-items: center; justify-content: space-between; padding: 22px 40px; }
.ao-brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; }
/* The DiveOS tile-with-waves mark, painted in currentColor through an alpha
   mask (images/diveos/brand-mark.svg — the same geometry the layout used to
   inline twice). Propshaft rewrites the url() to the digested asset path. */
.ao-brand-mark { display: block; flex: none; width: 30px; height: 30px; background: currentColor;
  -webkit-mask: url("/assets/diveos/brand-mark-f13480df.svg") center / contain no-repeat;
  mask: url("/assets/diveos/brand-mark-f13480df.svg") center / contain no-repeat; }
.ao-hero-brand .ao-brand-mark { width: 34px; height: 34px; }
/* Way back to the marketing site — outlined pill, same shape as the site's
   own Sign in button so the two read as one product. */
.ao-back { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 16px 0 12px;
  border-radius: 999px; border: 1px solid var(--ocean-pill-border); background: var(--ocean-pill-bg);
  /* dark glass: the bar sits on the LIGHTEST band of the ocean gradient,
     where a white-on-white pill was unreadable */ backdrop-filter: blur(10px);
  color: var(--ocean-ink); font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: background 0.25s ease, border-color 0.25s ease; }
.ao-back:hover { background: var(--ocean-pill-bg-h); border-color: var(--ocean-accent); }
.ao-back:focus-visible { outline: 2px solid var(--ocean-accent); outline-offset: 3px; }
.ao-back svg { transition: transform 0.18s cubic-bezier(0.32,0.72,0,1); }
.ao-back:hover svg { transform: translateX(-3px); }
.ao-brand .ao-wm { font-family: var(--font-display); font-weight: 600; font-size: var(--text-lg); letter-spacing: -0.02em; color: var(--ocean-ink); }
/* ════ LAYOUT ════ */
.ao-stage { position: relative; z-index: 10; min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 96px 24px 64px; }
/* Two-column split: form column + brand/hero column. On mobile the whole
   thing collapses to a single centered column (see the <=900px block) and
   the hero panel is hidden. */
.ao-split { width: 100%; max-width: 1120px; display: grid; grid-template-columns: minmax(0, 480px) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px); align-items: center; }
.ao-formcol { display: flex; justify-content: center; }
/* Brand/hero column — owns the ocean visual with the wordmark + tagline. */
.ao-hero { display: flex; flex-direction: column; justify-content: center; gap: 22px; padding: 8px 8px 8px 0; }
.ao-hero-brand { display: inline-flex; align-items: center; gap: 13px; }
.ao-hero-brand .ao-wm { font-family: var(--font-display); font-weight: 600; font-size: clamp(var(--text-xl), 2.4vw, var(--text-3xl)); letter-spacing: -0.02em; color: var(--ocean-ink); }
.ao-hero-eyebrow { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 500; text-transform: uppercase; letter-spacing: 0.22em; color: var(--ocean-accent); }
.ao-hero-title { font-family: var(--font-display); font-weight: 600; font-size: clamp(var(--text-3xl), 3.6vw, 48px); line-height: 1.08; letter-spacing: -0.025em; color: var(--ocean-ink); margin: 0; max-width: 15ch; text-wrap: balance; text-shadow: 0 2px 30px var(--text-glow); }
.ao-hero-tag { font-size: clamp(var(--text-sm), 1.3vw, var(--text-md)); line-height: 1.6; color: var(--ocean-dim); margin: 0; max-width: 46ch; text-shadow: 0 1px 18px var(--text-glow); }
/* ════ SIGN-IN CARD ════ */
.ao-card { position: relative; width: 100%; max-width: 480px; border-radius: 22px; padding: clamp(28px, 3.4vw, 42px) clamp(24px, 3vw, 42px) clamp(26px, 2.8vw, 38px);
  background: var(--glass-bg); border: 1px solid var(--glass-border); box-shadow: var(--glass-shadow);
  backdrop-filter: blur(var(--card-blur)) saturate(150%); -webkit-backdrop-filter: blur(var(--card-blur)) saturate(150%);
  animation: aoCardIn 0.7s cubic-bezier(0.32,0.72,0,1) both; }
@keyframes aoCardIn { from { opacity: 0; transform: translateY(22px) scale(0.985); } to { opacity: 1; transform: none; } }
.ao-card-head { text-align: center; padding-bottom: 28px; margin-bottom: 28px; border-bottom: 1px solid var(--hairline-soft); }
.ao-card-glyph { display: inline-flex; }
/* Card-head glyph: the brand mark at 46px, painted in the ocean accent. The
   card glyph was always drawn with a rounder corner (rx 26 vs the nav/hero
   rx 24), so it masks its own faithfully-extracted asset. */
.ao-card-glyph .ao-brand-mark { width: 46px; height: 46px; color: var(--ocean-accent);
  -webkit-mask-image: url("/assets/diveos/brand-mark-card-4bb5ea88.svg");
  mask-image: url("/assets/diveos/brand-mark-card-4bb5ea88.svg"); }
.ao-card-eyebrow { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 500; text-transform: uppercase; letter-spacing: 0.22em; color: var(--ocean-accent); margin-top: 16px; }
.ao-card-title { font-family: var(--font-display); font-weight: 600; font-size: var(--text-2xl); letter-spacing: -0.02em; color: var(--title-color); margin: 10px 0 0; }
.ao-card-sub { font-size: var(--text-sm); color: var(--ocean-dim); margin-top: 8px; }
.ao-alert { border-radius: 12px; padding: 12px 14px; margin-bottom: 20px; font-size: var(--text-sm); line-height: 1.45;
  border: 1px solid color-mix(in srgb, var(--ocean-ink) 16%, transparent); background: color-mix(in srgb, var(--ocean-trench) 42%, transparent); color: var(--ocean-ink); }
.ao-alert--error { border-color: color-mix(in srgb, var(--red-400) 50%, transparent); background: color-mix(in srgb, color-mix(in srgb, var(--red-900) 63%, black) 42%, transparent); color: var(--red-200); }
.ao-alert ul { margin: 0; padding-left: 18px; }
.ao-field { margin-bottom: 18px; }
.ao-field > label, .ao-field-label-row > label { display: block; font-size: var(--text-xs); font-weight: 500; letter-spacing: 0.01em; color: var(--ocean-dim); margin-bottom: 8px; }
.ao-input-wrap { position: relative; display: flex; align-items: center; }
.ao-input-wrap .ao-lead { position: absolute; left: 14px; color: var(--ocean-faint); display: inline-flex; pointer-events: none; transition: color 0.15s; }
.ao-input-wrap:focus-within .ao-lead { color: var(--ocean-accent); }
/* Leading padding follows the ICON, it does not assume one. Sign-in puts
   an .ao-lead in every wrap; the trial form has none, and a blanket 42px
   left it with a column of dead space down the whole form. */
.ao-field input { width: 100%; height: 48px; padding: 0 14px; border-radius: 10px; border: 1px solid var(--field-border);
  background: var(--field-bg); color: var(--ocean-ink); font-family: var(--font-sans); font-size: var(--text-md); line-height: 1;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s; outline: none; }
.ao-input-wrap:has(.ao-lead) input { padding-left: 42px; }
/* Select matches the input shell exactly — same height, radius, border,
   focus ring — so a mixed form reads as one control set. The native arrow
   is replaced by the canonical Lucide chevron-down path (m6 9 6 6 6-6),
   copied verbatim, used as an alpha MASK on the wrap's ::after so its colour
   comes from a token (a background-image data URI can't take var()). */
.ao-field select { width: 100%; height: 48px; padding: 0 40px 0 14px; border-radius: 10px; border: 1px solid var(--field-border);
  background-color: var(--field-bg); color: var(--ocean-ink); font-family: var(--font-sans); font-size: var(--text-md); line-height: 1;
  transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s; outline: none; cursor: pointer;
  -moz-appearance: none;
       appearance: none; -webkit-appearance: none; background-image: none; }
/* drop the forms-plugin arrow */
.ao-input-wrap:has(> select)::after { content: ''; position: absolute; right: 12px; width: 18px; height: 18px; pointer-events: none;
  background: var(--ocean-chevron);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat; }
.ao-field select:hover { border-color: var(--field-border-h); }
.ao-field select:focus { border-color: var(--field-border-f); box-shadow: var(--field-ring); }
/* The native popup renders in the OS's own palette, which is light on
   macOS/Windows — inheriting the form's near-white text would leave the
   list unreadable. */
.ao-field select option { color: var(--ink); background: var(--surface); }
.ao-field input[type="password"], .ao-field input.ao-has-toggle { padding-right: 46px; }
.ao-field input::-moz-placeholder { color: color-mix(in srgb, var(--ocean-ink) 36%, transparent); }
.ao-field input::placeholder { color: color-mix(in srgb, var(--ocean-ink) 36%, transparent); }
.ao-field input:hover { border-color: var(--field-border-h); }
.ao-field input:focus { border-color: var(--field-border-f); box-shadow: var(--field-ring); background: color-mix(in srgb, var(--ocean-trench) 55%, transparent); }
.ao-pw-toggle { position: absolute; right: 8px; height: 34px; width: 34px; display: grid; place-items: center; border: none; background: transparent; color: var(--ocean-faint); border-radius: 8px; cursor: pointer; transition: color 0.15s, background 0.15s; }
.ao-pw-toggle:hover { color: var(--ocean-ink); background: color-mix(in srgb, var(--ocean-ink) 6%, transparent); }
/* Both eye glyphs render server-side; the reveal toggles .is-revealed. */
.ao-pw-toggle.is-revealed .ao-pw-toggle__show,
.ao-pw-toggle:not(.is-revealed) .ao-pw-toggle__hide { display: none; }
/* Field hint + optional marker. Both were USED by the trial form and
   defined nowhere, so hints inherited body size — "At least 12
   characters." rendered as large as the question it belongs to — and
   "optional" read as part of the label rather than a qualifier. */
.ao-field-hint { font-size: var(--text-xs); line-height: 1.45; color: var(--ocean-faint); margin: 6px 0 0; }
.ao-optional { font-size: var(--text-xs); font-weight: 400; color: var(--ocean-faint); text-transform: lowercase; margin-left: 4px; }
/* Off-screen spam trap (bots fill it, people never see it). */
.ao-honeypot { position: absolute; left: -9999px; }
.ao-field-label-row { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--space-2); }
.ao-field-label-row > label { margin-bottom: 0; }
.ao-forgot { font-size: var(--text-xs); font-weight: 500; color: var(--ocean-accent); transition: color 0.15s; }
.ao-forgot:hover { color: var(--ocean-accent-strong); }
.ao-remember { display: flex; align-items: center; gap: 10px; margin: 4px 0 26px; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; user-select: none; font-size: var(--text-sm); color: var(--ocean-dim); }
.ao-remember input { position: absolute; opacity: 0; width: 0; height: 0; }
.ao-remember .ao-box { width: 18px; height: 18px; border-radius: 5px; border: 1px solid var(--field-border-h); background: var(--field-bg); display: grid; place-items: center; flex: none; transition: background 0.15s, border-color 0.15s; }
.ao-remember .ao-box svg { opacity: 0; transform: scale(0.6); transition: opacity 0.15s, transform 0.15s; color: var(--btn-solid-fg); }
.ao-remember input:checked + .ao-box { background: var(--btn-solid-bg); border-color: var(--btn-solid-bg); }
.ao-remember input:checked + .ao-box svg { opacity: 1; transform: none; }
.ao-remember input:focus-visible + .ao-box { box-shadow: 0 0 0 3px color-mix(in srgb, var(--sky-400) 22%, transparent); }
.ao-btn-signin { width: 100%; height: 50px; border-radius: 11px; border: none; cursor: pointer;
  background: var(--btn-solid-bg); color: var(--btn-solid-fg); box-shadow: var(--btn-solid-shadow);
  font-family: var(--font-sans); font-size: var(--text-md); font-weight: 600; letter-spacing: -0.01em;
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  transition: background 0.15s, transform 0.1s, box-shadow 0.2s; }
.ao-btn-signin:hover { background: var(--btn-solid-bg-h); }
.ao-btn-signin:active { transform: translateY(1px); }
.ao-btn-signin svg { transition: transform 0.18s cubic-bezier(0.32,0.72,0,1); }
.ao-btn-signin:hover svg { transform: translateX(3px); }
.ao-card-foot { text-align: center; font-size: var(--text-sm); color: var(--ocean-faint); margin-top: 24px; }
.ao-card-foot a { color: var(--ocean-accent); font-weight: 500; }
.ao-card-foot a:hover { color: var(--ocean-accent-strong); }
@media (prefers-reduced-motion: reduce) {
  .ao-bubble, .ao-flake, .ao-rays, .ao-rays .ao-beam, .ao-caustics, .ao-card { animation: none !important; }
  .ao-card { opacity: 1; transform: none; }
}
/* ── DESKTOP: reveal the two-column split (>= 900px) ── */
@media (min-width: 900px) {
  .ao-topnav .ao-brand { display: none; }  /* brand moves into the hero column; the back link stays */
  .ao-topnav { position: absolute; }       /* scrolls away with the page: fixed, the pill sat over the form
                                              card's top-left corner on the long trial form */
  .ao-stage { padding: 48px 40px; }
  /* The trial card is taller than the viewport, so it top-aligns at the 48px
     padding and sits ~20px under the Back pill; give it the room the shorter
     (vertically centred) auth cards get for free. */
  body.auth-trial-signups .ao-stage { padding-top: 104px; }
}
/* ── TABLET / MOBILE: single centered column, hero hidden (< 900px) ── */
@media (max-width: 899.98px) {
  .ao-split { grid-template-columns: minmax(0, 1fr); max-width: 480px; gap: 0; }
  .ao-hero { display: none; }
  .ao-formcol { justify-content: center; }
}
/* ── PHONE: trim padding + cut GPU cost (< 600px) ── */
@media (max-width: 600px) {
  .ao-topnav { padding: 18px 22px; }
  .ao-stage { padding: 84px 16px 44px; }
  .ao-card { max-width: 100%; }
  /* backdrop-filter is a per-frame GPU cost on phones — drop it and lean on
     a more opaque card tint so the form stays legible without the blur. */
  .ao-card { backdrop-filter: none; -webkit-backdrop-filter: none;
    background: linear-gradient(160deg, color-mix(in srgb, var(--card-top) 90%, transparent), color-mix(in srgb, var(--card-bot) 94%, transparent)); }
}
/* ── PHONE ambience: soften the caustics/vignette overhead ── */
@media (max-width: 760px) {
  .ao-caustics { display: none; }
  .ao-raybloom { filter: blur(28px); }
}
/* ════ PERF-LITE — capability-gated strip of the GPU-heavy layers ════
   Added by the capability detector (see the inline script) as
   `body.perf-lite` when the device is measured to be weak — a runtime FPS
   probe, tiny RAM/CPU, reduced-motion, or the ?lite=1 override. Unlike the
   width media queries above, this fires at ALL widths, so a weak *laptop*
   (wide screen) gets the same relief a phone does. It kills the animated +
   blurred layers and the backdrop-filter, and gives the card an opaque
   tint so the form stays legible without the blur. */
body.perf-lite .ao-rays,
body.perf-lite .ao-raybloom,
body.perf-lite .ao-caustics,
body.perf-lite .ao-bubbles,
body.perf-lite .ao-snow,
body.perf-lite .ao-creatures video { display: none !important; }
body.perf-lite .ao-card {
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  background: linear-gradient(160deg, color-mix(in srgb, var(--card-top) 92%, transparent), color-mix(in srgb, var(--card-bot) 96%, transparent)) !important;
}
/* ════ TAB-HIDDEN — freeze all CSS animation when the tab is backgrounded
   (universal battery/CPU win, not lite-gated). The JS toggles this class
   on <html> via the Page Visibility API and pauses the videos too. ════ */
html.tab-hidden body.auth-ocean *, html.tab-hidden body.auth-ocean *::before, html.tab-hidden body.auth-ocean *::after {
  animation-play-state: paused !important;
}
/* ─────────────────────────────────────────────────────────────────────
   Waiver form — the public diver waiver wizard (#413 design 17A/22A).
   The page is os-ds throughout: header + `.os-callout`, the four-phase
   `.os-progress-spine` (4A), an `.os-card` of fields, and the sticky
   viewport-pinned `.os-wz-foot` action bar, all inside the
   `.os-density--touch` scope. What remains here is the medical
   questionnaire's answer tiles (#349, rebuilt in B1.6). `.waiver-wizard`
   is the page scope (public/waiver_forms/steps/_step_shell).
   Token-clean; never leaks into account/*.
   ───────────────────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
  /* Retained for layouts/engine.html.erb, which still widens its header and
     footer when a page sets content_for(:engine_shell_wide). No waiver step
     sets it since the single-column rewrite (#413 B1.5). */
  /* Widens the engine header + footer to 63rem with the content flush to
     the box edge (the old rail + form shell's width). */
  :is(.engine-shell-wide, .os-engine-shell-wide) {
    max-width: 63rem;
    /* !important: Tailwind's utility layer (px-4/sm:px-6, also on this element)
       is reordered to always win over plain CSS regardless of source order, so
       a bare override here is silently ignored without it. */
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
}
/* ── Medical questionnaire: forced Yes/No per question (#349) ──────────
   The answer is the tap target, not the row — a stray tap on the question
   text can no longer declare a medical condition. Both targets clear 44px. */
:is(.waiver-medical-q, .os-waiver-medical-q) {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface);
  padding: 1rem;
  margin: 0;
}
:is(.waiver-medical-q, .os-waiver-medical-q).is-invalid {
  border-color: var(--cancelled-border, var(--hairline-strong));
}
:is(.waiver-medical-q__legend, .os-waiver-medical-q__legend) {
  padding: 0;
}
:is(.waiver-medical-q__answers, .os-waiver-medical-q__answers) {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.75rem;
}
:is(.waiver-medical-answer, .os-waiver-medical-answer) {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem; /* 48px — the DiveOS touch-target floor (Fitts's Law) */
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface);
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease;
}
:is(.waiver-medical-answer, .os-waiver-medical-answer):hover {
  background-color: var(--surface-alt);
}
/* The native input stays in the accessibility tree (keyboard + screen reader
   reach it, and it is what actually posts) but the label is the visible
   control. */
:is(.waiver-medical-answer__input, .os-waiver-medical-answer__input) {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
:is(.waiver-medical-answer__label, .os-waiver-medical-answer__label) {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--muted-2);
}
:is(.waiver-medical-answer, .os-waiver-medical-answer):has(:checked) {
  border-color: var(--accent);
  background-color: var(--accent-soft);
}
:is(.waiver-medical-answer, .os-waiver-medical-answer):has(:checked)
  :is(.waiver-medical-answer__label, .os-waiver-medical-answer__label) {
  color: var(--accent);
  font-weight: 600;
}
:is(.waiver-medical-answer, .os-waiver-medical-answer):has(:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* #413 21A — a DMSC "Go to box" question nests its Box inside its own
   fieldset, indented on a hairline rail so it reads as a follow-up to the
   question above, not a new section. */
.waiver-medical-q__number {
  font-variant-numeric: tabular-nums;
  margin-right: 0.25rem;
}
.waiver-medical-box {
  margin-top: 1rem;
  padding-left: 1rem;
  border-left: 2px solid var(--hairline-strong);
}
.waiver-medical-box[hidden],
[data-dmsc-callout][hidden] {
  display: none;
}
.waiver-medical-q--nested {
  background-color: var(--surface-alt);
}
:is(.waiver-medical-none, .os-waiver-medical-none) {
  /* #411 — composes .os-field-check (the box + label text) into a full-width
     tile: one tap anywhere on it toggles, and it clears the 48px touch floor
     for the phones and tablets at the dive-centre counter. */
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 3rem;
  margin-top: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface);
  transition: background-color 120ms ease, border-color 120ms ease;
}
/* Revealed by the medical-questionnaire controller on connect. The component's
   own display would otherwise out-rank the UA `[hidden]` rule. */
:is(.waiver-medical-none, .os-waiver-medical-none)[hidden] {
  display: none;
}
:is(.waiver-medical-none, .os-waiver-medical-none):hover {
  border-color: var(--hairline-strong);
}
:is(.waiver-medical-none, .os-waiver-medical-none):has(:checked) {
  border-color: var(--accent);
  background-color: var(--accent-soft);
}
/* ── #413 5A — template documents in page flow ─────────────────────────
   Markdown output (headings from h3, paragraphs, lists, bold/italic) at a
   readable 45–75ch measure. Heading roles mirror .os-h4 / .os-h5. */
.waiver-document {
  max-width: 68ch;
}
.waiver-document > * + * {
  margin-top: 0.75rem;
}
.waiver-document h3 {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: var(--leading-lg);
  color: var(--ink);
  margin-top: 1.5rem;
}
.waiver-document :is(h4, h5, h6) {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  line-height: var(--leading-md);
  color: var(--ink);
  margin-top: 1.25rem;
}
.waiver-document ul {
  list-style: disc;
  padding-left: 1.25rem;
}
.waiver-document ol {
  list-style: decimal;
  padding-left: 1.25rem;
}
.waiver-document li + li {
  margin-top: 0.25rem;
}
/* The ack is the one control on a document step: a full-width tile clearing
   the 48px touch floor, like the medical "None of the above" tile. */
.waiver-document-ack {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 3rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface);
}
.waiver-document-ack:has(:checked) {
  border-color: var(--accent);
  background-color: var(--accent-soft);
}
.waiver-document-ack.is-invalid {
  border-color: var(--cancelled-border, var(--hairline-strong));
}
[data-media-consent-target][hidden] {
  display: none;
}
/* ── #413 8A / 22A — Review & sign pads on the os-ds signpad ────────── */
.waiver-signpad__modes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.waiver-signpad__modes .os-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background-color: var(--accent-soft);
  color: var(--accent);
}
.waiver-signpad__canvas {
  display: block;
  width: 100%;
  height: 150px;
  touch-action: none;
}
.waiver-signpad .os-signpad__pad {
  place-items: stretch;
  background: var(--surface);
}
.waiver-signpad__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
/* The "Signed" line shows only in the signed state (the check tile already
   follows os-signpad--signed). */
.waiver-signpad__signed {
  display: none;
}
.os-signpad--signed .waiver-signpad__signed {
  display: inline;
}
/* ── #413 3A — staff waiver page signatures ─────────────────────────── */
.waiver-signature-image {
  max-width: 300px;
  height: auto;
  padding: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface);
}
/* A typed signature reads as a signature, not as form data. */
.waiver-signature-typed {
  display: inline-block;
  padding: 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface);
  font-family: "Brush Script MT", cursive;
  font-size: var(--text-2xl);
  line-height: var(--leading-2xl);
  color: var(--ink);
}
/* ── #413 3A / 7A — staff clearance rail ───────────────────────────── */
.waiver-clearance + * {
  margin-top: 1.5rem;
}
.waiver-clearance__preview {
  display: block;
  width: 100%;
  max-height: 16rem;
  -o-object-fit: contain;
     object-fit: contain;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md, 8px);
  background-color: var(--surface-alt);
}
/* Public packages storefront (/book/:shop/packages) — a public marketing page.
   Uses DiveOS foundation (.dv-btn / .dv-badge / .dv-eyebrow / .dv-* text styles
   + semantic tokens) wherever it maps; keeps bespoke bc-* ONLY for the
   marketing-specific layout (photo-mosaic hero, photo-overlay cards, full-bleed
   gallery) that has no foundation equivalent. */
:is(.bc, .os-bc) {
  /* Local marketing vars mapped onto DiveOS semantic tokens (closest match). */
  --nk: var(--ink);
  --tx: var(--gray-600);
  --mut: var(--muted);
  --mut2: var(--muted-2);
  --line: var(--hairline);
  --line2: var(--surface-alt);
  --bg: #E9F1FA;              /* marketing blue page tint — no foundation token */
  --surf: var(--surface);
  --acc: var(--accent);
  --acc-strong: var(--accent-strong);
  --acc-soft: var(--accent-soft);
  background: var(--bg);
  color: var(--tx);
  -webkit-font-smoothing: antialiased;
}
:is(.bc, .os-bc) * { box-sizing: border-box; }
:is(.bc-wrap, .os-bc-wrap) { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
/* Marketing weights: headings heavier (700) + buttons 600, matching the
   Packages Handover (the foundation defaults are 600 / 500). */
:is(.bc, .os-bc) :is(.dv-display, .os-display), :is(.bc, .os-bc) :is(.dv-h2, .os-h2), :is(.bc, .os-bc) :is(.dv-h3, .os-h3), :is(.bc, .os-bc) :is(.dv-h4, .os-h4) { font-weight: 700; }
:is(.bc, .os-bc) :is(.dv-btn, .os-btn) { font-weight: 600; }
/* Keep an eyebrow's icon + text on one line. */
:is(.bc, .os-bc) :is(.dv-eyebrow, .os-eyebrow) { display: inline-flex; align-items: center; gap: 6px; }
/* Two-tone marketing headings: the <em> highlight uses the accent. */
:is(.bc, .os-bc) :is(.dv-display, .os-display) em, :is(.bc, .os-bc) :is(.dv-h2, .os-h2) em, :is(.bc, .os-bc) :is(.dv-h3, .os-h3) em { color: var(--accent); font-style: normal; }
/* Marketing hero heading runs larger than the app display scale. */
:is(.bc-hm-card, .os-bc-hm-card) :is(.dv-display, .os-display) { font-size: 40px; line-height: 1.08; }
:is(.bc-sub, .os-bc-sub) { color: var(--mut); max-width: 560px; margin: 12px auto 0; }
/* Full-width buttons in card / offering feet. */
:is(.bc-card-foot, .os-bc-card-foot) :is(.dv-btn, .os-btn), :is(.bc-off-body, .os-bc-off-body) :is(.dv-btn, .os-btn) { width: 100%; }
/* checklist */
:is(.mkt-checks, .os-mkt-checks) { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; text-align: left; }
:is(.mkt-checks, .os-mkt-checks) li { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; color: var(--tx); line-height: 1.45; }
:is(.mkt-checks, .os-mkt-checks) li svg { color: var(--acc); flex: none; margin-top: 1px; }
/* nav */
:is(.bc-nav, .os-bc-nav) { position: sticky; top: 0; z-index: 40; background: rgba(219,233,247,.82); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
:is(.bc-nav, .os-bc-nav) :is(.bc-wrap, .os-bc-wrap) { display: flex; align-items: center; gap: 20px; height: 68px; }
:is(.bc-brand, .os-bc-brand) { display: flex; align-items: center; gap: 10px; }
:is(.bc-brand__mark, .os-bc-brand__mark) { width: 38px; height: 38px; border-radius: 10px; background: var(--acc); color: #fff; display: flex; align-items: center; justify-content: center; flex: none; }
:is(.bc-brand__logo, .os-bc-brand__logo) { height: 38px; width: auto; max-width: 150px; -o-object-fit: contain; object-fit: contain; flex: none; }
:is(.bc-brand__name, .os-bc-brand__name) { color: var(--nk); font-weight: 700; font-size: 16px; line-height: 1.05; }
:is(.bc-brand__tag, .os-bc-brand__tag) { display: block; font-size: 10px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--mut2); }
:is(.bc-navcta, .os-bc-navcta) { margin-left: auto; display: flex; align-items: center; gap: 18px; }
:is(.bc-phone, .os-bc-phone) { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--mut); }
/* hero mosaic */
:is(.bc-hm, .os-bc-hm) { background: transparent; padding: 44px 0 8px; }
:is(.bc-hm-inner, .os-bc-hm-inner) { position: relative; max-width: 1280px; margin: 0 auto; padding: 0 24px; }
:is(.bc-hm-mosaic, .os-bc-hm-mosaic) { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 238px; gap: 14px; }
:is(.bc-hm-tile, .os-bc-hm-tile) { position: relative; border-radius: 18px; overflow: hidden; background: var(--line2); }
:is(.bc-hm-tile, .os-bc-hm-tile) img { width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; display: block; }
:is(.bc-hm-tile, .os-bc-hm-tile):is(.bc-hm-t1, .os-bc-hm-t1) { grid-column: span 2; grid-row: span 2; }
:is(.bc-hm-tile, .os-bc-hm-tile):is(.bc-hm-t4, .os-bc-hm-t4) { grid-column: span 2; }
:is(.bc-hm-cap, .os-bc-hm-cap) { position: absolute; left: 14px; bottom: 14px; font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: #fff; background: rgba(15,23,42,.55); padding: 5px 11px; border-radius: 999px; backdrop-filter: blur(4px); }
:is(.bc-hm-card, .os-bc-hm-card) { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 460px; max-width: calc(100% - 120px); background: var(--surf); border-radius: 22px; box-shadow: 0 24px 70px rgba(15,23,42,.20); padding: 36px; text-align: center; }
:is(.bc-hm-card, .os-bc-hm-card) :is(.dv-display, .os-display) { margin-top: 12px; }
:is(.bc-hm-card, .os-bc-hm-card) p { color: var(--tx); font-size: 16px; line-height: 1.6; margin: 16px auto 0; max-width: 400px; }
:is(.bc-hm-cta, .os-bc-hm-cta) { display: flex; gap: 12px; margin-top: 26px; flex-wrap: wrap; justify-content: center; }
/* trust strip */
:is(.bc-strip, .os-bc-strip) { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--bg); margin-top: 24px; }
:is(.bc-strip, .os-bc-strip) :is(.bc-wrap, .os-bc-wrap) { display: flex; flex-wrap: wrap; justify-content: center; gap: 28px; padding: 16px 24px; }
:is(.bc-strip, .os-bc-strip) span { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--mut); }
:is(.bc-strip, .os-bc-strip) svg { color: var(--acc); }
/* section shell */
:is(.bc-sec, .os-bc-sec) { padding: 68px 0; }
:is(.bc-head, .os-bc-head) { text-align: center; max-width: 640px; margin: 0 auto 40px; }
/* package cards */
:is(.bc-grid, .os-bc-grid) { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; align-items: stretch; }
:is(.bc-card, .os-bc-card) { display: flex; flex-direction: column; height: 100%; background: var(--surf); border: 1px solid var(--line); border-radius: 20px; overflow: hidden; box-shadow: 0 12px 30px rgba(15,23,42,.05); transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s ease, border-color .3s ease; }
:is(.bc-card, .os-bc-card).is-feat { border: 2px solid var(--acc); box-shadow: 0 22px 55px rgba(3,105,161,.14); }
/* Photo hero extends behind the title + price (white), over a dark gradient. */
:is(.bc-card-media, .os-bc-card-media) { position: relative; height: 340px; background: var(--line2); overflow: hidden; }
:is(.bc-card-media, .os-bc-card-media) img { width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; display: block; transition: transform 1.1s cubic-bezier(.16,.68,.24,1); }
:is(.bc-card-scrim, .os-bc-card-scrim) { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(15,23,42,0) 22%, rgba(15,23,42,.18) 46%, rgba(15,23,42,.62) 74%, rgba(15,23,42,.86) 100%); transition: opacity .3s ease; }
:is(.bc-card-hero, .os-bc-card-hero) { transition: transform .3s cubic-bezier(.2,.7,.2,1); }
/* Immersive hover: card lifts, photo slow-zooms, title/price rise, gradient deepens. */
:is(.bc-card, .os-bc-card):hover { transform: translateY(-8px); box-shadow: 0 34px 70px rgba(15,23,42,.18); }
:is(.bc-card, .os-bc-card).is-feat:hover { box-shadow: 0 36px 78px rgba(3,105,161,.26); }
:is(.bc-card, .os-bc-card):not(.is-feat):hover { border-color: var(--acc); }
:is(.bc-card, .os-bc-card):hover :is(.bc-card-media, .os-bc-card-media) img { transform: scale(1.1); }
:is(.bc-card, .os-bc-card):hover :is(.bc-card-scrim, .os-bc-card-scrim) { opacity: .82; }
:is(.bc-card, .os-bc-card):hover :is(.bc-card-hero, .os-bc-card-hero) { transform: translateY(-4px); }
@media (prefers-reduced-motion: reduce) {
  :is(.bc-card, .os-bc-card), :is(.bc-card-media, .os-bc-card-media) img, :is(.bc-card-hero, .os-bc-card-hero), :is(.bc-card-scrim, .os-bc-card-scrim) { transition: none; }
  :is(.bc-card, .os-bc-card):hover { transform: none; }
  :is(.bc-card, .os-bc-card):hover :is(.bc-card-media, .os-bc-card-media) img { transform: none; }
}
:is(.bc-days-chip, .os-bc-days-chip) { position: absolute; top: 14px; left: 14px; z-index: 2; font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--nk); background: rgba(255,255,255,.92); padding: 4px 10px; border-radius: 999px; backdrop-filter: blur(4px); }
:is(.bc-card-ribbon, .os-bc-card-ribbon) { position: absolute; top: 14px; right: 14px; z-index: 2; }
:is(.bc-card-hero, .os-bc-card-hero) { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 0 22px 24px; text-align: center; color: #fff; }
:is(.bc-card-title, .os-bc-card-title) { color: #fff; font-weight: 700; letter-spacing: -.02em; font-size: 18px; line-height: 1.25; margin: 0; }
:is(.bc-card-price, .os-bc-card-price) { margin-top: 8px; }
:is(.bc-card-price, .os-bc-card-price) b { display: block; color: #fff; font-size: 32px; font-weight: 800; letter-spacing: -.02em; line-height: 1; }
:is(.bc-card-price, .os-bc-card-price) span { display: block; font-size: 12px; color: rgba(255,255,255,.82); margin-top: 5px; }
:is(.bc-card-body, .os-bc-card-body) { display: flex; flex-direction: column; flex: 1; padding: 22px 24px 24px; }
:is(.bc-card-blurb, .os-bc-card-blurb) { color: var(--mut); font-size: 14px; line-height: 1.5; margin: 0 0 16px; text-align: center; }
:is(.bc-card-cat, .os-bc-card-cat) { text-align: center; color: var(--acc); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 8px; }
/* Per-category browse catalogue (Fun Dives / Try Dives / Courses) — reuses the
   storefront package grid + card; only the back link is bespoke. */
:is(.bc-back, .os-bc-back) { display: inline-flex; align-items: center; gap: 6px; color: var(--acc); }
/* 12px, not 13px: a muted meta line sits one step under the 14px blurb, and
   12px is already the meta size elsewhere in this sheet (.bc-card-price span).
   13px was the only value in this file outside the accepted baseline. */
:is(.bc-card-loc, .os-bc-card-loc) { display: inline-flex; align-items: center; justify-content: center; gap: 6px; color: var(--mut); font-size: 12px; margin: 0 auto 16px; }
:is(.bc-card-loc, .os-bc-card-loc) svg { color: var(--acc); flex: none; }
:is(.bc-card-foot, .os-bc-card-foot) { margin-top: auto; padding-top: 22px; }
/* instagram / gallery — full bleed */
:is(.bc-gram, .os-bc-gram) { padding: 44px 0 60px; }
:is(.bc-gram-head, .os-bc-gram-head) { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 22px; }
:is(.bc-gram-head, .os-bc-gram-head) h2 { margin-top: 8px; }
:is(.bc-gram-head, .os-bc-gram-head) p { color: var(--mut); font-size: 15px; margin: 8px 0 0; }
:is(.bc-gram-grid, .os-bc-gram-grid) { display: grid; grid-template-columns: repeat(8, 1fr); gap: 8px; }
:is(.bc-gram-grid, .os-bc-gram-grid):is(.full, .os-full) { grid-template-columns: repeat(8, 1fr); }
:is(.bc-gram-tile, .os-bc-gram-tile) { position: relative; aspect-ratio: 1; overflow: hidden; background: var(--line2); display: block; }
:is(.bc-gram-tile, .os-bc-gram-tile) img { width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.7,.2,1); }
:is(.bc-gram-ov, .os-bc-gram-ov) { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; opacity: 0; background: rgba(3,105,161,.4); transition: opacity .25s ease; }
:is(.bc-gram-tile, .os-bc-gram-tile):hover :is(.bc-gram-ov, .os-bc-gram-ov) { opacity: 1; }
:is(.bc-gram-tile, .os-bc-gram-tile):hover img { transform: scale(1.1); }
@media (prefers-reduced-motion: reduce) { :is(.bc-gram-tile, .os-bc-gram-tile) img { transition: none; } :is(.bc-gram-tile, .os-bc-gram-tile):hover img { transform: none; } }
/* custom quote */
:is(.bc-cust, .os-bc-cust) { background: var(--bg); }
:is(.bc-cust, .os-bc-cust) :is(.bc-wrap, .os-bc-wrap) { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: center; padding-top: 56px; padding-bottom: 56px; }
:is(.bc-cust-media, .os-bc-cust-media) { aspect-ratio: 4/3; border-radius: 20px; overflow: hidden; background: var(--line2); }
:is(.bc-cust-media, .os-bc-cust-media) img { width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; display: block; }
:is(.bc-cust, .os-bc-cust) h2 { margin-top: 12px; }
:is(.bc-cust, .os-bc-cust) p { color: var(--tx); font-size: 16px; line-height: 1.6; margin: 16px 0 0; }
:is(.bc-cust-actions, .os-bc-cust-actions) { display: flex; gap: 12px; margin-top: 24px; flex-wrap: wrap; }
/* offerings */
:is(.bc-off-grid, .os-bc-off-grid) { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
:is(.bc-off-card, .os-bc-off-card) { display: flex; flex-direction: column; background: var(--surf); border: 1px solid var(--line); border-radius: 20px; overflow: hidden; }
:is(.bc-off-media, .os-bc-off-media) { position: relative; height: 150px; background: var(--line2); }
:is(.bc-off-media, .os-bc-off-media) img { width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; display: block; }
:is(.bc-off-tag, .os-bc-off-tag) { position: absolute; top: 12px; left: 12px; }
:is(.bc-off-body, .os-bc-off-body) { display: flex; flex-direction: column; flex: 1; padding: 20px; }
:is(.bc-off-body, .os-bc-off-body) p { color: var(--mut); font-size: 14px; line-height: 1.55; margin: 10px 0 18px; flex: 1; }
/* footer */
:is(.bc-foot, .os-bc-foot) { border-top: 1px solid var(--line); background: #D8E6F4; padding: 56px 0 0; }
:is(.bc-foot-grid, .os-bc-foot-grid) { display: grid; grid-template-columns: 1.6fr 1fr; gap: 40px; }
:is(.bc-foot-desc, .os-bc-foot-desc) { color: var(--mut); font-size: 14px; line-height: 1.6; margin: 16px 0 0; max-width: 360px; }
:is(.bc-foot-h, .os-bc-foot-h) { color: var(--nk); font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 16px; }
:is(.bc-contact, .os-bc-contact) { display: flex; gap: 10px; margin-bottom: 13px; font-size: 14px; color: var(--tx); align-items: flex-start; }
:is(.bc-contact, .os-bc-contact) svg { color: var(--acc); flex: none; margin-top: 2px; }
:is(.bc-foot-bottom, .os-bc-foot-bottom) { border-top: 1px solid var(--line); margin-top: 44px; padding: 22px 0; display: flex; align-items: center; justify-content: space-between; font-size: 12.5px; color: var(--mut2); }
:is(.bc-foot-bottom, .os-bc-foot-bottom) :is(.dv-figure, .os-figure) { letter-spacing: .08em; }
@media (max-width: 960px) {
  /* Roomier edge gutters on smaller screens. */
  :is(.bc-wrap, .os-bc-wrap), :is(.bc-hm-inner, .os-bc-hm-inner) { padding-left: 32px; padding-right: 32px; }
  :is(.bc-hm-card, .os-bc-hm-card) { position: static; transform: none; width: 100%; max-width: none; margin-top: 16px; box-shadow: 0 12px 30px rgba(15,23,42,.1); }
  :is(.bc-grid, .os-bc-grid), :is(.bc-off-grid, .os-bc-off-grid), :is(.bc-foot-grid, .os-bc-foot-grid) { grid-template-columns: 1fr; }
  :is(.bc-cust, .os-bc-cust) :is(.bc-wrap, .os-bc-wrap) { grid-template-columns: 1fr; }
  :is(.bc-gram-grid, .os-bc-gram-grid), :is(.bc-gram-grid, .os-bc-gram-grid):is(.full, .os-full) { grid-template-columns: repeat(4, 1fr); }
  :is(.bc-hm-mosaic, .os-bc-hm-mosaic) { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 150px; }
  :is(.bc-hm-tile, .os-bc-hm-tile):is(.bc-hm-t1, .os-bc-hm-t1), :is(.bc-hm-tile, .os-bc-hm-tile):is(.bc-hm-t4, .os-bc-hm-t4) { grid-column: span 2; grid-row: auto; }
}
/* Public guest-facing pages (waiver forms, entry pages, guest registration)
   aligned to the redesigned public booking funnel + receipt pages.
   Reuse os-ds components first; only page-composition glue lives here.
   Tokens only (var(--token)), no naked hex, no dark mode. */
:root {
  --guest-rail-col: 16rem; /* waiver wizard sticky left rail column */
  --guest-hero-copy-max: 34rem; /* sky-hero trip-head copy measure */
  --guest-narrow-max: 300px; /* narrow guest-page text block cap */
  --guest-phone-code-col: 7.5rem; /* phone row country-code column */
}
/* ── Waiver forms ─────────────────────────────────────────── */
/* Wizard shell. Phone/tablet: one column — the eyebrow, "Why we ask" (first
   step only), the funnel's horizontal stepper, then the form card.
   Desktop ≥1024: the shell breaks out of the 48rem engine column to 63rem
   (header + footer widen to match via content_for :engine_shell_wide) as a
   sticky left rail + the form column; the column header + stepper hide. */
.waiver-rail { display: none; }
/* #98 — the autofocus controller focuses the step heading on load so screen
   readers announce the new step. It's not interactive (tabindex -1), so no
   focus ring — keyboard users still get rings on every real control. */
.waiver-wizard [tabindex="-1"]:focus { outline: none; box-shadow: none; }
/* Progress bar sits flush under the site header: pull it up over the engine
   main's top padding (py-6 → 1.5rem, sm:py-8 → 2rem). */
body:has(.waiver-wizard) .waiver-wizard .bw-funnel-stepper { margin-top: calc(-1 * var(--space-6)); }
@media (min-width: 640px) { body:has(.waiver-wizard) .waiver-wizard .bw-funnel-stepper { margin-top: calc(-1 * var(--space-8)); } }
/* Phone/tablet progress: "Step N of M · <step>" over the os-ds stepper bars.
   The bars' own labels are visually hidden (kept for assistive tech). */
.waiver-progress-bar__meta { display: flex; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); }
.waiver-progress-bar .wz-couple { padding: 0; }
.waiver-progress-bar .wz-bars, .waiver-progress-bar .wz-bars-inner { max-width: none; padding: 0; }
.waiver-progress-bar .wz-seg .lbrow {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
@media (max-width: 1023px) {
  .waiver-why--later { display: none; }
}
/* The pinned action bar (os-ds `.os-wz-foot--pinned`, fixed full-bleed band):
   its buttons sit on the waiver SHELL's edges at every width: the engine
   column (48rem, 1rem / 1.5rem gutters) below 1024, the rail + form shell
   (--waiver-shell-w) from 1024. */
.waiver-wizard { --os-wz-foot-gutter: var(--space-4); --os-wz-foot-max: calc(48rem - 2 * var(--space-6)); }
@media (min-width: 640px) {
  .waiver-wizard { --os-wz-foot-gutter: var(--space-6); }
}
@media (min-width: 1024px) {
  .waiver-shell {
    --waiver-shell-w: min(63rem, calc(100vw - var(--space-12)));
    --os-wz-foot-max: var(--waiver-shell-w);
    display: grid;
    grid-template-columns: var(--guest-rail-col) minmax(0, 1fr);
    gap: var(--space-10);
    width: var(--waiver-shell-w);
    margin-inline: calc((100% - var(--waiver-shell-w)) / 2);
  }
  .waiver-rail { display: block; }
  .waiver-rail__inner {
    position: sticky;
    top: var(--space-6);
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
  }
  .waiver-rail .pkb-vrail { position: static; }
  .waiver-rail__why { padding-top: var(--space-5); border-top: 1px solid var(--hairline); }
  .waiver-main .waiver-why,
  .waiver-main .bw-funnel-stepper { display: none; }
}
/* Phone: give the form the height. The site header scrolls away; the progress
   bar stays at the top. The action bar is the os-ds pinned footer. */
@media (max-width: 640px) {
  body:has(.waiver-wizard) .engine-header { position: static; }
  /* The progress bar stays pinned to the top while the header scrolls away. */
  body:has(.waiver-wizard) .waiver-wizard .bw-funnel-stepper { top: 0; margin-bottom: var(--space-2); padding-block: var(--space-3); }
}
/* The form column starts flush with the rail: no stray offset above the first
   block (the autofocus wrapper's mt-2, and space-y-6 counting the form's hidden
   inputs as a preceding sibling). !important: Tailwind utilities always win. */
.waiver-main > [data-controller~="autofocus"] { margin-top: 0 !important; }
.waiver-main .wizard-step-form > input[type="hidden"] + :not(input[type="hidden"]) { margin-top: 0 !important; }
/* Medical questions — grouped by spacing, not boxes (Practical UI: lightest
   cue), laid out with gap only: header · notice · answer-all · questions are
   32px apart, tighter inside each block. Each question is a plain block with
   the compact Yes / No pair under it. DMSC follow-up boxes keep their tint. */
.waiver-medical { display: flex; flex-direction: column; gap: var(--space-10); }
.waiver-medical__intro { display: flex; flex-direction: column; gap: var(--space-4); }
.waiver-medical__head { display: flex; flex-direction: column; gap: var(--space-1); }
.waiver-medical__questions { display: flex; flex-direction: column; gap: var(--space-6); }
/* The answers' rhythm — None of the above + each question. 24px; try 16px
   (--space-4) if it reads too airy. */
.waiver-medical-qs { display: flex; flex-direction: column; gap: var(--waiver-q-gap, var(--space-6)); }
/* None of the above is a shortcut, not a question: a filled tile with no
   outline, so it reads apart from the outlined Yes / No answers. Ticked, it
   takes the accent selection like an answer. */
.waiver-medical .waiver-medical-none { margin-top: 0; background-color: var(--surface-alt); border-color: transparent; }
.waiver-medical .waiver-medical-none:hover { border-color: var(--hairline-strong); }
.waiver-medical .waiver-medical-none:has(:checked) { background-color: var(--accent-soft); border-color: var(--accent); }
.waiver-wizard .waiver-medical-q:not(.waiver-medical-q--nested) {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.waiver-wizard .waiver-medical-q__answers { max-width: var(--width-xs); }
/* Question = 16px medium (os-body-lg at the label weight); its hint is
   os-body (14px) muted, 4px under it. */
.waiver-medical-q__legend { font-weight: 500; color: var(--ink); }
.waiver-medical-q__hint { margin-top: var(--space-1); color: var(--muted); }
.waiver-wizard .waiver-medical-q.is-invalid .waiver-medical-answer { border-color: var(--cancelled-border); }
/* Waiver start + signed pages — the booking-detail "editorial sky" hero
   (sky head + diver illustration + layered waveband + sky body), reused via the
   .bk-detail scope so its rules aren't duplicated. */
.pg-sky-hero { overflow: hidden; }
.pg-sky-hero .bd2-trip-head { padding: var(--space-8) var(--space-6) var(--space-5); }
.pg-sky-hero .bd2-trip-head .diver { top: var(--space-2); right: var(--space-4); }
.pg-sky-hero .bd2-trip-head > :not(.diver) { position: relative; z-index: 2; max-width: var(--guest-hero-copy-max); }
.pg-sky-hero .bd2-trip-body { padding: var(--space-2) var(--space-6) var(--space-6); gap: var(--space-4); }
.pg-hero-state { display: flex; align-items: center; gap: var(--space-2); }
/* State pages (signed / expired / doctor's form): a quieter hero — title on
   the h3 role with the status icon, smaller illustration. */
.pg-sky-hero--compact .bd2-trip-head { padding: var(--space-6); }
.pg-sky-hero--compact .bd2-trip-head .diver { transform: scale(0.6); }
.pg-start-list { display: flex; flex-direction: column; gap: var(--space-4); }
.pg-start-list li { display: flex; align-items: flex-start; gap: var(--space-3); }
.pg-start-list .pg-start-ic {
  display: inline-flex; flex: none; align-items: center; justify-content: center;
  width: var(--space-8); height: var(--space-8);
  border-radius: var(--radius-pill); background: var(--accent-soft); color: var(--accent);
}
@media (max-width: 640px) {
  .pg-sky-hero .bd2-trip-head { padding: var(--space-6) var(--space-4) var(--space-4); }
  .pg-sky-hero .bd2-trip-head .diver { transform: scale(0.7); right: calc(-1 * var(--space-6)); }
  .pg-sky-hero .bd2-trip-body { padding: var(--space-2) var(--space-4) var(--space-4); }
}
/* Signed-waiver detail card: the diver's drawn / typed signature specimen. */
.waiver-sig-preview {
  display: inline-block;
  max-width: var(--guest-narrow-max);
  height: auto;
  padding: var(--space-2);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--surface-alt);
}
.waiver-sig-preview--typed {
  display: block;
  max-width: none;
  padding: var(--space-3);
  color: var(--ink);
  font-family: 'Brush Script MT', cursive;
  font-size: var(--text-2xl);
}
/* ── Entry pages (landing / browse / packages / storefront) ── */
/* Landing search card + its date popover: os-card resets padding, so the
   inset lives here (16 → 20px from sm up, as before). */
.os-card.pg-search-card { padding: var(--space-4); }
@media (min-width: 640px) { .os-card.pg-search-card { padding: var(--space-5); } }
/* ── Guest registration ───────────────────────────────────── */
/* One vertical rhythm between every block in a form section — the two-column
   rows and the contact fieldset aren't .os-field siblings, so the os-ds
   stacking margin skipped them (uneven gaps). Each section is its own os-card
   on the hero's sky body, grouped by spacing — no in-card dividers. */
.pg-guest-form { display: flex; flex-direction: column; gap: var(--space-4); }
.pg-guest-form .os-card__body > :is(.os-field, .grid, fieldset, .os-hint) + :is(.os-field, .grid, fieldset, .os-hint) { margin-top: var(--space-5); }
.pg-guest-form .os-card__body > .grid + .os-hint { margin-top: var(--space-2); }
/* Phone: the cards sit inside the hero's sky inset, so trim their own inset
   to give the fields the width. */
@media (max-width: 640px) {
  .pg-guest-form .os-card__head,
  .pg-guest-form .os-card__body { padding-inline: var(--space-4); }
}
/* Paired fields: inputs bottom-align even when one label wraps. */
.pg-guest-pair > .os-field { display: flex; flex-direction: column; }
.pg-guest-pair > .os-field > .os-input { margin-top: auto; }
/* Phone: compact dial-code select, the number field gets the rest. */
.pg-phone-row { display: flex; gap: var(--space-2); }
.pg-phone-row > :first-child { flex: none; width: var(--guest-phone-code-col); }
/* DiveOS — segmented control selected state.
   The BT `shared/fields/buttons` partial (Status, Chop level, etc.) is used
   unejected, so its selected button paints in the BT default blue (#3b82f6).
   Re-point it at the DiveOS accent so the app has ONE accent color, not two. */
:is(.btn-toggle, .os-btn-toggle):has(input:checked) :is(.button-alternative, .os-button-alternative) {
  background-color: var(--accent) !important;
  border-color: var(--accent) !important;
  color: #fff !important;
}
:is(.btn-toggle, .os-btn-toggle):has(input:checked) :is(.button-alternative, .os-button-alternative):hover {
  background-color: var(--accent-strong, var(--accent)) !important;
}
/* DiveOS — BT primary button (the `.button` token emitted by
   `first_button_primary`, used by ~47 scaffolded CTAs like "Add Dive Trip")
   defaults to the BT blue #3b82f6. Hand-written DiveOS CTAs use explicit
   bg-accent, so the two clash. Re-point the primary to the DiveOS accent. The
   `.button` token is distinct from `.button-secondary`/`.button-alternative`,
   so those variants are untouched. */
a:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)), button:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)) {
  background-color: var(--accent) !important;
  border-color: var(--accent) !important;
}
a:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover, button:is(.button, .os-button):not(:is(.button-secondary, .os-button-secondary)):not(:is(.button-alternative, .os-button-alternative)):hover {
  background-color: var(--accent-strong, var(--accent)) !important;
}
/* Dashboard Layout Containers */
:is(.dashboard-upper-container, .os-dashboard-upper-container) {
  /* margin-bottom: 32px !important; */
}
/* Margins between sections in the lower dashboard container */
:is(.dashboard-lower-container, .os-dashboard-lower-container)>* {
  margin-bottom: 32px !important;
}
:is(.dashboard-lower-container, .os-dashboard-lower-container)>*:last-child {
  margin-bottom: 0 !important;
}
/* Table Improvements */
:is(.table, .os-table) {
  background-color: transparent;
  border-collapse: separate;
  /* Required for sticky header borders and box-shadow */
  border-spacing: 0;
}
/* Zebra Striping - Light Mode */
:is(.table-striped, .os-table-striped) tbody tr:nth-child(even) {
  background-color: rgba(0, 0, 0, 0.02);
}
:is(.table-striped, .os-table-striped) tbody tr:nth-child(odd) {
  background-color: transparent;
}
/* --- Sticky Header ---
   Fixes the header to the top of the table container for vertical scrolling.
*/
/* Sticky Header */
:is(.table, .os-table) thead th {
  position: sticky;
  top: 0;
  z-index: 20;
  background-color: white;
  transition: box-shadow 0.2s ease;
  border-bottom: 1px solid #e5e7eb;
}
/* Ensure the sentinel doesn't affect layout */
:is(.sticky-sentinel, .os-sticky-sentinel) {
  height: 1px;
  width: 100%;
  margin-top: -1px;
  visibility: hidden;
  pointer-events: none;
}
/* --- Dual Sticky Columns ---
   Fixes the Checkbox (1st) and Name (2nd) columns to the left for horizontal scrolling.
   DESKTOP ONLY (min-width: 769px): below that the table collapses to a card
   stack (no horizontal scroll), where these z-index:25-31 sticky cells served
   no purpose and painted OVER the sticky page header while scrolling.
*/
@media (min-width: 769px) {
/* Dual Sticky Columns (Checkbox + Identity) */

/* Column 1 (Checkbox) - No shadow on this one */
:is(.table, .os-table) thead th:nth-child(1), :is(.table, .os-table) tbody td:nth-child(1) {
  position: sticky;
  left: 0;
  z-index: 26;
  background-color: white;
}

/* Column 2 (Name/Identity) - This one carries the shadow */
:is(.table, .os-table) thead th:nth-child(2) {
  position: sticky;
  z-index: 25;
  background-color: white;
}

:is(.table, .os-table) tbody td:nth-child(2) {
  position: sticky;
  z-index: 25;
  background-color: white;
  overflow: visible;
}

:is(.table, .os-table) thead th:nth-child(2) {
  z-index: 31;
}
}
/* --- Column Shadow (Left Side) ---
   Creates a vertical indicator line on the edge of the second (sticky) column.
   Toggled by the Stimulus controller when horizontal scroll is > 0.
*/
/* Shadow line when horizontally scrolled (on child 2) - Continuous Line effect */
:is(.table, .os-table) thead th:nth-child(2)::after, :is(.table, .os-table) tbody td:nth-child(2)::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 1px;
  background: transparent;
  transition: all 0.2s ease;
  pointer-events: none;
  z-index: 100;
}
/* --- Light Mode Shadow --- */
.has-horizontal-shadow :is(.table, .os-table) thead th:nth-child(2)::after, .has-horizontal-shadow :is(.table, .os-table) tbody td:nth-child(2)::after {
  /* This controls the slightly visible 1px line on the edge of the column */
  background: rgba(91, 91, 91, 0.1);

  /* This controls the actual "glow/shadow" effect (offset-x, offset-y, blur, color) */
  box-shadow: 1px 0 12px rgba(41, 41, 41, 0.5);
}
/* --- Container Shadow (Right Side) ---
   Persistent indicator on the right edge of the container to show hidden content.
   Toggled by the Stimulus controller and fixed to the parent container boundary.
*/
/* --- Persistent Right-side Scroll Indicator Shadow --- */
/* The parent of the scroll container needs relative positioning for the fixed overlay */
:is(.table-scroll-container--can-scroll-right, .os-table-scroll-container--can-scroll-right) {
  position: relative;
}
:is(.table-scroll-container--can-scroll-right, .os-table-scroll-container--can-scroll-right)::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100px;
  pointer-events: none;
  z-index: 40;
  transition: opacity 0.3s ease;
  opacity: 1;
  /* Persistent until end */
  box-shadow: none;
  /* Reduced alpha values (0.6 -> 0.3) for more transparency */
  background: #ffffff;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 90%, rgba(255, 255, 255, 1) 100%);
}
/* --- Background Overrides for Sticky Columns ---
   Sticky columns must have a solid background color (opaque) so that 
   the rest of the table content doesn't "bleed through" behind them.
*/
/* Solid backgrounds for all rows in sticky group */
:is(.table, .os-table) tbody tr td:nth-child(1), :is(.table, .os-table) tbody tr td:nth-child(2) {
  background-color: white;
}
/* Striped overrides */
:is(.table-striped, .os-table-striped) tbody tr:nth-child(even) td:nth-child(1), :is(.table-striped, .os-table-striped) tbody tr:nth-child(even) td:nth-child(2) {
  background-color: #f9fafb;
}
/* Hover highlights */
:is(.table, .os-table) tbody tr:hover td, :is(.table, .os-table) tbody tr:hover td:nth-child(1), :is(.table, .os-table) tbody tr:hover td:nth-child(2) {
  background-color: #ebf1fd;
}
/* Pin the primary body base to 14px (DiveOS --text-sm). Named text roles
   override per patterns.css; this stops stray/unstyled text defaulting to the
   BT theme base (15/16px). */
body { font-size: var(--text-sm); }
/* GEM DEFECT (os-ds v1.3.0) — os_ds/components/profile_row.css builds the
   `.os-profile-row__avatar` gradient from `var(--teal-900)`, a token os-ds
   never defines. An unresolvable var() voids the WHOLE `background`
   declaration, so the avatar disc renders with no fill and its white initials
   disappear. Supply the primitive here, set to DiveOS's previous avatar stop
   (--sky-900) so the roster gradient is unchanged by the migration.
   DELETE this once os-ds defines --teal-900 (or switches to --sky-900).
   Must stay BELOW every @import: postcss-import silently drops any @import
   that follows a non-@import statement. */
:root { --teal-900: var(--sky-900); }
.\*\:bg-gray-100 > *{
  --tw-bg-opacity: 1;
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.\*\:bg-white > *{
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
}
.file\:mr-4::file-selector-button{
  margin-right: 1rem;
}
.file\:rounded-md::file-selector-button{
  border-radius: 0.375rem;
}
.file\:border-0::file-selector-button{
  border-width: 0px;
}
.file\:bg-accent-soft::file-selector-button{
  background-color: var(--accent-soft, rgba(3,105,161,0.08));
}
.file\:px-4::file-selector-button{
  padding-left: 1rem;
  padding-right: 1rem;
}
.file\:py-2::file-selector-button{
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.file\:text-sm::file-selector-button{
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.file\:font-medium::file-selector-button{
  font-weight: 500;
}
.file\:text-accent::file-selector-button{
  color: var(--accent, #0369A1);
}
.placeholder\:font-sans::-moz-placeholder{
  font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
.placeholder\:font-sans::placeholder{
  font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
.placeholder\:text-muted-2::-moz-placeholder{
  color: var(--muted-2, #9CA3AF);
}
.placeholder\:text-muted-2::placeholder{
  color: var(--muted-2, #9CA3AF);
}
.first\:mt-0:first-child{
  margin-top: 0px;
}
.first\:border-t-0:first-child{
  border-top-width: 0px;
}
.first\:pl-5:first-child{
  padding-left: 1.25rem;
}
.first\:pt-0:first-child{
  padding-top: 0px;
}
.last\:mb-0:last-child{
  margin-bottom: 0px;
}
.last\:border-0:last-child{
  border-width: 0px;
}
.last\:border-b-0:last-child{
  border-bottom-width: 0px;
}
.last\:pb-0:last-child{
  padding-bottom: 0px;
}
.last\:pr-5:last-child{
  padding-right: 1.25rem;
}
.empty\:hidden:empty{
  display: none;
}
.focus-within\:bg-\[var\(--hover-warm\)\]:focus-within{
  background-color: var(--hover-warm);
}
.hover\:border-accent:hover{
  border-color: var(--accent, #0369A1);
}
.hover\:border-confirmed-border:hover{
  border-color: var(--confirmed-border, #BBF7D0);
}
.hover\:bg-\[var\(--hover-warm\)\]:hover{
  background-color: var(--hover-warm);
}
.hover\:bg-accent:hover{
  background-color: var(--accent, #0369A1);
}
.hover\:bg-accent-soft:hover{
  background-color: var(--accent-soft, rgba(3,105,161,0.08));
}
.hover\:bg-accent-strong:hover{
  background-color: var(--accent-strong, #075985);
}
.hover\:bg-base-200:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
.hover\:bg-base-50:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1));
}
.hover\:bg-blue-400:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(96 165 250 / var(--tw-bg-opacity, 1));
}
.hover\:bg-blue-50:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1));
}
.hover\:bg-blue-700:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
}
.hover\:bg-briefing-bg:hover{
  background-color: var(--briefing-bg, #FFFBEB);
}
.hover\:bg-cancelled-bg:hover{
  background-color: var(--cancelled-bg, #FFF1F2);
}
.hover\:bg-canvas:hover{
  background-color: var(--canvas, #F9FAFB);
}
.hover\:bg-confirmed:hover{
  background-color: var(--confirmed, #15803D);
}
.hover\:bg-confirmed-bg:hover{
  background-color: var(--confirmed-bg, #F0FDF4);
}
.hover\:bg-gray-100:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.hover\:bg-gray-50:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
}
.hover\:bg-hairline:hover{
  background-color: var(--hairline, #E5E7EB);
}
.hover\:bg-primary-600:hover{
  background-color: var(--primary-600);
}
.hover\:bg-red-600:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.hover\:bg-slate-100:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1));
}
.hover\:bg-slate-50:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1));
}
.hover\:bg-surface:hover{
  background-color: var(--surface, #FFFFFF);
}
.hover\:bg-surface-alt:hover{
  background-color: var(--surface-alt, #F3F4F6);
}
.hover\:bg-white:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
}
.hover\:bg-white\/10:hover{
  background-color: rgb(255 255 255 / 0.1);
}
.hover\:text-accent:hover{
  color: var(--accent, #0369A1);
}
.hover\:text-accent-strong:hover{
  color: var(--accent-strong, #075985);
}
.hover\:text-base-500:hover{
  --tw-text-opacity: 1;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1));
}
.hover\:text-base-700:hover{
  --tw-text-opacity: 1;
  color: rgb(51 65 85 / var(--tw-text-opacity, 1));
}
.hover\:text-base-900:hover{
  --tw-text-opacity: 1;
  color: rgb(15 23 42 / var(--tw-text-opacity, 1));
}
.hover\:text-blue-500:hover{
  --tw-text-opacity: 1;
  color: rgb(59 130 246 / var(--tw-text-opacity, 1));
}
.hover\:text-blue-600:hover{
  --tw-text-opacity: 1;
  color: rgb(37 99 235 / var(--tw-text-opacity, 1));
}
.hover\:text-blue-800:hover{
  --tw-text-opacity: 1;
  color: rgb(30 64 175 / var(--tw-text-opacity, 1));
}
.hover\:text-blue-900:hover{
  --tw-text-opacity: 1;
  color: rgb(30 58 138 / var(--tw-text-opacity, 1));
}
.hover\:text-cancelled:hover{
  color: var(--cancelled, #9F1239);
}
.hover\:text-confirmed:hover{
  color: var(--confirmed, #15803D);
}
.hover\:text-gray-400:hover{
  --tw-text-opacity: 1;
  color: rgb(156 163 175 / var(--tw-text-opacity, 1));
}
.hover\:text-ink:hover{
  color: var(--ink, #111827);
}
.hover\:text-muted:hover{
  color: var(--muted, #6B7280);
}
.hover\:text-primary-600:hover{
  color: var(--primary-600);
}
.hover\:text-red-800:hover{
  --tw-text-opacity: 1;
  color: rgb(153 27 27 / var(--tw-text-opacity, 1));
}
.hover\:text-secondary-600:hover{
  color: var(--secondary-600);
}
.hover\:text-white:hover{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.hover\:underline:hover{
  text-decoration-line: underline;
}
.hover\:no-underline:hover{
  text-decoration-line: none;
}
.hover\:opacity-80:hover{
  opacity: 0.8;
}
.hover\:opacity-90:hover{
  opacity: 0.9;
}
.hover\:shadow-inner:hover{
  --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.hover\:shadow-sm:hover{
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.hover\:ring-2:hover{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.hover\:ring-accent:hover{
  --tw-ring-color: var(--accent, #0369A1);
}
.hover\:file\:bg-accent-soft::file-selector-button:hover{
  background-color: var(--accent-soft, rgba(3,105,161,0.08));
}
.focus\:border-accent:focus{
  border-color: var(--accent, #0369A1);
}
.focus\:border-accent-strong:focus{
  border-color: var(--accent-strong, #075985);
}
.focus\:border-blue-400:focus{
  --tw-border-opacity: 1;
  border-color: rgb(96 165 250 / var(--tw-border-opacity, 1));
}
.focus\:border-primary-500:focus{
  border-color: var(--primary-500);
}
.focus\:border-red-500:focus{
  --tw-border-opacity: 1;
  border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
}
.focus\:bg-canvas:focus{
  background-color: var(--canvas, #F9FAFB);
}
.focus\:shadow:focus{
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.focus\:outline-none:focus{
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.focus\:outline-2:focus{
  outline-width: 2px;
}
.focus\:-outline-offset-2:focus{
  outline-offset: -2px;
}
.focus\:outline-accent:focus{
  outline-color: var(--accent, #0369A1);
}
.focus\:outline-blue-600:focus{
  outline-color: #2563eb;
}
.focus\:ring:focus{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-2:focus{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-inset:focus{
  --tw-ring-inset: inset;
}
.focus\:ring-accent:focus{
  --tw-ring-color: var(--accent, #0369A1);
}
.focus\:ring-blue-200:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(191 219 254 / var(--tw-ring-opacity, 1));
}
.focus\:ring-blue-500:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
}
.focus\:ring-primary-500:focus{
  --tw-ring-color: var(--primary-500);
}
.focus\:ring-primary-600:focus{
  --tw-ring-color: var(--primary-600);
}
.focus\:ring-red-500:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1));
}
.focus\:ring-white:focus{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity, 1));
}
.focus\:ring-opacity-50:focus{
  --tw-ring-opacity: 0.5;
}
.focus\:ring-offset-0:focus{
  --tw-ring-offset-width: 0px;
}
.focus\:ring-offset-2:focus{
  --tw-ring-offset-width: 2px;
}
.focus-visible\:outline:focus-visible{
  outline-style: solid;
}
.focus-visible\:outline-2:focus-visible{
  outline-width: 2px;
}
.focus-visible\:outline-\[var\(--accent-strong\)\]:focus-visible{
  outline-color: var(--accent-strong);
}
.active\:cursor-grabbing:active{
  cursor: grabbing;
}
.disabled\:bg-base-200:disabled{
  --tw-bg-opacity: 1;
  background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
}
.disabled\:bg-canvas:disabled{
  background-color: var(--canvas, #F9FAFB);
}
.disabled\:opacity-60:disabled{
  opacity: 0.6;
}
.disabled\:dark:disabled .pcr-app{
  border-width: 1px;
  border-style: solid;
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled .pcr-app .pcr-interaction .pcr-result{
  border-width: 1px;
  border-style: solid;
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .pcr-app .pcr-interaction .pcr-result:focus {
          box-shadow: 0 0 0 1px var(--primary-500), 0 0 0 3px var(--primary-500);
        }
.disabled\:dark:disabled .daterangepicker{
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled .daterangepicker::before {
        border-bottom-color: #0f172a;
      }
.disabled\:dark:disabled .daterangepicker::after {
        border-bottom-color: #1e293b;
      }
.disabled\:dark:disabled .daterangepicker .calendar-table{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .daterangepicker .calendar-table .available span{
  border-color: var(--primary-500);
}
.disabled\:dark:disabled .daterangepicker .drp-buttons {
        border-top-color: #0f172a;
        --tw-text-opacity: 1;
        color: rgb(203 213 225 / var(--tw-text-opacity, 1));
      }
.disabled\:dark:disabled .daterangepicker th.available:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(71 85 105 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled .daterangepicker td.off{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .daterangepicker td.available:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(71 85 105 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled .daterangepicker .hourselect,.disabled\:dark:disabled .daterangepicker .minuteselect,.disabled\:dark:disabled .daterangepicker .ampmselect{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
  --tw-text-opacity: 1 !important;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1)) !important;
}
.disabled\:dark:disabled .iti__country-list{
  border-width: 1px;
  border-style: solid;
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled .select2-container .select2-selection__rendered{
  --tw-text-opacity: 1 !important;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1)) !important;
}
.disabled\:dark:disabled .select2-container .select2-dropdown{
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled .select2-container .select2-search__field{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.disabled\:dark:disabled .select2-container .select2-selection--multiple,.disabled\:dark:disabled .select2-container .select2-selection--single{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.disabled\:dark:disabled .select2-container .select2-selection--multiple:focus,.disabled\:dark:disabled .select2-container .select2-selection--single:focus{
  --tw-ring-color: var(--primary-500) !important;
}
.disabled\:dark:disabled .select2-container .select2-selection--multiple,.disabled\:dark:disabled .select2-container .select2-selection--single{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.disabled\:dark:disabled .select2-container .select2-selection--multiple:focus,.disabled\:dark:disabled .select2-container .select2-selection--single:focus{
  --tw-ring-color: var(--primary-500) !important;
}
.disabled\:dark:disabled .select2-container .select2-selection--multiple,.disabled\:dark:disabled .select2-container .select2-selection--single{
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .select2-container .select2-selection__choice{
  border-color: var(--primary-500) !important;
  background-color: var(--primary-500) !important;
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .select2-container .select2-selection__choice .select2-selection__choice__remove{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .select2-container .select2-selection__choice .select2-selection__choice__remove:hover{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .select2-container .select2-results__option{
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled trix-editor{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.disabled\:dark:disabled trix-editor:focus,.disabled\:dark:disabled trix-editor:active{
  border-color: var(--primary-500) !important;
}
.disabled\:dark:disabled trix-toolbar{
  opacity: 0.5 !important;
}
.disabled\:dark:disabled trix-toolbar.visible{
  opacity: 1 !important;
}
.disabled\:dark:disabled trix-toolbar .trix-button-group,.disabled\:dark:disabled trix-toolbar .trix-button{
  --tw-border-opacity: 1 !important;
  border-color: rgb(148 163 184 / var(--tw-border-opacity, 1)) !important;
}
.disabled\:dark:disabled trix-toolbar .trix-button:disabled::before{
  opacity: 0.25;
}
.disabled\:dark:disabled trix-toolbar .trix-dialog{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1) !important;
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
  --tw-shadow-color: #0f172a !important;
  --tw-shadow: var(--tw-shadow-colored) !important;
}
.disabled\:dark:disabled trix-toolbar .trix-dialog .trix-button--dialog{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled trix-toolbar .trix-dialog .trix-input--dialog{
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.disabled\:dark:disabled trix-toolbar .trix-dialog .trix-input--dialog:focus{
  border-color: var(--primary-500);
  --tw-ring-color: var(--primary-500);
}
.disabled\:dark:disabled trix-toolbar .trix-dialog .trix-input--dialog:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .tribute-container ul{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.disabled\:dark:disabled .trix-dialogs{
  --tw-border-opacity: 1 !important;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1)) !important;
  --tw-bg-opacity: 1 !important;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)) !important;
}
.disabled\:dark:disabled .trix-content a[href^="bullettrain://"]{
  --tw-bg-opacity: 1;
  background-color: rgb(100 116 139 / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.disabled\:dark:disabled .ck {
      --ck-color-base-background: #1e293b;
      --ck-color-base-border: #0f172a;
      --ck-color-toolbar-background: #1e293b;
      --ck-color-toolbar-border: #0f172a;
      --ck-color-text: #cbd5e1;
    }
.disabled\:dark:disabled .ck .ck-editor__editable:not(.ck-editor__nested-editable){
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.disabled\:dark:disabled .ck .ck-editor__editable:not(.ck-editor__nested-editable).ck-focused{
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.disabled\:\[--code-editor-background\:theme\(\'colors\.base\.200\'\)\]:disabled{
  --code-editor-background: #e2e8f0;
}
.group[open] .group-open\:hidden{
  display: none;
}
.group:hover .group-hover\:visible{
  visibility: visible;
}
.group\/item:hover .group-hover\/item\:translate-x-3{
  --tw-translate-x: 0.75rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.group:hover .group-hover\:translate-x-3{
  --tw-translate-x: 0.75rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.group:hover .group-hover\:translate-y-0{
  --tw-translate-y: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.group:hover .group-hover\:scale-100{
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.group:hover .group-hover\:text-accent{
  color: var(--accent, #0369A1);
}
.group:hover .group-hover\:text-blue-600{
  --tw-text-opacity: 1;
  color: rgb(37 99 235 / var(--tw-text-opacity, 1));
}
.group:hover .group-hover\:text-blue-800{
  --tw-text-opacity: 1;
  color: rgb(30 64 175 / var(--tw-text-opacity, 1));
}
.group:hover .group-hover\:text-white{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.group:hover .group-hover\:underline{
  text-decoration-line: underline;
}
.group:hover .group-hover\:no-underline{
  text-decoration-line: none;
}
.group:hover .group-hover\:opacity-100{
  opacity: 1;
}
.dark .group:hover .group-hover\:visibletrix-toolbar{
  opacity: 1 !important;
}
.peer[open] ~ .peer-open\:hidden{
  display: none;
}
.has-\[\:checked\]\:border-accent:has(:checked){
  border-color: var(--accent, #0369A1);
}
.has-\[\:checked\]\:bg-accent-soft:has(:checked){
  background-color: var(--accent-soft, rgba(3,105,161,0.08));
}
.has-\[\:checked\]\:text-accent:has(:checked){
  color: var(--accent, #0369A1);
}
.has-\[\:focus-visible\]\:ring-2:has(:focus-visible){
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.has-\[\:focus-visible\]\:ring-accent:has(:focus-visible){
  --tw-ring-color: var(--accent, #0369A1);
}
.has-\[\:focus-visible\]\:ring-offset-2:has(:focus-visible){
  --tw-ring-offset-width: 2px;
}
.aria-selected\:border-accent[aria-selected="true"]{
  border-color: var(--accent, #0369A1);
}
.aria-selected\:font-semibold[aria-selected="true"]{
  font-weight: 600;
}
.aria-selected\:text-accent[aria-selected="true"]{
  color: var(--accent, #0369A1);
}
@media (min-width: 640px){
  .sm\:bottom-40{
    bottom: 10rem;
  }
  .sm\:col-span-1{
    grid-column: span 1 / span 1;
  }
  .sm\:col-span-2{
    grid-column: span 2 / span 2;
  }
  .sm\:col-span-3{
    grid-column: span 3 / span 3;
  }
  .sm\:col-span-4{
    grid-column: span 4 / span 4;
  }
  .sm\:col-span-5{
    grid-column: span 5 / span 5;
  }
  .sm\:col-span-7{
    grid-column: span 7 / span 7;
  }
  .sm\:col-span-8{
    grid-column: span 8 / span 8;
  }
  .sm\:col-start-1{
    grid-column-start: 1;
  }
  .sm\:m-10{
    margin: 2.5rem;
  }
  .sm\:mx-4{
    margin-left: 1rem;
    margin-right: 1rem;
  }
  .sm\:mx-auto{
    margin-left: auto;
    margin-right: auto;
  }
  .sm\:mb-0{
    margin-bottom: 0px;
  }
  .sm\:mt-0{
    margin-top: 0px;
  }
  .sm\:block{
    display: block;
  }
  .sm\:inline{
    display: inline;
  }
  .sm\:flex{
    display: flex;
  }
  .sm\:table-cell{
    display: table-cell;
  }
  .sm\:hidden{
    display: none;
  }
  .sm\:w-28{
    width: 7rem;
  }
  .sm\:w-40{
    width: 10rem;
  }
  .sm\:w-44{
    width: 11rem;
  }
  .sm\:w-auto{
    width: auto;
  }
  .sm\:w-full{
    width: 100%;
  }
  .sm\:max-w-md{
    max-width: 28rem;
  }
  .sm\:max-w-sm{
    max-width: 24rem;
  }
  .sm\:flex-shrink-0{
    flex-shrink: 0;
  }
  .sm\:grid-cols-2{
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .sm\:grid-cols-3{
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .sm\:grid-cols-6{
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
  .sm\:grid-cols-\[2fr_1fr\]{
    grid-template-columns: 2fr 1fr;
  }
  .sm\:flex-row{
    flex-direction: row;
  }
  .sm\:items-start{
    align-items: flex-start;
  }
  .sm\:items-end{
    align-items: flex-end;
  }
  .sm\:items-center{
    align-items: center;
  }
  .sm\:justify-end{
    justify-content: flex-end;
  }
  .sm\:justify-between{
    justify-content: space-between;
  }
  .sm\:gap-3{
    gap: 0.75rem;
  }
  .sm\:gap-4{
    gap: 1rem;
  }
  .sm\:rounded-2xl{
    border-radius: 1rem;
  }
  .sm\:rounded-md{
    border-radius: 0.375rem;
  }
  .sm\:bg-white{
    --tw-bg-opacity: 1;
    background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
  }
  .sm\:bg-gradient-to-br{
    background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
  }
  .sm\:p-5{
    padding: 1.25rem;
  }
  .sm\:p-6{
    padding: 1.5rem;
  }
  .sm\:px-12{
    padding-left: 3rem;
    padding-right: 3rem;
  }
  .sm\:px-5{
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }
  .sm\:px-6{
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
  .sm\:py-12{
    padding-top: 3rem;
    padding-bottom: 3rem;
  }
  .sm\:py-14{
    padding-top: 3.5rem;
    padding-bottom: 3.5rem;
  }
  .sm\:py-2{
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
  }
  .sm\:py-4{
    padding-top: 1rem;
    padding-bottom: 1rem;
  }
  .sm\:py-8{
    padding-top: 2rem;
    padding-bottom: 2rem;
  }
  .sm\:pl-0{
    padding-left: 0px;
  }
  .sm\:pl-8{
    padding-left: 2rem;
  }
  .sm\:pr-10{
    padding-right: 2.5rem;
  }
  .sm\:pr-6{
    padding-right: 1.5rem;
  }
  .sm\:text-lg{
    font-size: 1.125rem;
    line-height: 1.75rem;
  }
  .sm\:shadow{
    --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
    --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
  }
}
@media (min-width: 768px){
  .md\:relative{
    position: relative;
  }
  .md\:top-0\.5{
    top: 0.125rem;
  }
  .md\:col-span-2{
    grid-column: span 2 / span 2;
  }
  .md\:col-span-3{
    grid-column: span 3 / span 3;
  }
  .md\:mt-8{
    margin-top: 2rem;
  }
  .md\:block{
    display: block;
  }
  .md\:inline{
    display: inline;
  }
  .md\:flex{
    display: flex;
  }
  .md\:hidden{
    display: none;
  }
  .md\:h-14{
    height: 3.5rem;
  }
  .md\:h-auto{
    height: auto;
  }
  .md\:h-screen{
    height: 100vh;
  }
  .md\:w-1\/4{
    width: 25%;
  }
  .md\:w-14{
    width: 3.5rem;
  }
  .md\:w-2\/5{
    width: 40%;
  }
  .md\:w-3\/5{
    width: 60%;
  }
  .md\:w-80{
    width: 20rem;
  }
  .md\:w-full{
    width: 100%;
  }
  .md\:grid-cols-2{
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .md\:grid-cols-3{
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .md\:grid-cols-4{
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .md\:grid-cols-5{
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
  .md\:grid-cols-6{
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
  .md\:flex-row{
    flex-direction: row;
  }
  .md\:items-center{
    align-items: center;
  }
  .md\:justify-between{
    justify-content: space-between;
  }
  .md\:overflow-y-scroll{
    overflow-y: scroll;
  }
  .md\:rounded-lg{
    border-radius: 0.5rem;
  }
  .md\:rounded-l-lg{
    border-top-left-radius: 0.5rem;
    border-bottom-left-radius: 0.5rem;
  }
  .md\:rounded-t-lg{
    border-top-left-radius: 0.5rem;
    border-top-right-radius: 0.5rem;
  }
  .md\:rounded-tl-lg{
    border-top-left-radius: 0.5rem;
  }
  .md\:border-l-2{
    border-left-width: 2px;
  }
  .md\:border-none{
    border-style: none;
  }
  .md\:bg-gradient-to-br{
    background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
  }
  .md\:p-5{
    padding: 1.25rem;
  }
  .md\:p-8{
    padding: 2rem;
  }
  .md\:text-\[0\.75rem\]{
    font-size: 0.75rem;
  }
  .md\:text-sm{
    font-size: 0.875rem;
    line-height: 1.25rem;
  }
}
@media (min-width: 1024px){
  .lg\:col-span-1{
    grid-column: span 1 / span 1;
  }
  .lg\:m-20{
    margin: 5rem;
  }
  .lg\:-ml-px{
    margin-left: -1px;
  }
  .lg\:-mr-px{
    margin-right: -1px;
  }
  .lg\:-mt-5{
    margin-top: -1.25rem;
  }
  .lg\:mb-0{
    margin-bottom: 0px;
  }
  .lg\:inline-block{
    display: inline-block;
  }
  .lg\:flex{
    display: flex;
  }
  .lg\:hidden{
    display: none;
  }
  .lg\:w-4\/5{
    width: 80%;
  }
  .lg\:w-96{
    width: 24rem;
  }
  .lg\:max-w-md{
    max-width: 28rem;
  }
  .lg\:shrink-0{
    flex-shrink: 0;
  }
  .lg\:grid-cols-2{
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .lg\:grid-cols-3{
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .lg\:grid-cols-4{
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .lg\:grid-cols-\[1fr_320px\]{
    grid-template-columns: 1fr 320px;
  }
  .lg\:rounded-l-none{
    border-top-left-radius: 0px;
    border-bottom-left-radius: 0px;
  }
  .lg\:border-l{
    border-left-width: 1px;
  }
  .lg\:px-4{
    padding-left: 1rem;
    padding-right: 1rem;
  }
}
@media (min-width: 1280px){
  .xl\:col-span-1{
    grid-column: span 1 / span 1;
  }
  .xl\:grid{
    display: grid;
  }
  .xl\:w-52{
    width: 13rem;
  }
  .xl\:w-auto{
    width: auto;
  }
  .xl\:flex-none{
    flex: none;
  }
  .xl\:flex-shrink-0{
    flex-shrink: 0;
  }
  .xl\:flex-row{
    flex-direction: row;
  }
  .xl\:items-start{
    align-items: flex-start;
  }
  .xl\:justify-between{
    justify-content: space-between;
  }
  .xl\:gap-6{
    gap: 1.5rem;
  }
  .xl\:px-8{
    padding-left: 2rem;
    padding-right: 2rem;
  }
  .xl\:py-8{
    padding-top: 2rem;
    padding-bottom: 2rem;
  }
}
.dark\:divide-base-700\/5:where(.dark, .dark *) > :not([hidden]) ~ :not([hidden]){
  border-color: rgb(51 65 85 / 0.05);
}
.dark\:border-base-300\/10:where(.dark, .dark *){
  border-color: rgb(203 213 225 / 0.1);
}
.dark\:border-base-500:where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(100 116 139 / var(--tw-border-opacity, 1));
}
.dark\:border-base-500\/5:where(.dark, .dark *){
  border-color: rgb(100 116 139 / 0.05);
}
.dark\:border-base-600:where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(71 85 105 / var(--tw-border-opacity, 1));
}
.dark\:border-base-900:where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(15 23 42 / var(--tw-border-opacity, 1));
}
.dark\:border-blue-800:where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(30 64 175 / var(--tw-border-opacity, 1));
}
.dark\:border-red-700:where(.dark, .dark *){
  --tw-border-opacity: 1;
  border-color: rgb(185 28 28 / var(--tw-border-opacity, 1));
}
.dark\:bg-base-50\/10:where(.dark, .dark *){
  background-color: rgb(248 250 252 / 0.1);
}
.dark\:bg-base-700:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.dark\:bg-base-700\/50:where(.dark, .dark *){
  background-color: rgb(51 65 85 / 0.5);
}
.dark\:bg-base-800:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1));
}
.dark\:bg-base-900:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(15 23 42 / var(--tw-bg-opacity, 1));
}
.dark\:bg-black\/10:where(.dark, .dark *){
  background-color: rgb(0 0 0 / 0.1);
}
.dark\:bg-blue-900\/30:where(.dark, .dark *){
  background-color: rgb(30 58 138 / 0.3);
}
.dark\:bg-red-700:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(185 28 28 / var(--tw-bg-opacity, 1));
}
.dark\:bg-red-700\/40:where(.dark, .dark *){
  background-color: rgb(185 28 28 / 0.4);
}
.dark\:bg-red-900:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(127 29 29 / var(--tw-bg-opacity, 1));
}
.dark\:from-base-700:where(.dark, .dark *){
  --tw-gradient-from: #334155 var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(51 65 85 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.dark\:from-base-700\/50:where(.dark, .dark *){
  --tw-gradient-from: rgb(51 65 85 / 0.5) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(51 65 85 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.dark\:from-base-800:where(.dark, .dark *){
  --tw-gradient-from: #1e293b var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(30 41 59 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.dark\:from-primary-900:where(.dark, .dark *){
  --tw-gradient-from: var(--primary-900) var(--tw-gradient-from-position);
  --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.dark\:to-base-800:where(.dark, .dark *){
  --tw-gradient-to: #1e293b var(--tw-gradient-to-position);
}
.dark\:to-primary-600:where(.dark, .dark *){
  --tw-gradient-to: var(--primary-600) var(--tw-gradient-to-position);
}
.dark\:text-base-200:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(226 232 240 / var(--tw-text-opacity, 1));
}
.dark\:text-base-300:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(203 213 225 / var(--tw-text-opacity, 1));
}
.dark\:text-base-400:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(148 163 184 / var(--tw-text-opacity, 1));
}
.dark\:text-base-500:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(100 116 139 / var(--tw-text-opacity, 1));
}
.dark\:text-base-600:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(71 85 105 / var(--tw-text-opacity, 1));
}
.dark\:text-base-800:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(30 41 59 / var(--tw-text-opacity, 1));
}
.dark\:text-blue-300:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(147 197 253 / var(--tw-text-opacity, 1));
}
.dark\:text-blue-400:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(96 165 250 / var(--tw-text-opacity, 1));
}
.dark\:text-blue-500:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(59 130 246 / var(--tw-text-opacity, 1));
}
.dark\:text-primary-300:where(.dark, .dark *){
  color: var(--primary-300);
}
.dark\:text-red-100:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(254 226 226 / var(--tw-text-opacity, 1));
}
.dark\:text-white:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.dark\:shadow:where(.dark, .dark *){
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.dark\:shadow-black:where(.dark, .dark *){
  --tw-shadow-color: #000;
  --tw-shadow: var(--tw-shadow-colored);
}
.dark\:ring-transparent:where(.dark, .dark *){
  --tw-ring-color: transparent;
}
.dark\:ring-offset-base-700:where(.dark, .dark *){
  --tw-ring-offset-color: #334155;
}
.dark\:ring-offset-base-900:where(.dark, .dark *){
  --tw-ring-offset-color: #0f172a;
}
.dark\:\[--code-editor-background\:theme\(\'colors\.base\.800\'\)\]:where(.dark, .dark *){
  --code-editor-background: #1e293b;
}
.dark\:\*\:bg-base-700 > *:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.dark\:\*\:bg-base-900 > *:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(15 23 42 / var(--tw-bg-opacity, 1));
}
.dark\:hover\:bg-base-400:hover:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(148 163 184 / var(--tw-bg-opacity, 1));
}
.dark\:hover\:bg-base-700:hover:where(.dark, .dark *){
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.dark\:hover\:bg-blue-900\/30:hover:where(.dark, .dark *){
  background-color: rgb(30 58 138 / 0.3);
}
.hover\:dark\:bg-base-700:where(.dark, .dark *):hover{
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.dark\:hover\:text-blue-100:hover:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(219 234 254 / var(--tw-text-opacity, 1));
}
.disabled\:dark\:bg-base-700:where(.dark, .dark *):disabled{
  --tw-bg-opacity: 1;
  background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
}
.disabled\:dark\:\[--code-editor-background\:theme\(\'colors\.base\.700\'\)\]:where(.dark, .dark *):disabled{
  --code-editor-background: #334155;
}
.group:hover .dark\:group-hover\:bg-base-700\/25:where(.dark, .dark *){
  background-color: rgb(51 65 85 / 0.25);
}
.group:hover .dark\:group-hover\:text-base-100:where(.dark, .dark *){
  --tw-text-opacity: 1;
  color: rgb(241 245 249 / var(--tw-text-opacity, 1));
}
@media (min-width: 640px){
  .sm\:dark\:bg-base-700:where(.dark, .dark *){
    --tw-bg-opacity: 1;
    background-color: rgb(51 65 85 / var(--tw-bg-opacity, 1));
  }
  .sm\:dark\:shadow-lg:where(.dark, .dark *){
    --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
    --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
  }
}
@media print{
  .print\:block{
    display: block;
  }
  .print\:hidden{
    display: none;
  }
  .print\:grid-cols-2{
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .print\:grid-cols-3{
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .print\:grid-cols-4{
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .print\:grid-cols-5{
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
  .print\:grid-cols-6{
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
  .print\:shadow-none{
    --tw-shadow: 0 0 #0000;
    --tw-shadow-colored: 0 0 #0000;
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
  }
}
.\[\&_p\]\:mb-2 p{
  margin-bottom: 0.5rem;
}
