@import url('base.css');
@import url('buttons.css');

/* ==========================================
   Reusable Form Components
   Universal form styling for all pages
   ========================================== */

/* ==========================================
   Form Page Container (Create / Edit pages)
   Single source of truth — do NOT override per page.
   ========================================== */

/* Outer container — matches portal-wide width like .page-container / table-container */
.create-container-wide {
    max-width: 1400px;
    width: 100%;
    margin: 0 auto;
    padding: 0 20px;
}

/* Inner card wrapping the form */
.create-box {
    background: var(--dark-bg-tertiary);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 16px;
    padding: 40px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    width: 100%;
    max-width: 100%;
}

/* Form section block inside a create-box */
.form-section {
    margin-bottom: 30px;
    padding-bottom: 30px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.form-section:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}

/* Section title inside forms — typography is unified via portal-common.css
   (.section-title selector). Form-section just adds bottom spacing to next field. */
.form-section > .section-title,
.form-section > h2,
.form-section > h3 {
    margin-bottom: 24px;
}

/* ==========================================
   Form Groups & Fields
   ========================================== */
.form-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 24px;
}

.form-group:last-child {
    margin-bottom: 0;
}

.form-group label {
    font-size: var(--font-size-small, 0.875rem);
    font-weight: var(--font-weight-semibold, 600);
    color: var(--text-primary);
    margin-bottom: 0;
}

/* ==========================================
   Read-Only Field Display
   For fields where the value is fixed (e.g. account_id passed via URL).
   Visually distinct from editable inputs.
   ========================================== */
.readonly-display {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 15px 20px;
    background: var(--dark-bg-secondary);
    border: 1px dashed rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    color: var(--text-primary);
    font-size: var(--font-size-body, 1rem);
}

.readonly-display-primary {
    font-weight: 600;
    color: var(--text-primary);
}

.readonly-display-secondary {
    font-size: 0.85rem;
    color: var(--text-muted);
    font-family: 'Courier New', monospace;
}

/* Input Fields (text, email, password, tel, date, etc.) */
.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 15px 20px;
    font-size: var(--font-size-body, 1rem);
    font-family: var(--font-family);
    background: var(--dark-bg-secondary);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    color: var(--text-primary);
    transition: var(--transition-smooth);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(34, 199, 224, 0.1);
}

.form-group input::placeholder,
.form-group textarea::placeholder {
    color: var(--text-muted);
}

/* Select specific styling */
.form-group select {
    cursor: pointer;
}

.form-group select option {
    background: var(--dark-bg-secondary);
    color: var(--text-primary);
}

/* Textarea specific */
.form-group textarea {
    resize: vertical;
    min-height: 100px;
}

/* Date input styling */
.form-group input[type="date"] {
    color-scheme: dark;
}

.form-group input[type="date"]::-webkit-calendar-picker-indicator {
    filter: invert(1);
    cursor: pointer;
}

/* ==========================================
   Form Layout Helpers
   ========================================== */

/* Side-by-side fields */
.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    margin-bottom: 24px;
}

.form-row:last-child {
    margin-bottom: 0;
}

/* Three columns */
.form-row-3 {
    grid-template-columns: repeat(3, 1fr);
}

/* Four columns */
.form-row-4 {
    grid-template-columns: repeat(4, 1fr);
}

/* Responsive form rows */
@media (max-width: 768px) {
    .form-row,
    .form-row-3,
    .form-row-4 {
        grid-template-columns: 1fr;
        gap: 25px;
    }
}

/* ==========================================
   Form Validation & Error States
   ========================================== */

.form-group input.error,
.form-group select.error,
.form-group textarea.error {
    border-color: #ff4444;
}

.error-message {
    font-size: var(--font-size-small, 0.875rem);
    color: #ff4444;
    display: none;
}

/* The hint every entity-forms field renders. It had no rule at all, so it inherited body
   text: 1rem, full-strength white, sitting under the input at a larger size than the label
   above it. Same treatment as .form-hint, which is the same thing written in page markup. */
