.tm-code-verification {
  position: relative;
  isolation: isolate;
  height: 56px;
  flex-shrink: 0;
  min-width: 0;
  max-width: 100%;
  --code-green: #15803d;
}

.tm-code-inputs,
.tm-code-shards {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  transform: translateY(-50%);
}

/* Only OTP results opt out of the portals' motion resets. */
html .tm-code-verification[data-state='success'] {
  animation: tmCodeExpand 550ms cubic-bezier(0.22, 1, 0.36, 1) both !important;
}

html .tm-code-verification[data-state='success'] input {
  color: var(--code-green);
  -webkit-text-fill-color: var(--code-green);
  background: #dcfce7;
  border-color: var(--code-green);
  box-shadow: 0 0 0 3px rgb(21 128 61 / 10%);
  opacity: 1;
  animation: tmCodeGather 1650ms cubic-bezier(0.45, 0, 0.2, 1) both !important;
}

.tm-code-confirmation {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 78px;
  height: 78px;
  margin: -39px;
  border-radius: 50%;
  color: var(--code-green);
  background: #f0fdf4;
  box-shadow:
    inset 0 0 0 1px #bbf7d0,
    0 0 0 7px rgb(21 128 61 / 4%);
}

html .tm-code-verification .tm-code-confirmation {
  animation: tmCodeCheckAppear 400ms 1000ms both !important;
}

.tm-code-check {
  width: 46px;
  height: 46px;
}

.tm-code-check path {
  stroke: currentColor;
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
}

html .tm-code-verification .tm-code-check path {
  animation: tmCodeDrawCheck 400ms 1100ms both !important;
}

.tm-code-loading-ring {
  position: absolute;
  inset: -5px;
  border: 2px solid #bbf7d0;
  border-top-color: var(--code-green);
  border-right-color: var(--code-green);
  border-radius: 50%;
  opacity: 0;
}

html .tm-code-verification[data-loading='true'] .tm-code-loading-ring {
  opacity: 1;
  animation: tmCodeSpin 800ms linear infinite !important;
}

.tm-code-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.tm-code-verification[data-state='success'] .tm-code-status {
  top: calc(100% - 18px);
  left: 0;
  width: 100%;
  height: auto;
  margin: 0;
  overflow: visible;
  clip-path: none;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--code-green);
}

html .tm-code-verification[data-state='success'] .tm-code-status {
  animation: tmCodeCheckAppear 250ms 1000ms both !important;
}

html .tm-code-verification[data-state='error'] input {
  animation: tmCodeBreakInput 300ms var(--glass-delay, 0ms) ease-out both !important;
}

