.admin-only { display: none; }
body[data-admin-mode="on"] .admin-only { display: revert; }

/* The fixed admin-mode-bar sits at the bottom-right of the viewport at every scroll position, so
   any page whose real content also reaches the bottom of the document (e.g. the film detail page's
   .film-links-form, whose last input/button is the last substantial content before the footer) gets
   its content covered by the bar once scrolled that far. Reserving matching space at the bottom of
   the content column keeps the bar floating over empty margin instead of over real controls, for
   every route this base layout renders (:has() needs no markup change and no second {% if is_admin() %}
   in base.html.twig, which AdminModeContractTest::testAdminModeBarAndScriptStayInsideOneUnbrokenIsAdminBlock
   pins to exactly one occurrence). */
body:has(.admin-mode-bar) main.shell { padding-bottom: 7rem; }

.admin-mode-bar { position: fixed; right: 1rem; bottom: 1rem; z-index: 40; display: flex; flex-direction: column; gap: .5rem; align-items: flex-end; }
.admin-mode-toggle { padding: .55rem 1rem; color: var(--paper); font: bold .78rem/1 Arial, sans-serif; letter-spacing: .04em; background: var(--ink); border: 1px solid var(--ink); border-radius: .5rem; box-shadow: 0 .3rem .8rem rgba(0, 0, 0, .2); cursor: pointer; }
.view-as-user-form { margin: 0; }
.admin-mode-toggle[aria-pressed="false"] { color: var(--ink); background: var(--paper); border-color: var(--line); }
.admin-mode-toggle:hover { color: var(--paper); background: var(--accent); border-color: var(--accent); }
.admin-mode-toggle:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.admin-mode-link { padding: .5rem .9rem; color: var(--ink); font: .78rem/1.2 Arial, sans-serif; text-decoration: none; background: var(--paper); border: 1px solid var(--line); border-radius: .5rem; box-shadow: 0 .3rem .8rem rgba(0, 0, 0, .2); }
.admin-mode-link:hover, .admin-mode-link:focus-visible { color: var(--paper); background: var(--ink); border-color: var(--ink); text-decoration: none; }

/* The floating bar is a two-mode switch at every width. Admin mode: "Настройки" + "Как пользователь";
   view-as-user mode: only "Вернуться в админ-режим". Every other admin link stays reachable from
   /admin/settings. The link is also .admin-only, whose `display: revert` (0,2,1) would drop the flex
   centering, so its selector carries one more class (0,3,0). */
.admin-mode-bar .admin-mode-link.admin-only, .admin-mode-bar .admin-view-as-toggle { display: inline-flex; align-items: center; justify-content: center; min-height: 2.5rem; padding-block: 0; padding-inline: 1.1rem; font-size: .85rem; line-height: 1; }

@media (prefers-reduced-motion: reduce) {
    .admin-mode-bar * { transition: none !important; }
}

body[data-admin-mode="on"] .film-card { display: flex; flex-direction: column; }
body[data-admin-mode="on"] .film-card .film-card-link { height: auto; flex: 1; }
body[data-admin-mode="on"] .film-links-edit-forms { display: contents; }
body[data-admin-mode="on"] .film-card-admin { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; margin-left: auto; }
/* Fail-safe standalone rendering (is_admin() true but userMarks/user_context wasn't wired for this
   render path -- templates/catalog/index.html.twig's {% elseif is_admin() %} branch): here
   .film-card-admin is its own full-width row directly under .film-card, not an item inside the
   status/rating widget, so the shared margin-left:auto above would instead shrink-and-right-align the
   whole block against .film-card's column layout. Reset it and restore the original border-top
   separator + padding, pushing only the delete button itself to the row's right edge -- exactly the
   pre-restore-admin-rating-ui look. */
body[data-admin-mode="on"] .film-card-admin--standalone { margin-left: 0; padding: .7rem 1rem .9rem; border-top: 1px solid var(--line); }
.film-card-admin--standalone .film-card-delete { margin-left: auto; }

