@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600&display=swap'); :root { --bg: #17120f; --bg-raised: #1e1712; --line: #3a2f26; --text: #f3ead9; --text-muted: #c9baa3; --gold: #c9a15a; --gold-bright: #e0bb78; --ember: #a8402c; } * { box-sizing: border-box; } html { scroll-behavior: smooth; } /* `clip`, not `hidden` — `hidden` on both axes-owners forces the browser to also compute `overflow-y: auto` on each, which creates two nested scroll containers and breaks `position: sticky` for everything on the page. */ html, body { overflow-x: clip; } body { margin: 0; background: var(--bg); color: var(--text); font-family: 'Inter', system-ui, sans-serif; line-height: 1.5; } h1, h2, h3 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; letter-spacing: 0.01em; margin: 0; } a { color: var(--text); } .page { max-width: 68rem; margin: 0 auto; padding: 0 1.5rem; } /* Header */ .site-header { position: sticky; top: 0; z-index: 50; background: var(--bg); border-bottom: 1px solid var(--line); display: flex; align-content: center; justify-content: center; } .site-header-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; row-gap: 0.5rem; gap: 1rem; padding: 1.25rem 1.5rem; min-height: 5rem; width: 100%; max-width: 120rem } .wordmark { font-family: 'Fraunces', Georgia, serif; font-size: 1.15rem; letter-spacing: 0.03em; color: var(--text); text-decoration: none; } .wordmark span { color: var(--gold-bright); } .site-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem 1.25rem; list-style: none; margin: 0; padding: 0; font-size: 0.9rem; } .site-nav a { color: var(--text-muted); text-decoration: none; } .site-nav a:hover { color: var(--text); } .staff-login-link { color: var(--text-muted); font-size: 0.8rem; text-decoration: none; opacity: 0.75; } .staff-login-link:hover { color: var(--text); opacity: 1; } /* Hero */ .hero { position: relative; padding: 4.5rem 1.5rem 5rem; text-align: center; background: radial-gradient(ellipse at top, rgba(200, 90, 50, 0.2), transparent 60%), linear-gradient(rgba(23, 18, 15, 0.55), rgba(23, 18, 15, 0.93)), url('/hero-interior.jpg'); background-size: auto, auto, cover; background-position: center, center, center 55%; background-repeat: no-repeat; border-bottom: 1px solid var(--line); overflow: hidden; } .hero-flame { width: 4rem; height: 4rem; margin: 0 auto 1.5rem; color: var(--ember); } .hero h1 { font-size: clamp(2.25rem, 5vw, 3.5rem); color: var(--text); } .hero h1 span { color: var(--text); } .hero p { max-width: 34rem; margin: 1rem auto 0; color: var(--text-muted); font-size: 1.05rem; } .hero-actions { margin-top: 2rem; display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; } .btn { display: inline-block; font: inherit; font-weight: 600; padding: 0.75rem 1.5rem; border-radius: 0.25rem; text-decoration: none; cursor: pointer; border: 1px solid transparent; } .btn:disabled { opacity: 0.6; cursor: not-allowed; } .btn-primary { background: var(--gold); color: #201709; } .btn-primary:hover { background: var(--gold-bright); } .btn-secondary { background: transparent; border-color: var(--line); color: var(--text); } .btn-secondary:hover { border-color: var(--text-muted); color: var(--text); } .btn-ghost { background: none; border-color: transparent; color: var(--text-muted); } .btn-ghost:hover { color: var(--text); background: rgba(243, 234, 217, 0.06); } /* Sections */ .section { padding: 4rem 0; border-bottom: 1px solid var(--line); } .section:last-of-type { border-bottom: none; } .section-heading { font-size: 1.75rem; margin-bottom: 0.5rem; } .section-kicker { display: block; font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 0.75rem; } .section-grid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 3rem; } .section-grid > * { min-width: 0; } @media (max-width: 46rem) { .section-grid { grid-template-columns: 1fr; } } /* Opening hours */ .hours-list { list-style: none; margin: 1.5rem 0 0; padding: 0; border-top: 1px solid var(--line); } .hours-list li { display: flex; justify-content: space-between; gap: 1rem; padding: 0.65rem 0; border-bottom: 1px solid var(--line); color: var(--text-muted); } .hours-list li.today { color: var(--text); font-weight: 600; } .hours-list .day { font-family: 'Fraunces', Georgia, serif; } .hours-closed { font-style: italic; } /* Reservation form */ .reservation-form { display: flex; flex-direction: column; gap: 1.1rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.5rem; padding: 1.75rem; } .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; } .form-row > * { min-width: 0; } @media (max-width: 30rem) { .form-row { grid-template-columns: 1fr; } } .reservation-form label { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; font-weight: 500; font-size: 0.9rem; color: var(--text-muted); } .datetime-field { display: flex; flex-wrap: wrap; gap: 0.6rem } .date-input-group { position: relative; flex: 1 1 10rem; min-width: 10rem; } .date-input-group input[type='text'] { width: 100%; padding-right: 2.5rem; } .datetime-field select { flex: 1 1 6.5rem; min-width: 6.5rem; } .datetime-field select:disabled { opacity: 0.6; cursor: not-allowed; } .date-picker-trigger { position: absolute; top: 50%; right: 0.3rem; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; width: 1.9rem; height: 1.9rem; padding: 0; border: none; border-radius: 0.25rem; background: transparent; cursor: pointer; } .date-picker-trigger svg { flex-shrink: 0; width: 18px; height: 18px; color: var(--text); } .date-picker-trigger:hover, .date-picker-trigger[aria-expanded='true'] { anchor-name: --anchor-date-time; } .password-field { position: relative; } .password-field input { padding-right: 2.5rem; } .password-toggle { position: absolute; top: 50%; right: 0.3rem; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; width: 1.9rem; height: 1.9rem; padding: 0; border: none; border-radius: 0.25rem; background: transparent; color: var(--text-muted); cursor: pointer; } .password-toggle:hover { color: var(--text); } .password-toggle svg { flex-shrink: 0; width: 18px; height: 18px; } .date-popover-backdrop { display: contents; } .date-popover { position: absolute; position-anchor: --anchor-date-time; left: calc(anchor(center) - 100%); z-index: 20; padding: 0.6rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.4rem; box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35); overflow: hidden; } @media (max-width: 30rem) { .date-popover-backdrop { display: flex; position: fixed; inset: 0; z-index: 100; align-items: center; justify-content: center; padding: 1rem; background: rgba(0, 0, 0, 0.6); } .date-popover { position: static; width: 100%; padding: 1rem; box-shadow: 0 20px 45px rgba(0, 0, 0, 0.45); animation: confirm-dialog-fade-in 0.15s ease-out; } .date-popover-header { margin-bottom: 0.6rem; font-size: 1rem; } .date-popover-header button { width: 3rem; height: 3rem; font-size: 1.8rem; } .date-popover-weekdays span, .date-popover-grid button { font-size: 0.95rem; display: flex; align-items: center; justify-content: center; width: 100% !important; } .date-popover-grid button { aspect-ratio: unset; padding: 0.5rem 0; } } .date-popover-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.4rem; color: var(--text); font-size: 0.8rem; font-weight: 500; } .date-popover-header button { width: 1.5rem; height: 1.5rem; padding: 0; margin: 0; display: flex; align-items: center; justify-content: center; border: none; border-radius: 0.25rem; background: transparent; color: var(--text-muted); font: inherit; font-size: 1.2rem; cursor: pointer; } .date-popover-header button:hover:not(:disabled) { color: var(--text); } .date-popover-header button:disabled { opacity: 0.35; cursor: not-allowed; } .date-popover-weekdays, .date-popover-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.1rem; span { width: 1.8rem; } button { display: flex; align-items: center; justify-content: center; } } .date-popover-weekdays { margin-bottom: 0.15rem; font-size: 0.68rem; color: var(--text-muted); text-align: center; } .date-popover-grid button { aspect-ratio: 1; min-width: 0; min-height: 0; padding: 0; margin: 0; align-self: auto; border: none; border-radius: 50%; background: transparent; color: var(--text); font: inherit; font-size: 0.78rem; cursor: pointer; } .date-popover-grid button:hover:not(:disabled) { background: var(--line); } .date-popover-grid button:disabled { color: var(--text-muted); opacity: 0.35; cursor: not-allowed; } .date-popover-grid button.is-selected { background: var(--text); color: var(--bg); font-weight: 600; } .reservation-form input, .reservation-form select, .reservation-form textarea { width: 100%; min-width: 0; font-family: inherit; font-size: 1rem; padding: 0.6rem 0.7rem; border: 1px solid var(--line); border-radius: 0.3rem; background: var(--bg); color: var(--text); } .reservation-form textarea { resize: vertical; min-height: 4.5rem; } .reservation-form input:focus, .reservation-form select:focus, .reservation-form textarea:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(201, 161, 90, 0.25); } /* Overrides the generic `.reservation-form input` box styling above — that rule assumes text-like inputs and would otherwise stretch radios/checkboxes into full-width bordered rectangles instead of native controls. */ .reservation-form input[type='radio'], .reservation-form input[type='checkbox'] { width: 1rem; height: 1rem; padding: 0; border: none; background: none; accent-color: var(--gold); } .table-display-fieldset { display: flex; flex-direction: column; gap: 0.5rem; margin: 0; padding: 0; border: none; } .table-display-fieldset legend { padding: 0; margin-bottom: 0.35rem; font-weight: 500; font-size: 0.9rem; color: var(--text-muted); } .reservation-form .radio-option { flex-direction: row; align-items: center; gap: 0.5rem; font-weight: 400; font-size: 0.95rem; color: var(--text); } /* `.radio-option` centers its input against a single-line label, which breaks down for the consent checkbox's multi-line sentence — the checkbox needs to sit at the top of the text instead of drifting to its vertical center. */ .reservation-form .consent-option { align-items: flex-start; } .reservation-form .consent-option input { margin-top: 0.2rem; flex-shrink: 0; } /* `:not(.btn)` keeps this scoped to the plain submit buttons — anything already using the `.btn` component (Abbrechen, Bearbeiten, Löschen, …) styles itself and shouldn't be overridden here (a previous version of this rule beat `.btn-secondary` on specificity and left its hover text unreadable). `:not(.date-popover *):not(.date-picker-trigger):not(.table-marker):not(.password-toggle)` keeps it off the calendar's own buttons, the overview-photo markers, and the show-password toggle — they live inside this form too, and without this exclusion this rule's specificity beats their own button styles. */ .reservation-form button:not(.btn):not(.date-popover *):not(.date-picker-trigger):not(.table-marker):not(.password-toggle) { align-self: flex-start; font: inherit; font-weight: 600; padding: 0.7rem 1.5rem; border: none; border-radius: 0.3rem; background: var(--gold); color: #201709; cursor: pointer; } .reservation-form button:not(.btn):not(.date-popover *):not(.date-picker-trigger):not(.table-marker):not(.password-toggle):hover:not( :disabled ) { background: var(--gold-bright); } .reservation-form button:not(.btn):not(.date-popover *):not(.date-picker-trigger):not(.table-marker):not(.password-toggle):disabled { opacity: 0.6; cursor: not-allowed; } .field-hint { margin: -0.4rem 0 0; font-size: 0.82rem; color: var(--text-muted); } .field-hint a { color: inherit; text-decoration: underline; } .message { margin: 0; padding: 0.65rem 0.9rem; border-radius: 0.3rem; font-size: 0.9rem; } .message-error { background: #3a1414; color: #f3a9a9; border: 1px solid #5c1f1f; } .message-success { background: #17301c; color: #a9d9b4; border: 1px solid #23502c; } .staff-page-messages { display: flex; flex-direction: column; gap: 0.5rem; margin: 1.25rem 0 0; } /* Contact */ .contact-list { list-style: none; margin: 1.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.9rem; } .contact-list li { display: flex; gap: 0.75rem; color: var(--text-muted); } .contact-list .label { color: var(--text-muted); min-width: 6rem; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; padding-top: 0.15rem; } /* Footer */ .site-footer { padding: 2.5rem 1.5rem; text-align: center; color: var(--text-muted); font-size: 0.85rem; } .site-footer .wordmark { display: block; margin-bottom: 0.5rem; } .footer-nav { display: flex; gap: 1.25rem; justify-content: center; margin-top: 0.75rem; } .footer-nav a { color: var(--text-muted); text-decoration: none; } .footer-nav a:hover { color: var(--text); } /* Staff dashboard */ .staff-page { min-height: 100vh; } /* Sticks the topbar and the tabs below it together as one unit — sticking them separately would need the tabs' `top` hardcoded to the topbar's height, which shifts whenever the topbar wraps onto two lines on narrow screens. */ .staff-nav { position: sticky; top: 0; z-index: 50; background: var(--bg); } .staff-topbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; padding: 1.25rem 1.5rem; /* Matches `.site-header-inner`'s floor so both bars read as the same height — this bar's own content is already taller, so the min-height is a no-op here and never shrinks it. */ min-height: 5rem; border-bottom: 1px solid var(--line); } .staff-topbar-right { display: flex; align-items: center; gap: 1rem; color: var(--text-muted); font-size: 0.9rem; } .staff-topbar-right .btn { padding: 0.5rem 1rem; } .staff-tabs-bar { border-bottom: 1px solid var(--line); } .staff-tabs { display: flex; gap: 1.5rem; max-width: 68rem; margin: 0 auto; padding: 0 1.5rem; overflow: scroll hidden; &::-webkit-scrollbar { display: none; } } .staff-tab { display: inline-flex; align-items: center; padding: 0.9rem 0.1rem; margin-bottom: -1px; color: var(--text-muted); font-size: 0.9rem; font-weight: 500; text-decoration: none; border-bottom: 2px solid transparent; } .staff-tab:hover { color: var(--text); } .staff-tab.is-active { color: var(--gold-bright); border-bottom-color: var(--gold-bright); view-transition-name: staff-tab-active; } ::view-transition-group(staff-tab-active) { animation-duration: 0.22s; animation-timing-function: ease; } @media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } .bar-chart-bar { transition: none; } .confirm-dialog { animation: none; } .reservation-confirmed-flame { animation: none; } } .staff-main { padding: 3rem 1.5rem 4rem; } .staff-subheading { font-size: 1.35rem; margin: 2.5rem 0 1.25rem; } .staff-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-top: 1.5rem; } @media (max-width: 40rem) { .staff-stats { grid-template-columns: repeat(2, 1fr); } } .stat-card { display: flex; flex-direction: column; gap: 0.35rem; padding: 1.25rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.5rem; } .stat-value { font-family: 'Fraunces', Georgia, serif; font-size: 1.75rem; color: var(--text); } .stat-label { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); } .charts-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem; margin-top: 1.5rem; } @media (max-width: 48rem) { .charts-grid { grid-template-columns: 1fr; } } .chart-card { padding: 1.25rem 1.25rem 1rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.5rem; } .chart-card-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 1.25rem; } .chart-title { font-family: 'Inter', system-ui, sans-serif; font-size: 0.9rem; font-weight: 600; margin: 0; } .chart-toggle { display: inline-flex; gap: 0.15rem; padding: 0.15rem; background: var(--bg); border: 1px solid var(--line); border-radius: 0.4rem; } .chart-toggle button { padding: 0.3rem 0.65rem; border: none; border-radius: 0.3rem; background: transparent; color: var(--text-muted); font: inherit; font-size: 0.8rem; cursor: pointer; } .chart-toggle button:hover { color: var(--text); } .chart-toggle button.is-active { background: var(--gold); color: var(--bg); } .bar-chart-plot { position: relative; height: 10rem; } .bar-chart-gridline { position: absolute; left: 0; right: 0; border-top: 1px solid var(--line); } .bar-chart-tick { position: absolute; left: 0; bottom: 0; transform: translateY(50%); font-size: 0.7rem; color: var(--text-muted); } .bar-chart-bars { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 0.4rem; padding-left: 1.5rem; } .bar-chart-col { position: relative; flex: 1 1 0; height: 100%; min-width: 0; display: flex; align-items: flex-end; justify-content: center; outline: none; } .bar-chart-bar { position: relative; width: 100%; max-width: 1.5rem; margin-top: auto; min-height: 2px; background: var(--gold); border-radius: 4px 4px 0 0; transition: background-color 0.15s ease, height 0.2s ease; } .bar-chart-col:hover .bar-chart-bar, .bar-chart-col:focus-visible .bar-chart-bar { background: var(--gold-bright); } .bar-chart-col:focus-visible .bar-chart-bar { outline: 2px solid var(--gold-bright); outline-offset: 2px; } .bar-chart-value { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: 0.3rem; font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; } .bar-chart-tooltip { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%) translateY(-0.4rem); margin-bottom: 0.5rem; padding: 0.4rem 0.6rem; background: var(--bg); border: 1px solid var(--line); border-radius: 0.35rem; box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35); color: var(--text); font-size: 0.75rem; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity 0.12s ease; z-index: 1; } .bar-chart-col:hover .bar-chart-tooltip, .bar-chart-col:focus-visible .bar-chart-tooltip { opacity: 1; } .bar-chart-axis { display: flex; gap: 0.4rem; padding-left: 1.5rem; margin-top: 0.5rem; } .bar-chart-axis-label { flex: 1 1 0; min-width: 0; text-align: center; font-size: 0.7rem; color: var(--text-muted); } .staff-form-section { max-width: 36rem; } .form-actions { display: flex; gap: 0.75rem; align-items: center; } .form-actions .btn { font: inherit; padding: 0.7rem 1.5rem; } .staff-table-section { margin-top: 2.5rem; } .table-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; } .table-toolbar .staff-subheading { margin: 0; } .table-filters { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 1.25rem; } .table-filters input, .table-filters select { font-family: inherit; font-size: 0.9rem; padding: 0.55rem 0.7rem; border: 1px solid var(--line); border-radius: 0.3rem; background: var(--bg); color: var(--text); } .table-filters input:focus, .table-filters select:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(201, 161, 90, 0.25); } .table-search { flex: 1 1 16rem; min-width: 0; } .table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 0.5rem; &::-webkit-scrollbar { display: none; } } .reservations-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; } .reservations-table th, .reservations-table td { padding: 0.85rem 1rem; text-align: left; white-space: nowrap; border-bottom: 1px solid var(--line); } .reservations-table th { color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; background: var(--bg-raised); } .reservations-table tbody tr:last-child td { border-bottom: none; } .reservations-table tr.is-editing { background: rgba(243, 234, 217, 0.06); } .reservations-table-clickable tbody tr:hover { background: rgba(243, 234, 217, 0.05); cursor: pointer; } .reservations-table .muted { color: var(--text-muted); font-size: 0.8rem; } .reservations-table .message-cell { max-width: 16rem; overflow: hidden; text-overflow: ellipsis; } @media (max-width: 40rem) { /* On mobile the column headers are hidden and each row becomes a card laid out on a 2-column grid — related fields (table nr/name, party/status) sit side by side, while date/time, customer and message span full width. */ .reservations-table thead { display: none; } .reservations-table, .reservations-table tbody { display: block; width: 100%; } .reservations-table tbody { padding: 0.75rem; } .reservations-table tbody tr { display: grid; grid-template-columns: 1fr 1fr; column-gap: 1rem; row-gap: 0.6rem; padding: 0.9rem 1rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.5rem; } .reservations-table tbody tr + tr { margin-top: 0.75rem; } .reservations-table td { display: block; max-width: none; padding: 0; white-space: normal; word-break: break-word; border-bottom: none; } .reservations-table td[data-label]::before { content: attr(data-label); display: block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 0.15rem; } .reservations-table .cell-datetime, .reservations-table .cell-customer, .reservations-table .message-cell { grid-column: 1 / -1; } .reservations-table .message-cell { max-width: none; overflow: visible; text-overflow: unset; } } .status-badge { display: inline-flex; align-items: center; justify-content: center; width: 9.5rem; padding: 0.2rem 0.6rem; border-radius: 999px; font: inherit; font-size: 0.75rem; font-weight: 600; white-space: nowrap; } .status-badge.status-confirmed { background: rgba(201, 161, 90, 0.15); color: var(--gold-bright); border: 1px solid rgba(201, 161, 90, 0.35); } .status-badge.status-no_show { background: #3a1414; color: #f3a9a9; border: 1px solid #5c1f1f; } .status-badge.status-completed { background: #17301c; color: #a9d9b4; border: 1px solid #23502c; } /* A single grouped 3-way toggle track, not three loose floating pills — the active segment gets a solid fill, the other two stay flat text until hovered. */ .status-options { display: flex; gap: 0.25rem; margin: 0 0 1.5rem; padding: 0.25rem; background: var(--bg); border: 1px solid var(--line); border-radius: 999px; } .status-option { flex: 1; cursor: pointer; padding: 0.45rem 0.75rem; transition: background-color 0.15s ease, color 0.15s ease; } /* `.status-badge.status-option` — matches `.status-badge.status-confirmed` (etc.) on specificity so this actually wins and overrides their fixed `width`/`border`, rather than losing to them by cascade order. */ .status-badge.status-option { width: auto; border: none; } .status-option:disabled { cursor: not-allowed; } .status-option:hover:not(:disabled):not(.is-active) { color: var(--text); background: rgba(243, 234, 217, 0.06); } .status-option.is-active.status-confirmed { background: var(--gold); color: #201709; } .status-option.is-active.status-no_show { background: var(--ember); color: #fdeceb; } .status-option.is-active.status-completed { background: #2f7a3c; color: #eafcee; } .table-actions { display: flex; gap: 0.5rem; } .table-actions .btn { font: inherit; padding: 0.4rem 0.85rem; font-size: 0.8rem; } .action-menu-trigger { display: flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; padding: 0; border: none; border-radius: 0.3rem; background: transparent; color: var(--text-muted); cursor: pointer; } .action-menu-trigger:hover, .action-menu-trigger[aria-expanded='true'] { background: var(--line); color: var(--text); } /* `top`/`right` are set inline per instance (src/components/action-menu.tsx) — the panel is portaled to and positioned from a measured rect so it isn't clipped by `.table-scroll`'s (forced) `overflow-y: auto`. `z-index` is above `.confirm-dialog-backdrop` (100) since the menu can now be opened from inside the reservation detail modal, not just from a table row. */ .action-menu-panel { position: fixed; z-index: 110; display: flex; flex-direction: column; gap: 0.35rem; min-width: 11rem; padding: 0.5rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.4rem; box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35); } .action-menu-panel .btn { display: block; width: 100%; text-align: left; font: inherit; padding: 0.5rem 0.7rem; font-size: 0.85rem; } .table-thumb { width: 3rem; height: 3rem; border-radius: 0.3rem; object-fit: cover; display: block; } .table-thumb-empty { background: var(--bg); border: 1px dashed var(--line); } .table-image-field { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; } .table-image-field input[type='file'] { flex: 1 1 12rem; min-width: 0; padding: 0.4rem; font-size: 0.85rem; } .table-image-preview { width: 4.5rem; height: 4.5rem; border-radius: 0.3rem; object-fit: cover; flex-shrink: 0; } .table-preview { width: 100%; max-height: 14rem; object-fit: cover; border-radius: 0.4rem; border: 1px solid var(--line); } /* A fixed aspect ratio (rather than sizing to the photo's own dimensions) so a marker's percentage position lines up with the same spot on the image whether it's rendered here, in the admin editor, or at a different screen width — `object-fit: contain` (not `cover`) keeps the whole photo, and thus every marker coordinate, on-screen instead of letting some get cropped away. */ .table-overview-wrap { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 0.4rem; border: 1px solid var(--line); background: var(--bg); overflow: hidden; cursor: pointer; } .table-overview-wrap.is-busy { cursor: wait; opacity: 0.7; } .table-overview-image { display: block; width: 100%; height: 100%; object-fit: contain; pointer-events: none; } /* A classic map-pin: a square with three rounded corners (50% 50% 50% 0 leaves the bottom-left one sharp), rotated -45deg around that exact sharp corner so the corner itself — not the box center — lands on the `left`/`top` coordinate and becomes the pin's tip, with the round "head" swinging up above it. */ .table-marker { position: absolute; width: 1.6rem; height: 1.6rem; transform: translate(0, -100%) rotate(-45deg); transform-origin: 0 100%; border: none; border-radius: 50% 50% 50% 0; padding: 0; background: var(--bg-raised); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.45), inset 0 0 0 1.5px var(--gold); display: flex; align-items: center; justify-content: center; cursor: pointer; } .table-marker-label { transform: rotate(45deg); font: inherit; font-size: 0.62rem; font-weight: 700; color: var(--text); } .table-marker.is-selected, .table-marker.is-active { background: var(--gold); transform: translate(0, -100%) rotate(-45deg) scale(1.2); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); } .table-marker.is-selected .table-marker-label, .table-marker.is-active .table-marker-label { color: #201709; } .btn-danger { background: transparent; border-color: #5c1f1f; color: #f3a9a9; } .btn-danger:hover:not(:disabled) { background: #3a1414; } .btn-danger:disabled { opacity: 0.6; cursor: not-allowed; } .confirm-dialog-backdrop { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 1.5rem; background: rgba(0, 0, 0, 0.6); } .confirm-dialog { width: 100%; max-width: 24rem; padding: 1.5rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: 0.5rem; box-shadow: 0 20px 45px rgba(0, 0, 0, 0.45); animation: confirm-dialog-fade-in 0.15s ease-out; } @keyframes confirm-dialog-fade-in { from { opacity: 0; transform: translateY(-8px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } .confirm-dialog-title { font-size: 1.15rem; margin: 0 0 0.75rem; } .confirm-dialog-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 0.75rem; } .confirm-dialog-header .confirm-dialog-title { margin: 0; } .confirm-dialog-header-actions { display: flex; align-items: center; gap: 0.4rem; flex-shrink: 0; } .confirm-dialog-header-actions .btn { padding: 0.45rem 0.9rem; font-size: 0.85rem; } .confirm-dialog-message { margin: 0 0 1.25rem; color: var(--text-muted); } .confirm-dialog-message strong { color: var(--text); font-weight: 700; } .confirm-dialog-warning { display: flex; align-items: flex-start; gap: 0.6rem; margin: 0 0 1.5rem; padding: 0.75rem 0.9rem; border: 1px solid #5c1f1f; border-radius: 0.4rem; background: rgba(168, 64, 44, 0.14); color: #f3a9a9; } .confirm-dialog-warning svg { flex-shrink: 0; margin-top: 0.1rem; color: #f3a9a9; } .confirm-dialog-warning span { font-size: 0.85rem; font-weight: 600; line-height: 1.4; } .confirm-dialog-actions { display: flex; justify-content: flex-end; gap: 0.75rem; } /* Puts "Bearbeiten" and "Schließen" on opposite ends of the row instead of the usual right-aligned button cluster, since they aren't a confirm/cancel pair. */ .confirm-dialog-actions-split { justify-content: space-between; } .confirm-dialog-actions .btn { padding: 0.6rem 1.25rem; font-size: 0.9rem; } /* Beats the rule above on source order (same specificity), so it reads as a plain text action instead of a button-shaped one. */ .confirm-dialog-actions .btn-ghost { padding: 0; font-size: 0.8rem; text-decoration: underline; } .reservation-confirmed-dialog { max-width: 26rem; text-align: center; } .reservation-confirmed-flame { width: 3.25rem; height: 3.25rem; margin: 0 auto 1rem; color: var(--ember); animation: reservation-confirmed-flicker 2.2s ease-in-out infinite; } @keyframes reservation-confirmed-flicker { 0%, 100% { transform: rotate(0deg) scale(1); color: var(--ember); } 25% { transform: rotate(-3deg) scale(1.05); } 50% { transform: rotate(2deg) scale(0.97); color: var(--gold-bright); } 75% { transform: rotate(-2deg) scale(1.03); } } .reservation-confirmed-title { margin: 0 0 0.5rem; font-size: 1.5rem; color: var(--gold-bright); } .reservation-confirmed-message { margin: 0 0 1.5rem; color: var(--text-muted); } .reservation-confirmed-dialog .detail-list { text-align: left; } .reservation-confirmed-footnote { margin: 0 0 1.5rem; font-size: 0.82rem; color: var(--text-muted); } .reservation-confirmed-footnote strong { color: var(--text); font-weight: 600; } .reservation-confirmed-dialog .confirm-dialog-actions { justify-content: center; } .success-modal { max-width: 22rem; text-align: center; } .success-modal-icon { display: flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; margin: 0 auto 1rem; border: 1px solid var(--gold); border-radius: 50%; color: var(--gold-bright); } .success-modal .confirm-dialog-title { margin-bottom: 0.5rem; } .success-modal .confirm-dialog-message { margin-bottom: 1.5rem; } .success-modal .confirm-dialog-actions { justify-content: center; } .reservation-detail-dialog { max-width: 28rem; } .reservation-detail-dialog .table-preview { margin-bottom: 1.25rem; } .reservation-dialog-editing { max-width: 34rem; } /* The dialog card already provides the background/border/padding — strip `.reservation-form`'s own so the form doesn't render as a card-in-a-card. */ .reservation-form-dialog { background: none; border: none; padding: 0; } .detail-list { display: flex; flex-direction: column; gap: 0.6rem; margin: 0 0 1.25rem; } .detail-list > div { display: flex; justify-content: space-between; gap: 1rem; padding-bottom: 0.6rem; border-bottom: 1px solid var(--line); } .detail-list dt { color: var(--text-muted); font-size: 0.8rem; } .detail-list dd { margin: 0; text-align: right; font-weight: 500; } .detail-message { margin: 0 0 1.5rem; padding-top: 0.6rem; border-top: 1px solid var(--line); } .detail-message-label { display: block; margin-bottom: 0.35rem; color: var(--text-muted); font-size: 0.8rem; } .detail-message p { margin: 0; white-space: pre-wrap; } .empty-state { color: var(--text-muted); font-style: italic; } .staff-login-page { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 1.5rem; } .staff-login-form { width: 100%; max-width: 24rem; } .staff-login-heading { text-align: center; } .staff-login-heading .section-heading { font-size: 1.5rem; } .back-link { display: inline-flex; align-items: center; gap: 0.4rem; margin-bottom: 1.75rem; color: var(--text-muted); font-size: 0.85rem; text-decoration: none; } .back-link svg { transition: transform 0.15s ease; } .back-link:hover { color: var(--text); } .back-link:hover svg { transform: translateX(-3px); } /* Legal page */ .legal-page { padding: 3.5rem 0 4rem; } .legal-page h1 { font-size: 2.25rem; margin-bottom: 2rem; } .legal-page h2 { font-size: 1.25rem; color: var(--text); margin: 2.25rem 0 0.75rem; } .legal-page h3 { font-size: 1rem; margin: 1.5rem 0 0.5rem; } .legal-page p { color: var(--text-muted); max-width: 42rem; }