.tm-code-glass-definitions {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

.tm-code-breakup {
  position: absolute;
  inset: -8px 0;
  overflow: clip;
  contain: paint;
  pointer-events: none;
  z-index: 1;
  mask-image: linear-gradient(transparent, #000 16%, #000 84%, transparent);
}

.tm-code-breakup .tm-code-shards {
  left: 0;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(var(--code-length), minmax(0, 1fr));
  gap: 10px;
  height: 56px;
  pointer-events: none;
}

.tm-code-glass {
  position: relative;
  perspective: 400px;
}

.tm-code-glass-reset {
  position: absolute;
  inset: 0;
  border: 1.5px solid var(--tm-border-input, #e6d2b5);
  border-radius: 12px;
  background: var(--tm-card-light, #fff);
}

html .tm-code-verification .tm-code-glass-reset {
  animation: tmCodeGlassReset 180ms calc(900ms + var(--glass-delay)) ease-out both !important;
}

.tm-code-glass::before,
.tm-code-glass::after {
  position: absolute;
  content: '';
  pointer-events: none;
}

.tm-code-glass::before {
  inset: -4px;
  border-radius: 20px;
  background: radial-gradient(ellipse at 43% 44%, rgb(255 255 255 / 90%), rgb(239 100 87 / 16%) 44%, transparent 72%);
}

.tm-code-glass::after {
  inset: 4px;
  border: 1px solid rgb(203 74 63 / 45%);
  border-radius: 50%;
}

html .tm-code-verification .tm-code-glass::before {
  animation: tmCodeGlassImpact 420ms var(--glass-delay) ease-out both !important;
}

html .tm-code-verification .tm-code-glass::after {
  animation: tmCodeGlassShock 500ms var(--glass-delay) ease-out both !important;
}

.tm-code-shard,
.tm-code-cracks {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.tm-code-cracks {
  fill: none;
  stroke: #b94c43;
  stroke-width: 0.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 1px 0 white);
}

html .tm-code-verification .tm-code-cracks path {
  stroke-dasharray: 1;
  animation: tmCodeGlassCrack 380ms var(--glass-delay) ease-out both !important;
}

.tm-code-shard {
  transform-origin: 50% 50%;
  filter: drop-shadow(0 2px 1px rgb(109 40 33 / 14%));
}

.tm-code-glass-reflection {
  fill: rgb(255 255 255 / 80%);
}

.tm-code-glass-digit {
  font-family: inherit;
  font-size: 39px;
  font-weight: 700;
  fill: #ac4238;
}

.tm-code-glass-rim {
  fill: none;
  stroke: #d8847a;
  stroke-width: 2;
}

.tm-code-shard-edge {
  fill: none;
  stroke: #e5a69e;
  stroke-width: 0.65;
  stroke-linejoin: round;
}

html .tm-code-verification .tm-code-shard {
  animation: tmCodeShatter 860ms calc(180ms + var(--glass-delay) + var(--shard-delay)) linear both !important;
}

.tm-code-glint {
  position: absolute;
  top: 44%;
  left: 43%;
  width: 3px;
  height: 5px;
  background: #fff4ed;
  box-shadow: 0 0 4px rgb(192 85 68 / 55%);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

html .tm-code-verification .tm-code-glint {
  animation: tmCodeGlassGlint 620ms calc(280ms + var(--glass-delay) + var(--glint-delay)) ease-out both !important;
}

@keyframes tmCodeExpand {
  from {
    height: 56px;
  }
  to {
    height: 188px;
  }
}

@keyframes tmCodeGather {
  0%,
  16% {
    transform: translate(0, 0) scale(1);
  }
  42% {
    transform: translate(calc(var(--gather-x) * 0.65), var(--arc-y)) scale(0.65) rotate(-12deg);
  }
  70% {
    transform: translate(calc(var(--gather-x) + var(--ring-x)), var(--ring-y)) scale(0.3) rotate(90deg);
    border-radius: 14px;
  }
  100% {
    transform: translate(calc(var(--gather-x) + var(--orbit-x)), var(--orbit-y)) scale(0.3) rotate(150deg);
    border-radius: 14px;
  }
}

@keyframes tmCodeCheckAppear {
  from {
    opacity: 0;
    scale: 0.75;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

@keyframes tmCodeDrawCheck {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes tmCodeSpin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes tmCodeBreakInput {
  0% {
    opacity: 1;
    transform: translateX(0);
  }
  18% {
    transform: translateX(-2px) rotate(-1deg);
  }
  38% {
    transform: translateX(2px) rotate(1deg);
  }
  58% {
    opacity: 1;
    transform: translateX(-1px);
  }
  78%,
  100% {
    opacity: 0;
    transform: translateX(0) scale(0.98);
  }
}

@keyframes tmCodeGlassImpact {
  0% {
    opacity: 0;
    scale: 0.88;
  }
  28% {
    opacity: 1;
    scale: 1.06;
  }
  100% {
    opacity: 0;
    scale: 1.12;
  }
}

@keyframes tmCodeGlassReset {
  from {
    opacity: 0;
    transform: scale(0.94);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes tmCodeGlassShock {
  0%,
  15% {
    opacity: 0;
    scale: 0.3;
  }
  35% {
    opacity: 0.65;
  }
  100% {
    opacity: 0;
    scale: 1.25;
  }
}

@keyframes tmCodeGlassCrack {
  0% {
    opacity: 0;
    stroke-dashoffset: 1;
  }
  25% {
    opacity: 0.9;
  }
  60% {
    opacity: 1;
    stroke-dashoffset: 0;
  }
  100% {
    opacity: 0;
    stroke-dashoffset: 0;
  }
}

@keyframes tmCodeGlassGlint {
  0% {
    opacity: 0;
    transform: translate(0, 0) scale(0.4);
  }
  15% {
    opacity: 1;
  }
  60% {
    opacity: 0.8;
  }
  100% {
    opacity: 0;
    transform: translate(var(--glint-x), var(--glint-y)) rotate(125deg) scale(0.1);
  }
}

@keyframes tmCodeShatter {
  0% {
    opacity: 0;
    transform: perspective(400px) translate3d(0, 0, 0) rotate(0) rotateY(0);
  }
  3%,
  12% {
    opacity: 1;
    transform: perspective(400px) translate3d(0, 0, 0) rotate(0) rotateY(0);
  }
  42% {
    opacity: 1;
    transform: perspective(400px) translate3d(var(--shard-x), var(--shard-y), 12px)
      rotate(calc(var(--shard-turn) * 0.6)) rotateY(var(--shard-tilt)) scale(0.9);
  }
  72% {
    opacity: 0.55;
    transform: perspective(400px) translate3d(calc(var(--shard-x) * 1.25), calc(var(--shard-y) + 16px), 0)
      rotate(var(--shard-turn)) rotateY(calc(var(--shard-tilt) * 1.25)) scale(0.8);
  }
  100% {
    opacity: 0;
    transform: perspective(400px) translate3d(calc(var(--shard-x) * 1.4), calc(var(--shard-y) + 36px), -35px)
      rotate(calc(var(--shard-turn) * 1.3)) rotateY(calc(var(--shard-tilt) * 1.5)) scale(0.45);
  }
}

@media (max-width: 599px) {
  .tm-code-verification {
    height: 50px;
  }
  .tm-code-breakup .tm-code-shards {
    height: 50px;
    gap: 6px;
  }
  @keyframes tmCodeExpand {
    from {
      height: 50px;
    }
    to {
      height: 188px;
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  html .tm-code-verification[data-state][data-loading] *,
  html .tm-code-verification[data-state][data-loading] *::before,
  html .tm-code-verification[data-state][data-loading] *::after,
  html .tm-code-verification[data-state][data-loading] {
    animation: none !important;
  }
  .tm-code-verification[data-state='success'] {
    height: 148px;
  }
  .tm-code-verification[data-state='success'] .tm-code-inputs,
  .tm-code-shards {
    visibility: hidden;
  }
}
/*
 * Tres Marias design tokens as CSS custom properties (design system:
 * tokens/colors.css + tokens/typography.css). MUI components read the JS mirror
 * in tokens.js; plain CSS and inline styles can use these.
 *
 * The values below are the light (warm ivory) scheme, the default, used until
 * theme/colorMode.jsx writes the chosen scheme onto <html>. From then on <html>
 * wins, so body, scrollbars and everything styled with var(--tm-...) follow the
 * mode switch.
 */
:root {
  --tm-bg-base: #fbf7f0;
  --tm-bg-deep: #f3eadb;
  --tm-bg-panel: #ffffff;
  --tm-header-bg: #fdfbf6;

  --tm-gold: #c5a059;
  --tm-gold-light: #dfba73;
  --tm-gold-dark: #9d7c38;
  --tm-gold-glow: rgba(197, 160, 89, 0.35);
  --tm-on-gold: #2b2622;

  --tm-card-light: #ffffff;
  --tm-card-light-border: #e8dcc6;
  --tm-card-dark: #ffffff;
  --tm-card-dark-border: #e8dcc6;

  --tm-text-primary: #2b2622;
  --tm-text-secondary: #5e554d;
  --tm-text-muted: #8a8078;
  --tm-text-light: #2b2622;
  --tm-text-on-dark-soft: #5e554d;
  --tm-text-on-dark-muted: #8a8078;

  --tm-green: #10b981;
  --tm-amber: #f59e0b;
  --tm-blue: #3b82f6;
  --tm-red: #ef4444;

  --tm-radius-sm: 8px;
  --tm-radius-md: 10px;
  --tm-radius-lg: 16px;
  --tm-radius-pill: 999px;

  --tm-font-sans: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  color-scheme: light;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--tm-font-sans);
  background: var(--tm-bg-base);
  color: var(--tm-text-light);
}

h1,
h2,
h3 {
  text-wrap: balance;
}
[id^='event-'],
#quotation-card {
  scroll-margin-top: 100px;
}
@media print {
  .MuiTableContainer-root {
    max-height: none !important;
    overflow: visible !important;
  }
}
button,
a,
input,
select,
textarea {
  touch-action: manipulation;
}
.MuiTableCell-root,
.MuiLinearProgress-root {
  font-variant-numeric: tabular-nums;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important;
  }
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
  }
}

img {
  max-width: 100%;
}

::selection {
  background: rgba(197, 160, 89, 0.35);
}

:focus-visible {
  outline: 2px solid var(--tm-gold);
  outline-offset: 2px;
}

/* The evening portal has its own surface treatment; paper exports stay on their light palette. */
html[data-tm-mode='dark'] .tm-portal .tm-dash-card {
  background-image: linear-gradient(155deg, rgba(188, 213, 244, 0.035), transparent 55%);
}

html[data-tm-mode='dark'] .tm-portal .tm-feature-card {
  background-image: var(--tm-gradient-hero);
  border-top-color: var(--tm-gold);
}

html[data-tm-mode='dark'] .tm-portal-header {
  border-bottom-color: var(--tm-sidebar-border);
  box-shadow: 0 1px 0 rgba(188, 213, 244, 0.035);
}

html[data-tm-mode='dark'] .tm-sidebar-link {
  border-left-color: transparent;
  border-radius: 10px;
  font-weight: 400;
}

html[data-tm-mode='dark'] .tm-sidebar-link[aria-current='page'] {
  border-left-color: var(--tm-gold);
  background-image: linear-gradient(110deg, var(--tm-gold-tint), transparent);
  box-shadow: inset 0 0 0 1px var(--tm-shell-border);
  font-weight: 600;
}

html[data-tm-mode='dark'] .tm-sidebar-link[aria-current='page'] .MuiSvgIcon-root {
  color: var(--tm-sidebar-active-text);
}

html[data-tm-mode='dark'] .tm-portal h1 {
  font-weight: 600;
  letter-spacing: -0.035em;
}

html[data-tm-mode='dark'] .tm-bottom-nav-item .MuiBadge-root {
  padding: 4px 12px;
  border-radius: 10px;
}

html[data-tm-mode='dark'] .tm-bottom-nav-item[aria-current='page'] .MuiBadge-root {
  background-color: var(--tm-sidebar-active-bg);
  color: var(--tm-sidebar-active-text);
}

html[data-tm-mode='dark'] .tm-scroll {
  scrollbar-color: var(--tm-slate-700) transparent;
}

html[data-tm-mode='dark'] .tm-scroll::-webkit-scrollbar-thumb {
  background: var(--tm-slate-700);
}

/*
 * Switching dark / light mode (theme/colorMode.jsx).
 *
 * The browser photographs the page before and after the swap. Turning off the
 * default cross-fade and stacking the new photograph on top lets colorMode.jsx
 * clip it to a circle that opens from the toggle button, so the new theme washes
 * over the old one instead of both fading at once.
 */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-old(root) {
  z-index: 0;
}
::view-transition-new(root) {
  z-index: 1;
}

/*
 * Fallback for browsers without view transitions: colorMode.jsx puts this class
 * on <html> for the length of the switch so the colours fade instead of jumping.
 * It is removed straight after, so normal hovers and scrolling keep their own timing.
 */
.tm-theming,
.tm-theming *,
.tm-theming *::before,
.tm-theming *::after {
  transition:
    background-color 350ms ease,
    border-color 350ms ease,
    color 350ms ease,
    fill 350ms ease,
    box-shadow 350ms ease !important;
}

/* Thin, on-brand scrollbars inside panels */
.tm-scroll::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.tm-scroll::-webkit-scrollbar-thumb {
  background: rgba(148, 163, 184, 0.35);
  border-radius: 999px;
}

/* A page laid out for paper (the Reports sheet, the reservations list) waits off screen, at the A4
   content width that utils/savePdf.js lays a PDF out at, until it is printed or saved as a PDF:
   680 px for a portrait page, 1009 px for a landscape one (tm-print-landscape) */
.tm-print-sheet {
  position: fixed;
  top: 0;
  left: -10000px;
  width: 680px;
  pointer-events: none;
}
.tm-print-sheet.tm-print-landscape {
  width: 1009px;
}

/* A landscape sheet prints on landscape A4 pages */
@page tm-landscape {
  size: A4 landscape;
}

/* Printing a document dialog or a print sheet prints only that; printing a page drops the portal chrome */
@media print {
  main {
    padding: 0 !important;
  }

  body {
    background: #fff !important;
  }
  body:has(.tm-print-root) > *:not(.tm-print-root) {
    display: none !important;
  }
  .tm-print-root {
    position: static !important;
  }
  .tm-print-sheet {
    width: auto !important;
  }
  .tm-print-landscape {
    page: tm-landscape;
  }
  /* Print the colours a document or sheet is drawn with: the report's chart bars, shaded table heads and
     figure boxes, the receipt's box. Browsers leave background colours out of a printout unless the
     print window's "Background graphics" is ticked; this keeps them in, as Save PDF does */
  .tm-print-root,
  .tm-print-root * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .tm-print-root .MuiBackdrop-root,
  .tm-no-print {
    display: none !important;
  }
  .tm-print-root .MuiDialog-container {
    display: block !important;
    height: auto !important;
  }
  /* The height and overflow lines matter on phones, where the dialog is full-screen and scrolls
     inside itself: without them only the first screenful of the document would print */
  .tm-print-root .MuiDialog-paper {
    margin: 0 !important;
    max-width: none !important;
    width: 100% !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    box-shadow: none !important;
  }

  .tm-receipt-document .MuiDialog-container::after {
    display: none !important;
  }
  .tm-receipt-document .MuiDialog-paper {
    display: block !important;
    break-inside: avoid;
  }
  .tm-receipt-sheet {
    width: 180mm !important;
    max-width: 100% !important;
    margin: 0 auto !important;
    padding: 0 !important;
    break-inside: avoid;
  }
  .tm-receipt-sheet > .MuiBox-root {
    gap: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* The * rule above does not reach the view-transition pseudo-elements */
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }
}
/* Keep the admin portal static, including shared components and MUI portals attached to body. */
html[data-tm-portal='admin'],
html[data-tm-portal='admin'] *,
html[data-tm-portal='admin'] *::before,
html[data-tm-portal='admin'] *::after {
  animation: none !important;
  transition: none !important;
  scroll-behavior: auto !important;
}

html[data-tm-portal='admin']::view-transition-group(*),
html[data-tm-portal='admin']::view-transition-image-pair(*),
html[data-tm-portal='admin']::view-transition-old(*),
html[data-tm-portal='admin']::view-transition-new(*) {
  animation: none !important;
}

/* Buttons retain their immediate hover/focus feedback without ripple or card movement. */
html[data-tm-portal='admin'] .MuiTouchRipple-root {
  display: none !important;
}

html[data-tm-portal='admin'] .tm-dash-card:hover {
  transform: none !important;
}

/* An indeterminate loader remains visible as a static arc instead of an animated spinner. */
html[data-tm-portal='admin'] .MuiCircularProgress-circleIndeterminate {
  stroke-dasharray: 80px, 200px;
  stroke-dashoffset: 0;
}