.field-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    line-height: 1.4;
}

/* What an `amount` field actually parsed. '1.500' is fifteen hundred to a German reader and
   one and a half to Number(), and this line is where that disagreement becomes visible —
   before the value is submitted rather than after. Empty until there is something to echo,
   so it must not reserve a line of its own. */
.field-echo {
    font-size: 0.75rem;
    color: var(--primary-color);
    font-variant-numeric: tabular-nums;
    min-height: 0;
    line-height: 1.4;
}

.field-echo:empty {
    display: none;
}

.error-message.show {
    display: block;
}

/* Required field indicator */
.required {
    color: var(--primary-color);
    font-weight: 700;
}

/* ==========================================
   Alert Messages
   ========================================== */
.alert {
    padding: 15px 20px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: var(--font-size-small, 0.875rem);
    animation: slideDown 0.3s ease;
}

@keyframes slideDown {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.alert-error {
    background: rgba(255, 68, 68, 0.1);
    border: 1px solid rgba(255, 68, 68, 0.3);
    color: #ff4444;
}

.alert-success {
    background: rgba(34, 197, 94, 0.1);
    border: 1px solid rgba(34, 197, 94, 0.3);
    color: #22c55e;
}

.alert-warning {
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.3);
    color: #fbbf24;
}

.alert-info {
    background: rgba(59, 130, 246, 0.1);
    border: 1px solid rgba(59, 130, 246, 0.3);
    color: #3b82f6;
}

.alert-icon {
    font-size: 1.125rem;
}

.alert-message {
    flex: 1;
}

/* ==========================================
   Buttons
   ========================================== */

/* Form-specific button overrides (base styles in buttons.css) */
form .btn-primary,
form .btn-secondary {
    width: 100%;
    padding: 16px;
    border-radius: 10px;
}

form .btn-primary {
    margin-top: 10px;
}

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

/* Button Loading State */
.button-text,
.button-loader {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

.loader {
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;   /* @keyframes spin: base.css */
}

/* ==========================================
   Form Options & Checkboxes
   ========================================== */

/* ==========================================
   Checkboxes — ONE definition for the whole portal
   ==========================================
   `.checkbox-container` and `.checkbox-label` are the same control under two names; the
   markup uses both (3 and 23 times) and renaming 23 call sites buys nothing, so both are
   declared here together. What matters is that they are declared ONCE.

   Before this the box came in three sizes (16 / 18 / 20px) and three accent colours
   (primary, danger, and a hard-coded #f59e0b), because `.checkbox-label` was redefined in
   five page stylesheets and the copies had drifted: the four delete pages had 20px/danger,
   products/edit had 18px/primary, and the same class therefore meant something different
   depending on which page you were standing on.

   Do NOT redefine .checkbox-label per page. For the red confirmation box on a delete
   page, add `.checkbox-confirm` — that treatment is a modifier, not a new control.
   ========================================== */

.checkbox-container,
.checkbox-label {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: var(--font-size-small, 0.875rem);
    color: var(--text-secondary);
    cursor: pointer;
}

.checkbox-container input[type="checkbox"],
.checkbox-label input[type="checkbox"] {
    width: 18px;
    height: 18px;
    flex-shrink: 0;          /* never squashed by a long label */
    cursor: pointer;
    accent-color: var(--primary-color);
}

/* ── Confirmation of something destructive ──
   The delete pages ask the user to tick a box before the button unlocks. It gets the
   danger tone and a tinted panel so it reads as a gate rather than a preference. */
.checkbox-confirm {
    align-items: flex-start;
    padding: 1rem;
    border: 1px solid rgba(220, 53, 69, 0.25);
    border-radius: 8px;
    background: rgba(220, 53, 69, 0.05);
    color: var(--text-primary);
}

.checkbox-confirm:hover {
    border-color: var(--danger-color);
    background: rgba(220, 53, 69, 0.1);
}

.checkbox-confirm input[type="checkbox"] {
    accent-color: var(--danger-color);
    margin-top: 1px;         /* optical alignment with the first line of a wrapping label */
}

/* The label of a checkbox is a click target; dragging across it should not select the
   text instead of toggling the box. */
.checkbox-container span,
.checkbox-label span {
    user-select: none;
}

/* Radio buttons */
.radio-container {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--font-size-small, 0.875rem);
    color: var(--text-secondary);
    cursor: pointer;
}

