/*
 * The internal consent tool.
 *
 * Everything colour, radius and spacing related is a custom property, so a project styles the
 * dialog by redefining tokens instead of forking the file. The brand colour is taken from
 * --brand-primary when EXT:client defines one.
 */
:root {
    --cookie-bg: #ffffff;
    --cookie-fg: #1a1a1a;
    --cookie-muted: #4a4a4a;
    --cookie-border: #d0d0d0;
    --cookie-accent: var(--brand-primary, #005a9c);
    --cookie-accent-fg: #ffffff;
    --cookie-backdrop: rgba(0, 0, 0, 0.55);
    --cookie-radius: 0.25rem;
    --cookie-gap: 1rem;
    --cookie-max-width: 46rem;
    --cookie-z: 9999;
}

/* Hidden until the boot snippet has decided — no flash of a dialog for a visitor who decided
   months ago, and no flash of the page for one who has not. */
.cookie-consent[hidden] {
    display: none;
}

.cookie-consent {
    position: fixed;
    inset: 0;
    z-index: var(--cookie-z);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--cookie-gap);
    color: var(--cookie-fg);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.cookie-consent-backdrop {
    position: absolute;
    inset: 0;
    background: var(--cookie-backdrop);
}

.cookie-consent-dialog {
    position: relative;
    width: 100%;
    max-width: var(--cookie-max-width);
    max-height: calc(100vh - 2 * var(--cookie-gap));
    overflow-y: auto;
    padding: calc(var(--cookie-gap) * 1.5);
    background: var(--cookie-bg);
    border-radius: var(--cookie-radius);
    box-shadow: 0 0.5rem 2rem rgba(0, 0, 0, 0.25);
}

[data-consent-layout='bar'] .cookie-consent {
    align-items: flex-end;
}

[data-consent-layout='bar'] .cookie-consent-dialog {
    max-width: none;
}

[data-consent-layout='box'] .cookie-consent {
    align-items: flex-end;
    justify-content: flex-end;
}

[data-consent-layout='box'] .cookie-consent-dialog {
    max-width: 26rem;
}

[data-consent-layout='bar'] .cookie-consent-backdrop,
[data-consent-layout='box'] .cookie-consent-backdrop {
    background: transparent;
    pointer-events: none;
}

.cookie-consent-title {
    margin: 0 0 0.5rem;
    font-size: 1.125rem;
}

.cookie-consent-text {
    margin-bottom: var(--cookie-gap);
    color: var(--cookie-muted);
}

.cookie-consent-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cookie-gap);
    margin: 0 0 var(--cookie-gap);
    padding: 0;
    list-style: none;
}

.cookie-consent-links a {
    color: var(--cookie-accent);
}

/* The three buttons carry the same weight — same size, same contrast, same position. A greyed
   out decline next to a coloured accept is a dark pattern and makes the consent void. */
.cookie-consent-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* The buttons sit at the end of the list and scroll with it. A version that kept them at the bottom
   edge was tried and dropped: it has to reach over the padding of the dialog, cover what scrolls
   underneath and keep its own spacing right on every layer — three problems that only exist because
   the bar floats. At the end of the content there are none of them. */
.cookie-consent-layer > .cookie-consent-actions {
    margin-top: calc(var(--cookie-gap) * 1.5);
}

.cookie-consent-button {
    flex: 1 1 12rem;
    min-height: 2.75rem;
    padding: 0.625rem 1rem;
    color: var(--cookie-accent-fg);
    font: inherit;
    font-weight: 600;
    background: var(--cookie-accent);
    border: 0.125rem solid var(--cookie-accent);
    border-radius: var(--cookie-radius);
    cursor: pointer;
}

.cookie-consent-button:focus-visible {
    outline: 0.1875rem solid var(--cookie-fg);
    outline-offset: 0.125rem;
}

/* No margin of its own: the distance to the button bar belongs to the bar, which brings it as its
   top margin. Two margins would add up and leave a hole above the buttons. */
.cookie-consent-categories {
    margin-bottom: 0;
}

/* One block per category, with room around it: expanded, the list used to run together into one
   wall of text in which the switches were hard to find. */
.cookie-consent-category {
    padding: 1rem 0;
    border-top: 0.0625rem solid var(--cookie-border);
}

.cookie-consent-category:last-child {
    padding-bottom: 0;
}

.cookie-consent-category-head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    /* Mittig und nicht auf der Grundlinie: „immer aktiv" saß sonst auf der Unterkante des fetten
       Titels und sah aus, als hinge es daran. */
    align-items: center;
    justify-content: space-between;
}

.cookie-consent-switch {
    display: inline-flex;
    gap: 0.5rem;
    align-items: center;
    font-weight: 600;
    cursor: pointer;
}

.cookie-consent-switch input {
    width: 1.25rem;
    height: 1.25rem;
}