/* Admin actions of a card sit under the shared status/rating widget (the admin has no separate status
   or rating UI any more); the delete/links buttons share one look. */
.film-card-delete:focus-visible, .film-card-links:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.film-card-delete { padding: .3rem .7rem; color: var(--ink); font: .72rem/1 Arial, sans-serif; background: transparent; border: 1px solid var(--line); border-radius: .3rem; cursor: pointer; }
/* Navigates to /admin/films/{slug}/links (the general links editor) -- a real page, not an AJAX action, so
   it's a <button> handled by admin-mode.js's own data-admin-action delegation like .film-card-delete
   above, never an <a>: AdminModeContractTest::testCatalogCardCarriesAnAdminOnlySiblingOfTheLinkWithoutNewAnchors
   pins the film card to exactly one real anchor (the poster/title link) and zero <a> tags inside any
   .film-card-admin block. */
.film-card-links { padding: .3rem .7rem; color: var(--ink); font: .72rem/1 Arial, sans-serif; background: transparent; border: 1px solid var(--line); border-radius: .3rem; cursor: pointer; }
.film-card-admin-message { flex-basis: 100%; margin: .3rem 0 0; color: var(--accent); font: .72rem/1.3 Arial, sans-serif; }
.film-card-admin[aria-busy="true"] { opacity: .6; }
.film-card.is-removing { opacity: 0; transition: opacity .2s ease; }

@media (prefers-reduced-motion: reduce) {
    .film-card.is-removing { transition: none; }
}

.film-card-watch-links { display: flex; flex-direction: column; gap: .3rem; flex-basis: 100%; }
.film-card-watch-links-search { padding: .3rem .7rem; color: var(--ink); font: .72rem/1 Arial, sans-serif; background: transparent; border: 1px solid var(--line); border-radius: .3rem; cursor: pointer; }
.film-card-watch-links[aria-busy="true"] { opacity: .6; }
.film-card-watch-links-results:not([hidden]) { display: flex; flex-direction: column; gap: .4rem; }
.film-card-watch-links-results ul { display: flex; flex-direction: column; gap: .3rem; margin: 0; padding: 0; list-style: none; }
.film-card-watch-links-results li { display: flex; align-items: center; gap: .4rem; }
.film-card-watch-links-results button { flex: none; padding: .3rem .6rem; color: var(--ink); font: .72rem/1 Arial, sans-serif; white-space: nowrap; background: transparent; border: 1px solid var(--line); border-radius: .3rem; cursor: pointer; }
.film-card-watch-links-results button:hover { border-color: var(--accent); color: var(--accent); }
.film-card-watch-links-results button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.film-card-watch-links-results li > a { flex: 1 1 9rem; min-width: 0; overflow-wrap: anywhere; }
.film-card-watch-links-search:hover { border-color: var(--accent); color: var(--accent); }
.film-card-watch-links-search:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The one «search watch links» panel of the film page's admin block. */
.film-page-watch-links { margin: 0 0 1rem; align-items: flex-start; }
.film-page-watch-links .film-page-watch-links-note { margin: 0; color: var(--muted); font: .78rem/1.4 Arial, sans-serif; }
.film-page-watch-links .film-card-watch-links-search { padding: .5rem .9rem; font-size: .85rem; }
.film-page-watch-links .film-card-admin-message { margin: 0; color: var(--accent); font: .8rem/1.4 Arial, sans-serif; }
/* Where a search result comes from: platform icon + name (admin-watch-links.js, admin-import-watch-links.js). */
.watch-source { font: .8rem/1.4 Arial, sans-serif; overflow-wrap: anywhere; }
.watch-source a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: .2em; }
.watch-source-name { display: flex; align-items: center; gap: .4rem; margin: 0 0 .15rem; font-weight: 700; }
.watch-source-icon { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 18px; height: 18px; line-height: 1; }
img.watch-source-icon { display: inline-block; object-fit: contain; border-radius: .2rem; vertical-align: middle; margin-right: .3rem; }
.watch-source-name .watch-source-icon, .film-card-watch-links-results li > .watch-source-icon, .admin-import-watch-links-line li > .watch-source-icon { margin-right: 0; }
.watch-candidate-meta { flex: none; color: var(--muted); font-size: .72rem; white-space: nowrap; }
.watch-source-hint { color: var(--muted); }