.radio-container input[type="radio"] {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--primary-color);
}

/* ==========================================
   Form Hints & Helper Text
   ========================================== */

.form-hint {
    margin-top: 5px;
    font-size: 0.75rem;
    color: var(--text-muted);
    line-height: 1.4;
}

.password-requirements {
    margin-top: 5px;
}

.password-requirements small {
    color: var(--text-muted);
    font-size: 0.75rem;
    line-height: 1.4;
}

/* ==========================================
   Links
   ========================================== */

.link {
    color: var(--primary-color);
    text-decoration: none;
    transition: var(--transition-smooth);
}

.link:hover {
    color: var(--secondary-color);
    text-decoration: underline;
}

/* ==========================================
   Form Sections (for multi-section forms)
   ========================================== */

.form-section {
    padding: 30px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    margin-bottom: 20px;
}

.form-section:last-of-type {
    border-bottom: none;
}

.section-title {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 20px;
    display: flex;
    align-items: center;
    gap: 10px;
}

.section-title small {
    font-size: var(--font-size-small, 0.875rem);
    font-weight: 400;
    color: var(--text-muted);
}

/* Responsive adjustments */
@media (max-width: 640px) {
    .form-section {
        padding: 20px 0;
    }

    .section-title {
        font-size: 1.125rem;
    }
}

/* ==========================================
   Collapsible sections
   ==========================================
   A <details> styled as a form section. Used by the content upload form and by every
   optional section entity-forms.js renders, so it lives here rather than next to either.
   The fields inside stay in the DOM while folded — this hides them, it does not remove
   them, which is why collect() and find-in-page still work on a closed section. */

details.form-section.collapsible,
details.collapsible {
    padding: 0;
}

.collapsible-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    cursor: pointer;
    list-style: none;
    border-radius: 10px;
}

.collapsible-summary::-webkit-details-marker { display: none; }
.collapsible-summary:hover { background: rgba(255, 255, 255, 0.03); }
.collapsible-summary:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: -2px;
}

.collapsible-title { font-weight: 600; }

.collapsible-hint {
    flex: 1;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.collapsible-chevron {
    color: var(--text-muted);
    transition: transform 0.15s;
}

details.collapsible[open] .collapsible-chevron { transform: rotate(90deg); }

.collapsible-body { padding: 4px 16px 16px; }

/* A folded section is a row, not a block — without this the closed state keeps the 30px
   padding of an open form section and looks like an empty area rather than a header. */
details.form-section.collapsible:not([open]) {
    margin-bottom: 8px;
}

details.form-section.collapsible .section-description {
    margin-top: 0;
}

/* ==========================================
   File Upload Styling
   ========================================== */

.file-upload-container {
    position: relative;
}

.file-upload-input {
    display: none;
}

.file-upload-label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 15px 20px;
    background: var(--dark-bg-secondary);
    border: 2px dashed rgba(255, 255, 255, 0.2);
    border-radius: 10px;
    color: var(--text-secondary);
    cursor: pointer;
    transition: var(--transition-smooth);
}

.file-upload-label:hover {
    border-color: var(--primary-color);
    background: rgba(34, 199, 224, 0.05);
    color: var(--text-primary);
}

.file-upload-icon {
    font-size: var(--font-size-h3, 1.5rem);
}

/* ==========================================
   Toggle Switch
   ========================================== */

.toggle-container {
    display: flex;
    align-items: center;
    gap: 10px;
}

.toggle-switch {
    position: relative;
    width: 50px;
    height: 26px;
}