/* Die beiden Beisätze am Schalter — „immer aktiv" an einer Kategorie, „abweichend von der
   Kategorie" an einem Dienst. Sie stehen NEBEN dem Label, nicht darin, und richteten sich deshalb
   an der Grundlinie des fetten Namens aus: ohne Abstand und optisch tiefer als er. Mittig und mit
   Luft davor lesen sie sich als das, was sie sind — eine Anmerkung, keine Fortsetzung des Namens. */
.cookie-consent-note,
.cookie-consent-deviation {
    display: inline-block;
    margin-left: 0.5rem;
    vertical-align: middle;
    white-space: nowrap;
    color: var(--cookie-muted);
    font-size: 0.8125rem;
}

/* Im Kopf einer Kategorie ordnet das Flex-Layout schon an; ein zweiter Abstand davor doppelt. */
.cookie-consent-category-head > .cookie-consent-note {
    margin-left: 0;
}

/* Eine Kategorie, in der nicht alles gewählt ist, zeigt das am Kasten selbst: `indeterminate` ist
   im Browser ein Strich statt eines Hakens. Ohne das sähe eine Kategorie mit einem abgewählten
   Dienst aus wie eine vollständig gewählte, solange die Dienste zugeklappt sind. */
.cookie-consent-switch input:indeterminate {
    accent-color: var(--cookie-muted);
}

/* Everything under a switch lines up with its LABEL, not with the checkbox: 1.25rem for the box
   and 0.5rem for the gap. A description that starts under the box reads as a second column. */
.cookie-consent-category-text {
    margin: 0.25rem 0 0.5rem 1.75rem;
    color: var(--cookie-muted);
    font-size: 0.875rem;
}

.cookie-consent-category > .cookie-consent-services {
    margin-left: 1.75rem;
}

/* Consents given at the element itself. Set off from the categories, because they belong to no
   category — but with the same switches, because they are the same kind of decision. */
.cookie-consent-extra {
    margin: var(--cookie-gap) 0 0;
    padding-top: 0.75rem;
    border-top: 0.0625rem solid var(--cookie-border);
}

.cookie-consent-extra[hidden] {
    display: none;
}

.cookie-consent-extra-title {
    margin: 0 0 0.25rem;
    font-size: 1rem;
}

.cookie-consent-extra-text {
    margin: 0 0 0.5rem;
    color: var(--cookie-muted);
}

/* What a withdrawal could not take back. Set off from the switches above, because it answers what
   the visitor just did instead of asking something. */
.cookie-consent-residue {
    margin: var(--cookie-gap) 0 0;
    padding: 0.75rem;
    border: 0.0625rem solid var(--cookie-border);
    border-left: 0.25rem solid var(--cookie-accent);
    border-radius: var(--cookie-radius);
}

.cookie-consent-residue[hidden] {
    display: none;
}

.cookie-consent-residue-title {
    margin: 0 0 0.25rem;
    font-size: 1rem;
}

.cookie-consent-residue-text {
    margin: 0 0 0.5rem;
    color: var(--cookie-muted);
}

.cookie-consent-residue-list {
    margin: 0 0 0.75rem;
    padding-left: 1.25rem;
}

/* Reloading is the offer, closing the way past it — same size, same weight, next to each other. */
.cookie-consent-residue .cookie-consent-actions {
    margin-top: 0.5rem;
}

/* A control, not a sentence in accent colour: a target that can be hit, and a hover that says it
   answers. */
.cookie-consent-services > summary {
    padding: 0.25rem 0;
    color: var(--cookie-accent);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
}

.cookie-consent-services > summary:hover {
    text-decoration: underline;
}

.cookie-consent-service {
    padding: 0.75rem 0 0.75rem 1rem;
    border-left: 0.125rem solid var(--cookie-border);
}

/* One line between two services. Without it, an expanded category is a single column of text in
   which a switch and the description of the service above it sit next to each other. */
.cookie-consent-service + .cookie-consent-service {
    border-top: 0.0625rem solid var(--cookie-border);
}

/* Aligned with the label like everything else, and the table inside scrolls instead of squeezing
   five columns into 20 rem — it is the widest thing in the dialog. */
.cookie-consent-service-details {
    margin-left: 1.75rem;
    overflow-x: auto;
    color: var(--cookie-muted);
    font-size: 0.875rem;
}

/* The declaration on the page. Nothing here had a margin of its own, so heading, text, facts and
   table stood flush against each other and the whole list read as one paragraph. The extension has
   to bring this spacing itself: a project stylesheet resets the margins of headings, and the
   declaration is not part of its content styles. */
.cookie-policy-state {
    margin: 0 0 var(--cookie-gap);
}

/* A line means one thing here: a new category begins. Services are grouped by the rule on their
   left, the way the dialog groups them — with a line above every service as well, the reader could
   not tell whether a line ended something or started it, and the rows of the cookie table looked
   like separators of the same kind. */
.cookie-policy-category {
    margin-top: calc(var(--cookie-gap) * 1.5);
}