/* Popover opened by clicking the age-rating badge on a film card (admin-mode.js
   initializeAgeRatingClick()). Appended to <body> and absolutely positioned under the badge, so it
   floats above the card grid and is dismissed on any outside click or Escape. */
.age-rating-menu { z-index: 50; display: flex; flex-direction: column; gap: .2rem; padding: .35rem; background: var(--paper); border: 1px solid var(--line); border-radius: .5rem; box-shadow: 0 .3rem .8rem rgba(0, 0, 0, .2); }
.age-rating-menu-item { padding: .35rem .7rem; color: var(--ink); font: bold .75rem/1 Arial, sans-serif; text-align: left; background: transparent; border: 1px solid transparent; border-radius: .35rem; cursor: pointer; }
.age-rating-menu-item:hover, .age-rating-menu-item:focus-visible { color: var(--paper); background: var(--accent); border-color: var(--accent); outline: none; }
.age-rating-menu-item[aria-checked="true"] { border-color: var(--accent); }
.age-rating-menu-item[disabled] { opacity: .5; cursor: default; }
.age-rating-menu-clear { margin-top: .15rem; padding-top: .45rem; border-top: 1px solid var(--line); border-radius: 0; }

/* /admin/settings: the "view as user" switch and the admin tool links. */
.admin-settings-section { display: flex; flex-direction: column; align-items: flex-start; gap: .75rem; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.admin-settings-section h2 { margin: 0; }
.admin-settings-section p { margin: 0; }
.admin-settings-section .admin-mode-toggle { box-shadow: none; }
.admin-settings-tools { display: flex; flex-direction: column; gap: .4rem; margin: 0; padding: 0; list-style: none; }
.admin-settings-tools a { color: var(--ink); font: .95rem Arial, sans-serif; text-decoration: underline; text-underline-offset: .25rem; }

/* Cross-links between public pages and their admin counterparts (templates/_crosslink.html.twig): a real, visible button. */
.crosslink-row { margin: 0 0 1rem }
/* A section that opens the page (cross-link or heading first) clears the header's bottom rule instead of touching it. */
main > .catalog-section:first-child { padding-top: 1.25rem }
.crosslink { display: inline-flex; align-items: center; gap: .45rem; box-sizing: border-box; min-height: 2.2rem; padding: .35rem .95rem; color: var(--ink); font: 600 .82rem/1.2 Arial, sans-serif; letter-spacing: .02em; text-decoration: none; background: var(--paper); border: 1px solid var(--ink); border-radius: .45rem }
.crosslink[data-crosslink="admin"]::before { content: "\2192" }
.crosslink[data-crosslink="site"]::before { content: "\2190" }
.crosslink:hover { color: var(--accent); border-color: var(--accent) }
.crosslink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
/* The "Порядок фильмов" button in the collection edit heading: one line, same size as the other admin buttons. */
.section-heading .admin-collections-button { box-sizing: border-box; min-height: 2.2rem; padding: .35rem .95rem; font-weight: 600; white-space: nowrap; line-height: 1.5; border-radius: .45rem; border-color: var(--ink) }
.section-heading > span:has(> .admin-collections-button) { flex: none; align-self: center }
/* Collection edit heading only: breathing room above the button and above the bottom rule (it used to touch the rule when wrapped). */
.admin-collection-edit > .section-heading { padding: .6rem 0 }