.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(255, 255, 255, 0.1);
    transition: 0.4s;
    border-radius: 26px;
}

.toggle-slider:before {
    position: absolute;
    content: "";
    height: 20px;
    width: 20px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.4s;
    border-radius: 50%;
}

.toggle-switch input:checked + .toggle-slider {
    background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
}

.toggle-switch input:checked + .toggle-slider:before {
    transform: translateX(24px);
}

/* ==========================================
   Declarative forms (js/entity-forms.js)
   Classes the shared form renderer emits and that were not already covered above.
   ========================================== */

/* Explanatory copy under a section title. */
.section-description {
    margin: -4px 0 16px;
    font-size: 0.86rem;
    line-height: 1.55;
    color: var(--text-muted);
}

/* Read-only value rendered in place of an input (field type 'static'). */
.form-static {
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 0.9rem;
    color: var(--text-color);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.form-group--checkbox .checkbox-label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-size: 0.92rem;
}

.form-group--checkbox .checkbox-label input {
    width: auto;
    margin: 0;
}

/* Pointer from a single-purpose create page to the guided flow. */
.wizard-hint {
    padding: 12px 16px;
    margin-bottom: 22px;
    border-radius: 10px;
    font-size: 0.86rem;
    line-height: 1.55;
    color: var(--text-muted);
    background: rgba(139, 92, 246, 0.07);
    border: 1px solid rgba(139, 92, 246, 0.2);
}

.wizard-hint a {
    color: var(--primary-color);
    font-weight: 600;
}

/* ==========================================
   Authenticator apps (js/forms.js)
   ==========================================
   Sits above the enrolment QR code on the login page and on the security page. In forms.css
   because that is the one stylesheet both of them load — the login page has no
   portal-common.css. */

.auth-apps {
    margin: 0 0 18px;
    padding: 14px 16px;
    background: var(--dark-bg-secondary);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    text-align: left;
}

.auth-apps-intro {
    margin: 0 0 10px;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-primary);
}

.auth-apps-list {
    margin: 0 0 10px;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.auth-apps-list li {
    font-size: 0.82rem;
    color: var(--text-secondary);
}

.auth-app-name {
    display: inline-block;
    min-width: 11.5rem;
    font-weight: 600;
    color: var(--text-primary);
}

.auth-apps-list a {
    color: var(--primary-color);
    text-decoration: none;
}

.auth-apps-list a:hover {
    text-decoration: underline;
}

.auth-apps-note {
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-muted);
}

/* The name stops being a column once it no longer fits beside the links. */
@media (max-width: 520px) {
    .auth-app-name {
        display: block;
        min-width: 0;
        margin-bottom: 2px;
    }
}

/* ==========================================
   Account role choices (portal/accounts/create)
   ==========================================
   Prominent by design: these three flags decide what the account may do, and they used not to be
   askable at all. A row of bare checkboxes would have been the cheap version — a card each, with
   the consequence spelled out, is what lets somebody choose without knowing the data model. */

.role-choices {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px;
}

.role-choice {
    display: flex;
    gap: 12px;
    padding: 14px 16px;
    background: var(--dark-bg-secondary);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    cursor: pointer;
    transition: var(--transition-smooth);
}

.role-choice:hover {
    border-color: rgba(34, 199, 224, 0.4);
}

/* :has, so the whole card shows the state rather than only the box in its corner. */
.role-choice:has(input:checked) {
    border-color: var(--primary-color);
    background: rgba(34, 199, 224, 0.08);
}

.role-choice input {
    width: 18px;
    height: 18px;
    margin-top: 2px;
    flex-shrink: 0;
    accent-color: var(--primary-color);
    cursor: pointer;
}

.role-choice-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.role-choice-title {
    font-weight: 600;
    color: var(--text-primary);
}

.role-choice-summary {
    font-size: 0.82rem;
    color: var(--text-primary);
}

.role-choice-detail {
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-muted);
}