.cookie-policy-category + .cookie-policy-category {
    margin-top: calc(var(--cookie-gap) * 2);
    padding-top: calc(var(--cookie-gap) * 1.5);
    border-top: 0.0625rem solid var(--cookie-border);
}

.cookie-policy-category > h2,
.cookie-policy-category > h3,
.cookie-policy-category > h4,
.cookie-policy-category > h5,
.cookie-policy-category > h6 {
    margin: 0 0 0.5rem;
}

.cookie-policy-category > p {
    margin: 0 0 0.75rem;
}

.cookie-policy-service {
    margin-top: var(--cookie-gap);
    padding-left: 1rem;
    border-left: 0.125rem solid var(--cookie-border);
}

.cookie-policy-service > h2,
.cookie-policy-service > h3,
.cookie-policy-service > h4,
.cookie-policy-service > h5,
.cookie-policy-service > h6 {
    margin: 0 0 0.5rem;
}

.cookie-policy-service > p {
    margin: 0 0 0.75rem;
}

.cookie-policy-table {
    width: 100%;
    margin: 0.75rem 0 0;
    border-collapse: collapse;
    font-size: 0.8125rem;
}

.cookie-policy-table th,
.cookie-policy-table td {
    padding: 0.375rem 0.5rem;
    text-align: left;
    vertical-align: top;
    border-bottom: 0.0625rem solid var(--cookie-border);
}

/* A width the five columns can live in, and a container that scrolls below it. Percentages were
   tried first and were worse: with a fixed share for the purpose, the name column shrank to one
   character per line — a cookie name written downwards. */
.cookie-policy-table {
    min-width: 32rem;
}

.cookie-policy-table th {
    font-weight: 600;
    white-space: nowrap;
}

.cookie-policy-table td:first-child {
    min-width: 9rem;
}

.cookie-policy-table code {
    overflow-wrap: anywhere;
}

.cookie-policy-facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.25rem 1rem;
    margin: 0.75rem 0;
}

.cookie-policy-facts dt {
    color: var(--cookie-muted);
}

.cookie-policy-facts dd {
    margin: 0;
}

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

/* The way to the settings is a link between two buttons. Without an underline it reads as a
   caption in a project theme that styles neither — on the site this was reported from, the visitor
   could not tell it was a control at all. */
.enable-settings {
    text-decoration: underline;
}

@media (prefers-reduced-motion: no-preference) {
    .cookie-consent-dialog {
        animation: cookie-consent-in 0.2s ease-out;
    }

    @keyframes cookie-consent-in {
        from {
            transform: translateY(0.5rem);
            opacity: 0;
        }
    }
}

/* The way back to the decision — shown only once there IS one to come back to. Which state
   applies sits on the root element before the first paint, so this never flashes into view. */
.cookie-consent-reopen {
    display: none;
}

[data-consent="granted"] .cookie-consent-reopen {
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    padding: 0.5rem 0.875rem;
    color: var(--cookie-fg);
    font: inherit;
    background: var(--cookie-bg);
    border: 0.0625rem solid var(--cookie-border);
    border-radius: var(--cookie-radius);
    cursor: pointer;
}

/* Floating: above the page, out of the content flow. The other variant stays where it is
   rendered, so a project can place and style it like any other button of its own. */
[data-consent="granted"] .cookie-consent-reopen-floating {
    position: fixed;
    inset-inline-start: 1rem;
    inset-block-end: 1rem;
    z-index: calc(var(--cookie-z) - 1);
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.15);
}

[data-consent="granted"] .cookie-consent-reopen:hover {
    border-color: var(--cookie-accent);
}

[data-consent="granted"] .cookie-consent-reopen:focus-visible {
    outline: 0.1875rem solid var(--cookie-accent);
    outline-offset: 0.125rem;
}

/* Only the symbol. The label keeps its place in the tree — a button whose name is gone is a button
   nobody can ask for — and is hidden the one way that leaves it readable to a screen reader. */
[data-consent="granted"] .cookie-consent-reopen-iconic {
    justify-content: center;
    width: var(--cookie-reopen-icon-size, 2.75rem);
    height: var(--cookie-reopen-icon-size, 2.75rem);
    min-height: 0;
    padding: 0;
    border-radius: var(--cookie-reopen-icon-radius, 50%);
}

.cookie-consent-reopen-iconic .cookie-consent-reopen-label {
    position: absolute;
    width: 0.0625rem;
    height: 0.0625rem;
    margin: -0.0625rem;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* One template, two states: without the icon mode the symbol is not rendered away, it is hidden. */
.cookie-consent-reopen:not(.cookie-consent-reopen-iconic) .cookie-consent-reopen-icon {
    display: none;
}

/* While the dialog is open the button would sit behind it and compete with its own dialog. */
[data-consent-open="1"] .cookie-consent-reopen {
    display: none;
}
