/*!
 *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
 *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
 */
/* FONT PATH
 * -------------------------- */
@font-face {
  font-family: 'FontAwesome';
  src: url('/assets/fontawesome-webfont-G5YE5S7X.eot?v=4.7.0');
  src: url('/assets/fontawesome-webfont-G5YE5S7X.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('/assets/fontawesome-webfont-B-jkhYfk.woff2?v=4.7.0') format('woff2'), url('/assets/fontawesome-webfont-CDK5bt4p.woff?v=4.7.0') format('woff'), url('/assets/fontawesome-webfont-CQDK8MU3.ttf?v=4.7.0') format('truetype'), url('/assets/fontawesome-webfont-D13rzr4g.svg?v=4.7.0#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}
.fa {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* makes the font 33% larger relative to the icon container */
.fa-lg {
  font-size: 1.33333333em;
  line-height: 0.75em;
  vertical-align: -15%;
}
.fa-2x {
  font-size: 2em;
}
.fa-3x {
  font-size: 3em;
}
.fa-4x {
  font-size: 4em;
}
.fa-5x {
  font-size: 5em;
}
.fa-fw {
  width: 1.28571429em;
  text-align: center;
}
.fa-ul {
  padding-left: 0;
  margin-left: 2.14285714em;
  list-style-type: none;
}
.fa-ul > li {
  position: relative;
}
.fa-li {
  position: absolute;
  left: -2.14285714em;
  width: 2.14285714em;
  top: 0.14285714em;
  text-align: center;
}
.fa-li.fa-lg {
  left: -1.85714286em;
}
.fa-border {
  padding: .2em .25em .15em;
  border: solid 0.08em #eeeeee;
  border-radius: .1em;
}
.fa-pull-left {
  float: left;
}
.fa-pull-right {
  float: right;
}
.fa.fa-pull-left {
  margin-right: .3em;
}
.fa.fa-pull-right {
  margin-left: .3em;
}
/* Deprecated as of 4.4.0 */
.pull-right {
  float: right;
}
.pull-left {
  float: left;
}
.fa.pull-left {
  margin-right: .3em;
}
.fa.pull-right {
  margin-left: .3em;
}
.fa-spin {
  -webkit-animation: fa-spin 2s infinite linear;
  animation: fa-spin 2s infinite linear;
}
.fa-pulse {
  -webkit-animation: fa-spin 1s infinite steps(8);
  animation: fa-spin 1s infinite steps(8);
}
@-webkit-keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}
@keyframes fa-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}
.fa-rotate-90 {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
  -webkit-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
}
.fa-rotate-180 {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
  -webkit-transform: rotate(180deg);
  -ms-transform: rotate(180deg);
  transform: rotate(180deg);
}
.fa-rotate-270 {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
  -webkit-transform: rotate(270deg);
  -ms-transform: rotate(270deg);
  transform: rotate(270deg);
}
.fa-flip-horizontal {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
  -webkit-transform: scale(-1, 1);
  -ms-transform: scale(-1, 1);
  transform: scale(-1, 1);
}
.fa-flip-vertical {
  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
  -webkit-transform: scale(1, -1);
  -ms-transform: scale(1, -1);
  transform: scale(1, -1);
}
:root .fa-rotate-90,
:root .fa-rotate-180,
:root .fa-rotate-270,
:root .fa-flip-horizontal,
:root .fa-flip-vertical {
  filter: none;
}
.fa-stack {
  position: relative;
  display: inline-block;
  width: 2em;
  height: 2em;
  line-height: 2em;
  vertical-align: middle;
}
.fa-stack-1x,
.fa-stack-2x {
  position: absolute;
  left: 0;
  width: 100%;
  text-align: center;
}
.fa-stack-1x {
  line-height: inherit;
}
.fa-stack-2x {
  font-size: 2em;
}
.fa-inverse {
  color: #ffffff;
}
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
   readers do not read off random characters that represent icons */
.fa-glass:before {
  content: "\f000";
}
.fa-music:before {
  content: "\f001";
}
.fa-search:before {
  content: "\f002";
}
.fa-envelope-o:before {
  content: "\f003";
}
.fa-heart:before {
  content: "\f004";
}
.fa-star:before {
  content: "\f005";
}
.fa-star-o:before {
  content: "\f006";
}
.fa-user:before {
  content: "\f007";
}
.fa-film:before {
  content: "\f008";
}
.fa-th-large:before {
  content: "\f009";
}
.fa-th:before {
  content: "\f00a";
}
.fa-th-list:before {
  content: "\f00b";
}
.fa-check:before {
  content: "\f00c";
}
.fa-remove:before,
.fa-close:before,
.fa-times:before {
  content: "\f00d";
}
.fa-search-plus:before {
  content: "\f00e";
}
.fa-search-minus:before {
  content: "\f010";
}
.fa-power-off:before {
  content: "\f011";
}
.fa-signal:before {
  content: "\f012";
}
.fa-gear:before,
.fa-cog:before {
  content: "\f013";
}
.fa-trash-o:before {
  content: "\f014";
}
.fa-home:before {
  content: "\f015";
}
.fa-file-o:before {
  content: "\f016";
}
.fa-clock-o:before {
  content: "\f017";
}
.fa-road:before {
  content: "\f018";
}
.fa-download:before {
  content: "\f019";
}
.fa-arrow-circle-o-down:before {
  content: "\f01a";
}
.fa-arrow-circle-o-up:before {
  content: "\f01b";
}
.fa-inbox:before {
  content: "\f01c";
}
.fa-play-circle-o:before {
  content: "\f01d";
}
.fa-rotate-right:before,
.fa-repeat:before {
  content: "\f01e";
}
.fa-refresh:before {
  content: "\f021";
}
.fa-list-alt:before {
  content: "\f022";
}
.fa-lock:before {
  content: "\f023";
}
.fa-flag:before {
  content: "\f024";
}
.fa-headphones:before {
  content: "\f025";
}
.fa-volume-off:before {
  content: "\f026";
}
.fa-volume-down:before {
  content: "\f027";
}
.fa-volume-up:before {
  content: "\f028";
}
.fa-qrcode:before {
  content: "\f029";
}
.fa-barcode:before {
  content: "\f02a";
}
.fa-tag:before {
  content: "\f02b";
}
.fa-tags:before {
  content: "\f02c";
}
.fa-book:before {
  content: "\f02d";
}
.fa-bookmark:before {
  content: "\f02e";
}
.fa-print:before {
  content: "\f02f";
}
.fa-camera:before {
  content: "\f030";
}
.fa-font:before {
  content: "\f031";
}
.fa-bold:before {
  content: "\f032";
}
.fa-italic:before {
  content: "\f033";
}
.fa-text-height:before {
  content: "\f034";
}
.fa-text-width:before {
  content: "\f035";
}
.fa-align-left:before {
  content: "\f036";
}
.fa-align-center:before {
  content: "\f037";
}
.fa-align-right:before {
  content: "\f038";
}
.fa-align-justify:before {
  content: "\f039";
}
.fa-list:before {
  content: "\f03a";
}
.fa-dedent:before,
.fa-outdent:before {
  content: "\f03b";
}
.fa-indent:before {
  content: "\f03c";
}
.fa-video-camera:before {
  content: "\f03d";
}
.fa-photo:before,
.fa-image:before,
.fa-picture-o:before {
  content: "\f03e";
}
.fa-pencil:before {
  content: "\f040";
}
.fa-map-marker:before {
  content: "\f041";
}
.fa-adjust:before {
  content: "\f042";
}
.fa-tint:before {
  content: "\f043";
}
.fa-edit:before,
.fa-pencil-square-o:before {
  content: "\f044";
}
.fa-share-square-o:before {
  content: "\f045";
}
.fa-check-square-o:before {
  content: "\f046";
}
.fa-arrows:before {
  content: "\f047";
}
.fa-step-backward:before {
  content: "\f048";
}
.fa-fast-backward:before {
  content: "\f049";
}
.fa-backward:before {
  content: "\f04a";
}
.fa-play:before {
  content: "\f04b";
}
.fa-pause:before {
  content: "\f04c";
}
.fa-stop:before {
  content: "\f04d";
}
.fa-forward:before {
  content: "\f04e";
}
.fa-fast-forward:before {
  content: "\f050";
}
.fa-step-forward:before {
  content: "\f051";
}
.fa-eject:before {
  content: "\f052";
}
.fa-chevron-left:before {
  content: "\f053";
}
.fa-chevron-right:before {
  content: "\f054";
}
.fa-plus-circle:before {
  content: "\f055";
}
.fa-minus-circle:before {
  content: "\f056";
}
.fa-times-circle:before {
  content: "\f057";
}
.fa-check-circle:before {
  content: "\f058";
}
.fa-question-circle:before {
  content: "\f059";
}
.fa-info-circle:before {
  content: "\f05a";
}
.fa-crosshairs:before {
  content: "\f05b";
}
.fa-times-circle-o:before {
  content: "\f05c";
}
.fa-check-circle-o:before {
  content: "\f05d";
}
.fa-ban:before {
  content: "\f05e";
}
.fa-arrow-left:before {
  content: "\f060";
}
.fa-arrow-right:before {
  content: "\f061";
}
.fa-arrow-up:before {
  content: "\f062";
}
.fa-arrow-down:before {
  content: "\f063";
}
.fa-mail-forward:before,
.fa-share:before {
  content: "\f064";
}
.fa-expand:before {
  content: "\f065";
}
.fa-compress:before {
  content: "\f066";
}
.fa-plus:before {
  content: "\f067";
}
.fa-minus:before {
  content: "\f068";
}
.fa-asterisk:before {
  content: "\f069";
}
.fa-exclamation-circle:before {
  content: "\f06a";
}
.fa-gift:before {
  content: "\f06b";
}
.fa-leaf:before {
  content: "\f06c";
}
.fa-fire:before {
  content: "\f06d";
}
.fa-eye:before {
  content: "\f06e";
}
.fa-eye-slash:before {
  content: "\f070";
}
.fa-warning:before,
.fa-exclamation-triangle:before {
  content: "\f071";
}
.fa-plane:before {
  content: "\f072";
}
.fa-calendar:before {
  content: "\f073";
}
.fa-random:before {
  content: "\f074";
}
.fa-comment:before {
  content: "\f075";
}
.fa-magnet:before {
  content: "\f076";
}
.fa-chevron-up:before {
  content: "\f077";
}
.fa-chevron-down:before {
  content: "\f078";
}
.fa-retweet:before {
  content: "\f079";
}
.fa-shopping-cart:before {
  content: "\f07a";
}
.fa-folder:before {
  content: "\f07b";
}
.fa-folder-open:before {
  content: "\f07c";
}
.fa-arrows-v:before {
  content: "\f07d";
}
.fa-arrows-h:before {
  content: "\f07e";
}
.fa-bar-chart-o:before,
.fa-bar-chart:before {
  content: "\f080";
}
.fa-twitter-square:before {
  content: "\f081";
}
.fa-facebook-square:before {
  content: "\f082";
}
.fa-camera-retro:before {
  content: "\f083";
}
.fa-key:before {
  content: "\f084";
}
.fa-gears:before,
.fa-cogs:before {
  content: "\f085";
}
.fa-comments:before {
  content: "\f086";
}
.fa-thumbs-o-up:before {
  content: "\f087";
}
.fa-thumbs-o-down:before {
  content: "\f088";
}
.fa-star-half:before {
  content: "\f089";
}
.fa-heart-o:before {
  content: "\f08a";
}
.fa-sign-out:before {
  content: "\f08b";
}
.fa-linkedin-square:before {
  content: "\f08c";
}
.fa-thumb-tack:before {
  content: "\f08d";
}
.fa-external-link:before {
  content: "\f08e";
}
.fa-sign-in:before {
  content: "\f090";
}
.fa-trophy:before {
  content: "\f091";
}
.fa-github-square:before {
  content: "\f092";
}
.fa-upload:before {
  content: "\f093";
}
.fa-lemon-o:before {
  content: "\f094";
}
.fa-phone:before {
  content: "\f095";
}
.fa-square-o:before {
  content: "\f096";
}
.fa-bookmark-o:before {
  content: "\f097";
}
.fa-phone-square:before {
  content: "\f098";
}
.fa-twitter:before {
  content: "\f099";
}
.fa-facebook-f:before,
.fa-facebook:before {
  content: "\f09a";
}
.fa-github:before {
  content: "\f09b";
}
.fa-unlock:before {
  content: "\f09c";
}
.fa-credit-card:before {
  content: "\f09d";
}
.fa-feed:before,
.fa-rss:before {
  content: "\f09e";
}
.fa-hdd-o:before {
  content: "\f0a0";
}
.fa-bullhorn:before {
  content: "\f0a1";
}
.fa-bell:before {
  content: "\f0f3";
}
.fa-certificate:before {
  content: "\f0a3";
}
.fa-hand-o-right:before {
  content: "\f0a4";
}
.fa-hand-o-left:before {
  content: "\f0a5";
}
.fa-hand-o-up:before {
  content: "\f0a6";
}
.fa-hand-o-down:before {
  content: "\f0a7";
}
.fa-arrow-circle-left:before {
  content: "\f0a8";
}
.fa-arrow-circle-right:before {
  content: "\f0a9";
}
.fa-arrow-circle-up:before {
  content: "\f0aa";
}
.fa-arrow-circle-down:before {
  content: "\f0ab";
}
.fa-globe:before {
  content: "\f0ac";
}
.fa-wrench:before {
  content: "\f0ad";
}
.fa-tasks:before {
  content: "\f0ae";
}
.fa-filter:before {
  content: "\f0b0";
}
.fa-briefcase:before {
  content: "\f0b1";
}
.fa-arrows-alt:before {
  content: "\f0b2";
}
.fa-group:before,
.fa-users:before {
  content: "\f0c0";
}
.fa-chain:before,
.fa-link:before {
  content: "\f0c1";
}
.fa-cloud:before {
  content: "\f0c2";
}
.fa-flask:before {
  content: "\f0c3";
}
.fa-cut:before,
.fa-scissors:before {
  content: "\f0c4";
}
.fa-copy:before,
.fa-files-o:before {
  content: "\f0c5";
}
.fa-paperclip:before {
  content: "\f0c6";
}
.fa-save:before,
.fa-floppy-o:before {
  content: "\f0c7";
}
.fa-square:before {
  content: "\f0c8";
}
.fa-navicon:before,
.fa-reorder:before,
.fa-bars:before {
  content: "\f0c9";
}
.fa-list-ul:before {
  content: "\f0ca";
}
.fa-list-ol:before {
  content: "\f0cb";
}
.fa-strikethrough:before {
  content: "\f0cc";
}
.fa-underline:before {
  content: "\f0cd";
}
.fa-table:before {
  content: "\f0ce";
}
.fa-magic:before {
  content: "\f0d0";
}
.fa-truck:before {
  content: "\f0d1";
}
.fa-pinterest:before {
  content: "\f0d2";
}
.fa-pinterest-square:before {
  content: "\f0d3";
}
.fa-google-plus-square:before {
  content: "\f0d4";
}
.fa-google-plus:before {
  content: "\f0d5";
}
.fa-money:before {
  content: "\f0d6";
}
.fa-caret-down:before {
  content: "\f0d7";
}
.fa-caret-up:before {
  content: "\f0d8";
}
.fa-caret-left:before {
  content: "\f0d9";
}
.fa-caret-right:before {
  content: "\f0da";
}
.fa-columns:before {
  content: "\f0db";
}
.fa-unsorted:before,
.fa-sort:before {
  content: "\f0dc";
}
.fa-sort-down:before,
.fa-sort-desc:before {
  content: "\f0dd";
}
.fa-sort-up:before,
.fa-sort-asc:before {
  content: "\f0de";
}
.fa-envelope:before {
  content: "\f0e0";
}
.fa-linkedin:before {
  content: "\f0e1";
}
.fa-rotate-left:before,
.fa-undo:before {
  content: "\f0e2";
}
.fa-legal:before,
.fa-gavel:before {
  content: "\f0e3";
}
.fa-dashboard:before,
.fa-tachometer:before {
  content: "\f0e4";
}
.fa-comment-o:before {
  content: "\f0e5";
}
.fa-comments-o:before {
  content: "\f0e6";
}
.fa-flash:before,
.fa-bolt:before {
  content: "\f0e7";
}
.fa-sitemap:before {
  content: "\f0e8";
}
.fa-umbrella:before {
  content: "\f0e9";
}
.fa-paste:before,
.fa-clipboard:before {
  content: "\f0ea";
}
.fa-lightbulb-o:before {
  content: "\f0eb";
}
.fa-exchange:before {
  content: "\f0ec";
}
.fa-cloud-download:before {
  content: "\f0ed";
}
.fa-cloud-upload:before {
  content: "\f0ee";
}
.fa-user-md:before {
  content: "\f0f0";
}
.fa-stethoscope:before {
  content: "\f0f1";
}
.fa-suitcase:before {
  content: "\f0f2";
}
.fa-bell-o:before {
  content: "\f0a2";
}
.fa-coffee:before {
  content: "\f0f4";
}
.fa-cutlery:before {
  content: "\f0f5";
}
.fa-file-text-o:before {
  content: "\f0f6";
}
.fa-building-o:before {
  content: "\f0f7";
}
.fa-hospital-o:before {
  content: "\f0f8";
}
.fa-ambulance:before {
  content: "\f0f9";
}
.fa-medkit:before {
  content: "\f0fa";
}
.fa-fighter-jet:before {
  content: "\f0fb";
}
.fa-beer:before {
  content: "\f0fc";
}
.fa-h-square:before {
  content: "\f0fd";
}
.fa-plus-square:before {
  content: "\f0fe";
}
.fa-angle-double-left:before {
  content: "\f100";
}
.fa-angle-double-right:before {
  content: "\f101";
}
.fa-angle-double-up:before {
  content: "\f102";
}
.fa-angle-double-down:before {
  content: "\f103";
}
.fa-angle-left:before {
  content: "\f104";
}
.fa-angle-right:before {
  content: "\f105";
}
.fa-angle-up:before {
  content: "\f106";
}
.fa-angle-down:before {
  content: "\f107";
}
.fa-desktop:before {
  content: "\f108";
}
.fa-laptop:before {
  content: "\f109";
}
.fa-tablet:before {
  content: "\f10a";
}
.fa-mobile-phone:before,
.fa-mobile:before {
  content: "\f10b";
}
.fa-circle-o:before {
  content: "\f10c";
}
.fa-quote-left:before {
  content: "\f10d";
}
.fa-quote-right:before {
  content: "\f10e";
}
.fa-spinner:before {
  content: "\f110";
}
.fa-circle:before {
  content: "\f111";
}
.fa-mail-reply:before,
.fa-reply:before {
  content: "\f112";
}
.fa-github-alt:before {
  content: "\f113";
}
.fa-folder-o:before {
  content: "\f114";
}
.fa-folder-open-o:before {
  content: "\f115";
}
.fa-smile-o:before {
  content: "\f118";
}
.fa-frown-o:before {
  content: "\f119";
}
.fa-meh-o:before {
  content: "\f11a";
}
.fa-gamepad:before {
  content: "\f11b";
}
.fa-keyboard-o:before {
  content: "\f11c";
}
.fa-flag-o:before {
  content: "\f11d";
}
.fa-flag-checkered:before {
  content: "\f11e";
}
.fa-terminal:before {
  content: "\f120";
}
.fa-code:before {
  content: "\f121";
}
.fa-mail-reply-all:before,
.fa-reply-all:before {
  content: "\f122";
}
.fa-star-half-empty:before,
.fa-star-half-full:before,
.fa-star-half-o:before {
  content: "\f123";
}
.fa-location-arrow:before {
  content: "\f124";
}
.fa-crop:before {
  content: "\f125";
}
.fa-code-fork:before {
  content: "\f126";
}
.fa-unlink:before,
.fa-chain-broken:before {
  content: "\f127";
}
.fa-question:before {
  content: "\f128";
}
.fa-info:before {
  content: "\f129";
}
.fa-exclamation:before {
  content: "\f12a";
}
.fa-superscript:before {
  content: "\f12b";
}
.fa-subscript:before {
  content: "\f12c";
}
.fa-eraser:before {
  content: "\f12d";
}
.fa-puzzle-piece:before {
  content: "\f12e";
}
.fa-microphone:before {
  content: "\f130";
}
.fa-microphone-slash:before {
  content: "\f131";
}
.fa-shield:before {
  content: "\f132";
}
.fa-calendar-o:before {
  content: "\f133";
}
.fa-fire-extinguisher:before {
  content: "\f134";
}
.fa-rocket:before {
  content: "\f135";
}
.fa-maxcdn:before {
  content: "\f136";
}
.fa-chevron-circle-left:before {
  content: "\f137";
}
.fa-chevron-circle-right:before {
  content: "\f138";
}
.fa-chevron-circle-up:before {
  content: "\f139";
}
.fa-chevron-circle-down:before {
  content: "\f13a";
}
.fa-html5:before {
  content: "\f13b";
}
.fa-css3:before {
  content: "\f13c";
}
.fa-anchor:before {
  content: "\f13d";
}
.fa-unlock-alt:before {
  content: "\f13e";
}
.fa-bullseye:before {
  content: "\f140";
}
.fa-ellipsis-h:before {
  content: "\f141";
}
.fa-ellipsis-v:before {
  content: "\f142";
}
.fa-rss-square:before {
  content: "\f143";
}
.fa-play-circle:before {
  content: "\f144";
}
.fa-ticket:before {
  content: "\f145";
}
.fa-minus-square:before {
  content: "\f146";
}
.fa-minus-square-o:before {
  content: "\f147";
}
.fa-level-up:before {
  content: "\f148";
}
.fa-level-down:before {
  content: "\f149";
}
.fa-check-square:before {
  content: "\f14a";
}
.fa-pencil-square:before {
  content: "\f14b";
}
.fa-external-link-square:before {
  content: "\f14c";
}
.fa-share-square:before {
  content: "\f14d";
}
.fa-compass:before {
  content: "\f14e";
}
.fa-toggle-down:before,
.fa-caret-square-o-down:before {
  content: "\f150";
}
.fa-toggle-up:before,
.fa-caret-square-o-up:before {
  content: "\f151";
}
.fa-toggle-right:before,
.fa-caret-square-o-right:before {
  content: "\f152";
}
.fa-euro:before,
.fa-eur:before {
  content: "\f153";
}
.fa-gbp:before {
  content: "\f154";
}
.fa-dollar:before,
.fa-usd:before {
  content: "\f155";
}
.fa-rupee:before,
.fa-inr:before {
  content: "\f156";
}
.fa-cny:before,
.fa-rmb:before,
.fa-yen:before,
.fa-jpy:before {
  content: "\f157";
}
.fa-ruble:before,
.fa-rouble:before,
.fa-rub:before {
  content: "\f158";
}
.fa-won:before,
.fa-krw:before {
  content: "\f159";
}
.fa-bitcoin:before,
.fa-btc:before {
  content: "\f15a";
}
.fa-file:before {
  content: "\f15b";
}
.fa-file-text:before {
  content: "\f15c";
}
.fa-sort-alpha-asc:before {
  content: "\f15d";
}
.fa-sort-alpha-desc:before {
  content: "\f15e";
}
.fa-sort-amount-asc:before {
  content: "\f160";
}
.fa-sort-amount-desc:before {
  content: "\f161";
}
.fa-sort-numeric-asc:before {
  content: "\f162";
}
.fa-sort-numeric-desc:before {
  content: "\f163";
}
.fa-thumbs-up:before {
  content: "\f164";
}
.fa-thumbs-down:before {
  content: "\f165";
}
.fa-youtube-square:before {
  content: "\f166";
}
.fa-youtube:before {
  content: "\f167";
}
.fa-xing:before {
  content: "\f168";
}
.fa-xing-square:before {
  content: "\f169";
}
.fa-youtube-play:before {
  content: "\f16a";
}
.fa-dropbox:before {
  content: "\f16b";
}
.fa-stack-overflow:before {
  content: "\f16c";
}
.fa-instagram:before {
  content: "\f16d";
}
.fa-flickr:before {
  content: "\f16e";
}
.fa-adn:before {
  content: "\f170";
}
.fa-bitbucket:before {
  content: "\f171";
}
.fa-bitbucket-square:before {
  content: "\f172";
}
.fa-tumblr:before {
  content: "\f173";
}
.fa-tumblr-square:before {
  content: "\f174";
}
.fa-long-arrow-down:before {
  content: "\f175";
}
.fa-long-arrow-up:before {
  content: "\f176";
}
.fa-long-arrow-left:before {
  content: "\f177";
}
.fa-long-arrow-right:before {
  content: "\f178";
}
.fa-apple:before {
  content: "\f179";
}
.fa-windows:before {
  content: "\f17a";
}
.fa-android:before {
  content: "\f17b";
}
.fa-linux:before {
  content: "\f17c";
}
.fa-dribbble:before {
  content: "\f17d";
}
.fa-skype:before {
  content: "\f17e";
}
.fa-foursquare:before {
  content: "\f180";
}
.fa-trello:before {
  content: "\f181";
}
.fa-female:before {
  content: "\f182";
}
.fa-male:before {
  content: "\f183";
}
.fa-gittip:before,
.fa-gratipay:before {
  content: "\f184";
}
.fa-sun-o:before {
  content: "\f185";
}
.fa-moon-o:before {
  content: "\f186";
}
.fa-archive:before {
  content: "\f187";
}
.fa-bug:before {
  content: "\f188";
}
.fa-vk:before {
  content: "\f189";
}
.fa-weibo:before {
  content: "\f18a";
}
.fa-renren:before {
  content: "\f18b";
}
.fa-pagelines:before {
  content: "\f18c";
}
.fa-stack-exchange:before {
  content: "\f18d";
}
.fa-arrow-circle-o-right:before {
  content: "\f18e";
}
.fa-arrow-circle-o-left:before {
  content: "\f190";
}
.fa-toggle-left:before,
.fa-caret-square-o-left:before {
  content: "\f191";
}
.fa-dot-circle-o:before {
  content: "\f192";
}
.fa-wheelchair:before {
  content: "\f193";
}
.fa-vimeo-square:before {
  content: "\f194";
}
.fa-turkish-lira:before,
.fa-try:before {
  content: "\f195";
}
.fa-plus-square-o:before {
  content: "\f196";
}
.fa-space-shuttle:before {
  content: "\f197";
}
.fa-slack:before {
  content: "\f198";
}
.fa-envelope-square:before {
  content: "\f199";
}
.fa-wordpress:before {
  content: "\f19a";
}
.fa-openid:before {
  content: "\f19b";
}
.fa-institution:before,
.fa-bank:before,
.fa-university:before {
  content: "\f19c";
}
.fa-mortar-board:before,
.fa-graduation-cap:before {
  content: "\f19d";
}
.fa-yahoo:before {
  content: "\f19e";
}
.fa-google:before {
  content: "\f1a0";
}
.fa-reddit:before {
  content: "\f1a1";
}
.fa-reddit-square:before {
  content: "\f1a2";
}
.fa-stumbleupon-circle:before {
  content: "\f1a3";
}
.fa-stumbleupon:before {
  content: "\f1a4";
}
.fa-delicious:before {
  content: "\f1a5";
}
.fa-digg:before {
  content: "\f1a6";
}
.fa-pied-piper-pp:before {
  content: "\f1a7";
}
.fa-pied-piper-alt:before {
  content: "\f1a8";
}
.fa-drupal:before {
  content: "\f1a9";
}
.fa-joomla:before {
  content: "\f1aa";
}
.fa-language:before {
  content: "\f1ab";
}
.fa-fax:before {
  content: "\f1ac";
}
.fa-building:before {
  content: "\f1ad";
}
.fa-child:before {
  content: "\f1ae";
}
.fa-paw:before {
  content: "\f1b0";
}
.fa-spoon:before {
  content: "\f1b1";
}
.fa-cube:before {
  content: "\f1b2";
}
.fa-cubes:before {
  content: "\f1b3";
}
.fa-behance:before {
  content: "\f1b4";
}
.fa-behance-square:before {
  content: "\f1b5";
}
.fa-steam:before {
  content: "\f1b6";
}
.fa-steam-square:before {
  content: "\f1b7";
}
.fa-recycle:before {
  content: "\f1b8";
}
.fa-automobile:before,
.fa-car:before {
  content: "\f1b9";
}
.fa-cab:before,
.fa-taxi:before {
  content: "\f1ba";
}
.fa-tree:before {
  content: "\f1bb";
}
.fa-spotify:before {
  content: "\f1bc";
}
.fa-deviantart:before {
  content: "\f1bd";
}
.fa-soundcloud:before {
  content: "\f1be";
}
.fa-database:before {
  content: "\f1c0";
}
.fa-file-pdf-o:before {
  content: "\f1c1";
}
.fa-file-word-o:before {
  content: "\f1c2";
}
.fa-file-excel-o:before {
  content: "\f1c3";
}
.fa-file-powerpoint-o:before {
  content: "\f1c4";
}
.fa-file-photo-o:before,
.fa-file-picture-o:before,
.fa-file-image-o:before {
  content: "\f1c5";
}
.fa-file-zip-o:before,
.fa-file-archive-o:before {
  content: "\f1c6";
}
.fa-file-sound-o:before,
.fa-file-audio-o:before {
  content: "\f1c7";
}
.fa-file-movie-o:before,
.fa-file-video-o:before {
  content: "\f1c8";
}
.fa-file-code-o:before {
  content: "\f1c9";
}
.fa-vine:before {
  content: "\f1ca";
}
.fa-codepen:before {
  content: "\f1cb";
}
.fa-jsfiddle:before {
  content: "\f1cc";
}
.fa-life-bouy:before,
.fa-life-buoy:before,
.fa-life-saver:before,
.fa-support:before,
.fa-life-ring:before {
  content: "\f1cd";
}
.fa-circle-o-notch:before {
  content: "\f1ce";
}
.fa-ra:before,
.fa-resistance:before,
.fa-rebel:before {
  content: "\f1d0";
}
.fa-ge:before,
.fa-empire:before {
  content: "\f1d1";
}
.fa-git-square:before {
  content: "\f1d2";
}
.fa-git:before {
  content: "\f1d3";
}
.fa-y-combinator-square:before,
.fa-yc-square:before,
.fa-hacker-news:before {
  content: "\f1d4";
}
.fa-tencent-weibo:before {
  content: "\f1d5";
}
.fa-qq:before {
  content: "\f1d6";
}
.fa-wechat:before,
.fa-weixin:before {
  content: "\f1d7";
}
.fa-send:before,
.fa-paper-plane:before {
  content: "\f1d8";
}
.fa-send-o:before,
.fa-paper-plane-o:before {
  content: "\f1d9";
}
.fa-history:before {
  content: "\f1da";
}
.fa-circle-thin:before {
  content: "\f1db";
}
.fa-header:before {
  content: "\f1dc";
}
.fa-paragraph:before {
  content: "\f1dd";
}
.fa-sliders:before {
  content: "\f1de";
}
.fa-share-alt:before {
  content: "\f1e0";
}
.fa-share-alt-square:before {
  content: "\f1e1";
}
.fa-bomb:before {
  content: "\f1e2";
}
.fa-soccer-ball-o:before,
.fa-futbol-o:before {
  content: "\f1e3";
}
.fa-tty:before {
  content: "\f1e4";
}
.fa-binoculars:before {
  content: "\f1e5";
}
.fa-plug:before {
  content: "\f1e6";
}
.fa-slideshare:before {
  content: "\f1e7";
}
.fa-twitch:before {
  content: "\f1e8";
}
.fa-yelp:before {
  content: "\f1e9";
}
.fa-newspaper-o:before {
  content: "\f1ea";
}
.fa-wifi:before {
  content: "\f1eb";
}
.fa-calculator:before {
  content: "\f1ec";
}
.fa-paypal:before {
  content: "\f1ed";
}
.fa-google-wallet:before {
  content: "\f1ee";
}
.fa-cc-visa:before {
  content: "\f1f0";
}
.fa-cc-mastercard:before {
  content: "\f1f1";
}
.fa-cc-discover:before {
  content: "\f1f2";
}
.fa-cc-amex:before {
  content: "\f1f3";
}
.fa-cc-paypal:before {
  content: "\f1f4";
}
.fa-cc-stripe:before {
  content: "\f1f5";
}
.fa-bell-slash:before {
  content: "\f1f6";
}
.fa-bell-slash-o:before {
  content: "\f1f7";
}
.fa-trash:before {
  content: "\f1f8";
}
.fa-copyright:before {
  content: "\f1f9";
}
.fa-at:before {
  content: "\f1fa";
}
.fa-eyedropper:before {
  content: "\f1fb";
}
.fa-paint-brush:before {
  content: "\f1fc";
}
.fa-birthday-cake:before {
  content: "\f1fd";
}
.fa-area-chart:before {
  content: "\f1fe";
}
.fa-pie-chart:before {
  content: "\f200";
}
.fa-line-chart:before {
  content: "\f201";
}
.fa-lastfm:before {
  content: "\f202";
}
.fa-lastfm-square:before {
  content: "\f203";
}
.fa-toggle-off:before {
  content: "\f204";
}
.fa-toggle-on:before {
  content: "\f205";
}
.fa-bicycle:before {
  content: "\f206";
}
.fa-bus:before {
  content: "\f207";
}
.fa-ioxhost:before {
  content: "\f208";
}
.fa-angellist:before {
  content: "\f209";
}
.fa-cc:before {
  content: "\f20a";
}
.fa-shekel:before,
.fa-sheqel:before,
.fa-ils:before {
  content: "\f20b";
}
.fa-meanpath:before {
  content: "\f20c";
}
.fa-buysellads:before {
  content: "\f20d";
}
.fa-connectdevelop:before {
  content: "\f20e";
}
.fa-dashcube:before {
  content: "\f210";
}
.fa-forumbee:before {
  content: "\f211";
}
.fa-leanpub:before {
  content: "\f212";
}
.fa-sellsy:before {
  content: "\f213";
}
.fa-shirtsinbulk:before {
  content: "\f214";
}
.fa-simplybuilt:before {
  content: "\f215";
}
.fa-skyatlas:before {
  content: "\f216";
}
.fa-cart-plus:before {
  content: "\f217";
}
.fa-cart-arrow-down:before {
  content: "\f218";
}
.fa-diamond:before {
  content: "\f219";
}
.fa-ship:before {
  content: "\f21a";
}
.fa-user-secret:before {
  content: "\f21b";
}
.fa-motorcycle:before {
  content: "\f21c";
}
.fa-street-view:before {
  content: "\f21d";
}
.fa-heartbeat:before {
  content: "\f21e";
}
.fa-venus:before {
  content: "\f221";
}
.fa-mars:before {
  content: "\f222";
}
.fa-mercury:before {
  content: "\f223";
}
.fa-intersex:before,
.fa-transgender:before {
  content: "\f224";
}
.fa-transgender-alt:before {
  content: "\f225";
}
.fa-venus-double:before {
  content: "\f226";
}
.fa-mars-double:before {
  content: "\f227";
}
.fa-venus-mars:before {
  content: "\f228";
}
.fa-mars-stroke:before {
  content: "\f229";
}
.fa-mars-stroke-v:before {
  content: "\f22a";
}
.fa-mars-stroke-h:before {
  content: "\f22b";
}
.fa-neuter:before {
  content: "\f22c";
}
.fa-genderless:before {
  content: "\f22d";
}
.fa-facebook-official:before {
  content: "\f230";
}
.fa-pinterest-p:before {
  content: "\f231";
}
.fa-whatsapp:before {
  content: "\f232";
}
.fa-server:before {
  content: "\f233";
}
.fa-user-plus:before {
  content: "\f234";
}
.fa-user-times:before {
  content: "\f235";
}
.fa-hotel:before,
.fa-bed:before {
  content: "\f236";
}
.fa-viacoin:before {
  content: "\f237";
}
.fa-train:before {
  content: "\f238";
}
.fa-subway:before {
  content: "\f239";
}
.fa-medium:before {
  content: "\f23a";
}
.fa-yc:before,
.fa-y-combinator:before {
  content: "\f23b";
}
.fa-optin-monster:before {
  content: "\f23c";
}
.fa-opencart:before {
  content: "\f23d";
}
.fa-expeditedssl:before {
  content: "\f23e";
}
.fa-battery-4:before,
.fa-battery:before,
.fa-battery-full:before {
  content: "\f240";
}
.fa-battery-3:before,
.fa-battery-three-quarters:before {
  content: "\f241";
}
.fa-battery-2:before,
.fa-battery-half:before {
  content: "\f242";
}
.fa-battery-1:before,
.fa-battery-quarter:before {
  content: "\f243";
}
.fa-battery-0:before,
.fa-battery-empty:before {
  content: "\f244";
}
.fa-mouse-pointer:before {
  content: "\f245";
}
.fa-i-cursor:before {
  content: "\f246";
}
.fa-object-group:before {
  content: "\f247";
}
.fa-object-ungroup:before {
  content: "\f248";
}
.fa-sticky-note:before {
  content: "\f249";
}
.fa-sticky-note-o:before {
  content: "\f24a";
}
.fa-cc-jcb:before {
  content: "\f24b";
}
.fa-cc-diners-club:before {
  content: "\f24c";
}
.fa-clone:before {
  content: "\f24d";
}
.fa-balance-scale:before {
  content: "\f24e";
}
.fa-hourglass-o:before {
  content: "\f250";
}
.fa-hourglass-1:before,
.fa-hourglass-start:before {
  content: "\f251";
}
.fa-hourglass-2:before,
.fa-hourglass-half:before {
  content: "\f252";
}
.fa-hourglass-3:before,
.fa-hourglass-end:before {
  content: "\f253";
}
.fa-hourglass:before {
  content: "\f254";
}
.fa-hand-grab-o:before,
.fa-hand-rock-o:before {
  content: "\f255";
}
.fa-hand-stop-o:before,
.fa-hand-paper-o:before {
  content: "\f256";
}
.fa-hand-scissors-o:before {
  content: "\f257";
}
.fa-hand-lizard-o:before {
  content: "\f258";
}
.fa-hand-spock-o:before {
  content: "\f259";
}
.fa-hand-pointer-o:before {
  content: "\f25a";
}
.fa-hand-peace-o:before {
  content: "\f25b";
}
.fa-trademark:before {
  content: "\f25c";
}
.fa-registered:before {
  content: "\f25d";
}
.fa-creative-commons:before {
  content: "\f25e";
}
.fa-gg:before {
  content: "\f260";
}
.fa-gg-circle:before {
  content: "\f261";
}
.fa-tripadvisor:before {
  content: "\f262";
}
.fa-odnoklassniki:before {
  content: "\f263";
}
.fa-odnoklassniki-square:before {
  content: "\f264";
}
.fa-get-pocket:before {
  content: "\f265";
}
.fa-wikipedia-w:before {
  content: "\f266";
}
.fa-safari:before {
  content: "\f267";
}
.fa-chrome:before {
  content: "\f268";
}
.fa-firefox:before {
  content: "\f269";
}
.fa-opera:before {
  content: "\f26a";
}
.fa-internet-explorer:before {
  content: "\f26b";
}
.fa-tv:before,
.fa-television:before {
  content: "\f26c";
}
.fa-contao:before {
  content: "\f26d";
}
.fa-500px:before {
  content: "\f26e";
}
.fa-amazon:before {
  content: "\f270";
}
.fa-calendar-plus-o:before {
  content: "\f271";
}
.fa-calendar-minus-o:before {
  content: "\f272";
}
.fa-calendar-times-o:before {
  content: "\f273";
}
.fa-calendar-check-o:before {
  content: "\f274";
}
.fa-industry:before {
  content: "\f275";
}
.fa-map-pin:before {
  content: "\f276";
}
.fa-map-signs:before {
  content: "\f277";
}
.fa-map-o:before {
  content: "\f278";
}
.fa-map:before {
  content: "\f279";
}
.fa-commenting:before {
  content: "\f27a";
}
.fa-commenting-o:before {
  content: "\f27b";
}
.fa-houzz:before {
  content: "\f27c";
}
.fa-vimeo:before {
  content: "\f27d";
}
.fa-black-tie:before {
  content: "\f27e";
}
.fa-fonticons:before {
  content: "\f280";
}
.fa-reddit-alien:before {
  content: "\f281";
}
.fa-edge:before {
  content: "\f282";
}
.fa-credit-card-alt:before {
  content: "\f283";
}
.fa-codiepie:before {
  content: "\f284";
}
.fa-modx:before {
  content: "\f285";
}
.fa-fort-awesome:before {
  content: "\f286";
}
.fa-usb:before {
  content: "\f287";
}
.fa-product-hunt:before {
  content: "\f288";
}
.fa-mixcloud:before {
  content: "\f289";
}
.fa-scribd:before {
  content: "\f28a";
}
.fa-pause-circle:before {
  content: "\f28b";
}
.fa-pause-circle-o:before {
  content: "\f28c";
}
.fa-stop-circle:before {
  content: "\f28d";
}
.fa-stop-circle-o:before {
  content: "\f28e";
}
.fa-shopping-bag:before {
  content: "\f290";
}
.fa-shopping-basket:before {
  content: "\f291";
}
.fa-hashtag:before {
  content: "\f292";
}
.fa-bluetooth:before {
  content: "\f293";
}
.fa-bluetooth-b:before {
  content: "\f294";
}
.fa-percent:before {
  content: "\f295";
}
.fa-gitlab:before {
  content: "\f296";
}
.fa-wpbeginner:before {
  content: "\f297";
}
.fa-wpforms:before {
  content: "\f298";
}
.fa-envira:before {
  content: "\f299";
}
.fa-universal-access:before {
  content: "\f29a";
}
.fa-wheelchair-alt:before {
  content: "\f29b";
}
.fa-question-circle-o:before {
  content: "\f29c";
}
.fa-blind:before {
  content: "\f29d";
}
.fa-audio-description:before {
  content: "\f29e";
}
.fa-volume-control-phone:before {
  content: "\f2a0";
}
.fa-braille:before {
  content: "\f2a1";
}
.fa-assistive-listening-systems:before {
  content: "\f2a2";
}
.fa-asl-interpreting:before,
.fa-american-sign-language-interpreting:before {
  content: "\f2a3";
}
.fa-deafness:before,
.fa-hard-of-hearing:before,
.fa-deaf:before {
  content: "\f2a4";
}
.fa-glide:before {
  content: "\f2a5";
}
.fa-glide-g:before {
  content: "\f2a6";
}
.fa-signing:before,
.fa-sign-language:before {
  content: "\f2a7";
}
.fa-low-vision:before {
  content: "\f2a8";
}
.fa-viadeo:before {
  content: "\f2a9";
}
.fa-viadeo-square:before {
  content: "\f2aa";
}
.fa-snapchat:before {
  content: "\f2ab";
}
.fa-snapchat-ghost:before {
  content: "\f2ac";
}
.fa-snapchat-square:before {
  content: "\f2ad";
}
.fa-pied-piper:before {
  content: "\f2ae";
}
.fa-first-order:before {
  content: "\f2b0";
}
.fa-yoast:before {
  content: "\f2b1";
}
.fa-themeisle:before {
  content: "\f2b2";
}
.fa-google-plus-circle:before,
.fa-google-plus-official:before {
  content: "\f2b3";
}
.fa-fa:before,
.fa-font-awesome:before {
  content: "\f2b4";
}
.fa-handshake-o:before {
  content: "\f2b5";
}
.fa-envelope-open:before {
  content: "\f2b6";
}
.fa-envelope-open-o:before {
  content: "\f2b7";
}
.fa-linode:before {
  content: "\f2b8";
}
.fa-address-book:before {
  content: "\f2b9";
}
.fa-address-book-o:before {
  content: "\f2ba";
}
.fa-vcard:before,
.fa-address-card:before {
  content: "\f2bb";
}
.fa-vcard-o:before,
.fa-address-card-o:before {
  content: "\f2bc";
}
.fa-user-circle:before {
  content: "\f2bd";
}
.fa-user-circle-o:before {
  content: "\f2be";
}
.fa-user-o:before {
  content: "\f2c0";
}
.fa-id-badge:before {
  content: "\f2c1";
}
.fa-drivers-license:before,
.fa-id-card:before {
  content: "\f2c2";
}
.fa-drivers-license-o:before,
.fa-id-card-o:before {
  content: "\f2c3";
}
.fa-quora:before {
  content: "\f2c4";
}
.fa-free-code-camp:before {
  content: "\f2c5";
}
.fa-telegram:before {
  content: "\f2c6";
}
.fa-thermometer-4:before,
.fa-thermometer:before,
.fa-thermometer-full:before {
  content: "\f2c7";
}
.fa-thermometer-3:before,
.fa-thermometer-three-quarters:before {
  content: "\f2c8";
}
.fa-thermometer-2:before,
.fa-thermometer-half:before {
  content: "\f2c9";
}
.fa-thermometer-1:before,
.fa-thermometer-quarter:before {
  content: "\f2ca";
}
.fa-thermometer-0:before,
.fa-thermometer-empty:before {
  content: "\f2cb";
}
.fa-shower:before {
  content: "\f2cc";
}
.fa-bathtub:before,
.fa-s15:before,
.fa-bath:before {
  content: "\f2cd";
}
.fa-podcast:before {
  content: "\f2ce";
}
.fa-window-maximize:before {
  content: "\f2d0";
}
.fa-window-minimize:before {
  content: "\f2d1";
}
.fa-window-restore:before {
  content: "\f2d2";
}
.fa-times-rectangle:before,
.fa-window-close:before {
  content: "\f2d3";
}
.fa-times-rectangle-o:before,
.fa-window-close-o:before {
  content: "\f2d4";
}
.fa-bandcamp:before {
  content: "\f2d5";
}
.fa-grav:before {
  content: "\f2d6";
}
.fa-etsy:before {
  content: "\f2d7";
}
.fa-imdb:before {
  content: "\f2d8";
}
.fa-ravelry:before {
  content: "\f2d9";
}
.fa-eercast:before {
  content: "\f2da";
}
.fa-microchip:before {
  content: "\f2db";
}
.fa-snowflake-o:before {
  content: "\f2dc";
}
.fa-superpowers:before {
  content: "\f2dd";
}
.fa-wpexplorer:before {
  content: "\f2de";
}
.fa-meetup:before {
  content: "\f2e0";
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
  position: static;
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  clip: auto;
}
/* New-app-only additions on top of the vendored legacy stylesheet.
   Keep minimal — everything visual should come from the legacy CSS. */

@keyframes fs-skeleton {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

.fs-skeleton {
  animation: fs-skeleton 1.4s ease-in-out infinite;
  background-color: var(--color-surface-muted);
}

/* "N new transfers" pill (no legacy equivalent — new realtime UX) */
.transfers-new-pill-container {
  position: sticky;
  top: 8px;
  z-index: 10;
  display: flex;
  justify-content: center;
  height: 0;
}

.transfers-new-pill {
  margin-top: 8px;
  border: none;
  border-radius: 999px;
  background: var(--color-accent);
  color: var(--color-surface);
  font-size: 0.75rem;
  padding: 6px 16px;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
.transfers-filter-container {
  position: relative;
}

/* Keep-alive shell: the header used to sit inside the scrolling .content and
   inherited `.content .container-fluid { padding: 0 2rem }` (styles.scss).
   It now lives beside the panes — keep its container padding identical. */

/* HARD 320px minimum (round 17): below a 320px viewport the page stops
   reflowing — the browser scrolls an intact 320 layout. Nothing ever
   renders narrower than 320. */
body {
  min-width: 320px;
}

/* Filter-bar controls: clean markup, PRODUCTION styling. Every value below
   is EXTRACTED from the live production DOM via getComputedStyle
   (parity/controls/prod-computed-styles.json + controls-reference.md) —
   do not restyle from memory. */
:is(.fs-filterbar, .fs-scope) .fs-control {
  display: inline-block;
  /* KIT variant: the production 34px bar line, restored (verdict);
     horizontal inset = THE token */
  height: var(--fs-bar-control-height);
  /* THE BAR HAS ONE TEXT LINE, AND IT IS THE CONTROL'S OWN (D-184).
     Declared here, once, for every control the bar renders — no bar and
     no control carries vertical metrics of its own.

     WHAT IT REPLACED, measured in pixels (the closed pulldown's text is
     drawn by the UA and cannot be read from the DOM; the numbers are ink
     rows from a screenshot at 1:1, one word in every control):

       pulldown, closed          12..22
       checkbox label            12..22
       a chip in a chip field    12..22
       chip field, placeholder   11..21   <- a pixel high

     A 17.5px line centred in the box is what put the placeholder there:
     34 - 17.5 leaves 16.5, so the line began at a half pixel and the
     text rounded up off the bar's line. The line IS the box now, so
     every control's half-leading is the same whole number.

     The 2px/0 padding the pulldown carried was the other half of the
     same habit, and it MOVED NOTHING — measured, by putting it back:
     the pulldown's ink stayed at 12..22 with the padding and the 17.5px
     line restored, so the UA does not let either property move the
     selected text. Which is the finding that matters: the pulldown could
     not have been walked up to the chips, because nothing in CSS was
     holding it down. It was the placeholder that had to come to it. */
  padding: 0 var(--fs-control-inset);
  /* bar controls keep PRODUCTION's 14 (extraction 2026-07-27) — own
     token so the 16px input bump can't drag the bar along */
  font-size: var(--fs-select-font-size);
  font-weight: var(--fs-control-font-weight);
  line-height: var(--fs-bar-control-height);
  color: var(--color-text);
  background-color: var(--color-surface-muted);
  border: none;
  border-radius: 0;
  vertical-align: middle;
  outline: none;
}
:is(.fs-filterbar, .fs-scope) .fs-select {
  appearance: none;
  padding-right: var(--fs-bar-select-clearance);
  /* production chevron: bootstrap4 double-triangle SVG, 8x10px */
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: calc(100% - var(--fs-bar-arrow-offset)) 50%;
  background-size: 8px 10px;
}
/* production widths (legacy Site.scss); inline bar from the master
   768 breakpoint up (round 18 re-homing: the stacked bar exists ONLY
   below 768, together with burger + mobile margin) */
@media (min-width: 927px) {
  /* TWO KINDS OF CONTROL, TWO SIZING RULES (D-121, owner's ruling and
     its correction).

     THE CAPPED KIND — the chip fields and the Distributors pulldown —
     wears the shared resting width and cuts a long value with an
     ellipsis. Distributors is capped because its options are long and
     varied ("Solveig Sautier, Festival International du Film Alpin des
     Diablerets" measures 445px, and the list changes with the data and
     the region), which is exactly what made it re-lay out.

     EVERY OTHER PULLDOWN IS SIZED BY ITS CONTENT: as wide as its own
     widest option needs and no wider, so a short list stays narrow and
     no space is wasted. That is the native select's own sizing, so
     there is NO width rule for them here — and a control that has no
     width rule cannot drift from one. It also cannot change width when
     the selection changes, because the widest option, not the current
     one, is what sizes it.

     What this replaced: five hand-set numbers (Distributor 220 in
     kit-port, Status 128, Mode and Dates 120, and a dead second copy of
     120 at a 543px breakpoint) plus five intrinsic controls. The
     numbers are gone; the intrinsic ones are the rule now. The D-038
     "Distributor is intrinsic by design" verdict is superseded — it is
     the one pulldown that must NOT be. */
  .fs-filterbar-form select.fs-select--capped {
    width: var(--fs-chipfield-width);
    /* the right padding is the caret's clearance, so the ellipsis lands
       before the chevron rather than under it */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
/* checkbox: 34px #F5F5F5 box + FontAwesome check — BLUE when checked,
   ghost var(--color-line-strong) when unchecked (production always renders the glyph)

   G2.1: every rule below also names .fs-toggle.fs-checkrow — THE checkbox
   row (components/Checkbox.tsx) carries its own paint instead of
   depending on an ancestor. It names BOTH classes on purpose: the row
   class alone also matches the admin family's row (FormCheckbox), whose
   input is a hidden one sitting behind that family's own painted box. The bar/.fs-scope selectors stay for the inline toggles
   that are not rows. Same declarations, one block each: a row rendered
   anywhere (a portal, a form, a table) can no longer fall through to the
   browser's native box, which is exactly how the popup broke in round G. */
:is(.fs-filterbar, .fs-scope) .fs-toggle,
.fs-toggle.fs-checkrow {
  display: inline-flex;
  align-items: center;
  margin: 0;
  color: var(--color-text);
  font-size: 14px;
  font-weight: 300;
  cursor: pointer;
  user-select: none;
}
:is(.fs-filterbar, .fs-scope) .fs-toggle input,
.fs-toggle.fs-checkrow input {
  appearance: none;
  /* O6: ONE size, app-wide (control-kit --fs-checkbox-size). This was a
     hand-set 34 and the compact variant below was 29; they are the same
     number now, so no surface can drift from another.
     D-121: the FILTER ROW takes its height from the bar's own token
     instead — see the override below. This rule is shared with the
     off-bar checkrow, so it is not the place to do it. */
  width: var(--fs-checkbox-size);
  height: var(--fs-checkbox-size);
  margin: 0;
  padding: 0.4rem 0.7rem;
  background-color: var(--color-surface-soft);
  cursor: pointer;
  position: relative;
  display: inline-block;
}
/* ONE HEIGHT FOR EVERY CONTROL IN THE FILTER ROW (D-121, owner's
   ruling): chip fields, pulldowns, checkboxes and Reset all read
   --fs-bar-control-height. The checkbox is square, so the token sets
   both of its sides; off the bar the app-wide --fs-checkbox-size still
   rules, which is why this is scoped to the bar form. */
.fs-filterbar-form .fs-toggle input {
  width: var(--fs-bar-control-height);
  height: var(--fs-bar-control-height);
}
/* AND ONE LINE (D-184). The label's seat below reads --fs-checkbox-size,
   which is the same 34 off the bar and must stay the checkrow's; ON the
   bar the line is the bar's, from the bar's token, like every other
   control's. Same number today — the point is that it stays the same
   number when one of them moves. */
.fs-filterbar-form .fs-toggle span:not(.mk):not(.mk-paint) {
  line-height: var(--fs-bar-control-height);
}
:is(.fs-filterbar, .fs-scope) .fs-toggle input::after,
.fs-toggle.fs-checkrow input::after {
  /* the exact FA 4.7 fa-check outline (see faGlyphs.ts) — the old
     content:'\f00c' rendered tofu after the legacy font purge */
  content: '';
  position: absolute;
  inset: 0;
  background: center / 16px 16px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1792 1792'%3E%3Cpath transform='translate(0,1536) scale(1,-1)' fill='%231183CF' d='M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z'/%3E%3C/svg%3E");
  opacity: 0;
}
:is(.fs-filterbar, .fs-scope) .fs-toggle input:checked::after,
.fs-toggle.fs-checkrow input:checked::after {
  opacity: 1;
}

/* THE LAST SELECTED KIND, LOCKED (D-061).
 *
 * Trailer and Features partition the catalogue, so one of them is
 * always on and the remaining box cannot be unticked. LOCKED IS NOT
 * DISABLED — the input keeps its tab stop and its announced state
 * (aria-disabled + aria-description carry the reason), so this rule
 * supplies only the LOOK.
 *
 * It must read as settled rather than broken: the tick stays at full
 * strength because the filter really is on, the pointer stops offering
 * a click, and hover does not react. Dimming the tick would say
 * "unavailable" about a filter that is very much in force. */
:is(.fs-filterbar, .fs-scope) .fs-toggle--locked,
.fs-toggle--locked.fs-checkrow,
:is(.fs-filterbar, .fs-scope) .fs-toggle--locked input,
.fs-toggle--locked.fs-checkrow input {
  cursor: default;
}
:is(.fs-filterbar, .fs-scope) .fs-toggle--locked span:not(.mk):not(.mk-paint),
.fs-toggle--locked.fs-checkrow span:not(.mk):not(.mk-paint) {
  /* the LABEL recedes — that is what says "not yours to change now" —
     while the box itself stays fully lit. */
  opacity: 0.55;
}
:is(.fs-filterbar, .fs-scope) .fs-toggle span:not(.mk):not(.mk-paint),
.fs-toggle.fs-checkrow span:not(.mk):not(.mk-paint) {
  /* on the uniform 34px line (round 4; production padded to 37.5px).
     MarkIcon rollout 1: the box now rides inside .mk/.mk-paint spans —
     this rule is the LABEL-text seat only, so those are excluded (the
     bare `span` also padded .mk-paint and shoved the input 16px right). */
  /* G2b: THE icon -> text distance, one global value */
  padding: 0 0 0 var(--fs-checkrow-gap);
  line-height: var(--fs-checkbox-size);
}
/* typeahead (production select2 impression) */
.fs-combobox {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  max-width: 100%;
}
/* ONE LINE, FOREVER (D-111 part 4, second review — reverses the
   wrap-inside answer). A bar chip field never grows a second line: the
   DEFAULT width is its floor — --fs-chipfield-width, THE shared bar
   standard, for every chip field on films, transfers and screeners
   alike (the screeners-only 300px token this comment used to describe
   was removed by D-111 part 4's third review; kit-tables states the
   ruling), content MAY widen the field up to the space its row affords (the
   viewport-derived cap below — every ancestor is shrink-to-fit, so a
   percentage would be circular), and past the cap the chips ellipsize
   ON the one line. Nothing about content ever narrows the field or
   adds a line; height is the 34px bar line, always. */
.fs-filterbar-form .fs-combobox .fs-combobox-value {
  min-width: var(--fs-chipfield-width);
}
.fs-combobox .fs-control {
  height: var(--fs-bar-control-height);
}
.fs-combobox .fs-combobox-value {
  display: flex;
  flex-wrap: nowrap;
  width: max-content;
  max-width: calc(100vw - 79px);
  overflow: hidden;
  align-items: center;
  /* NOTHING SITS BETWEEN THE LAST CHIP AND THE FIELD'S INNER EDGE
     (D-121): a column-gap here would, so the inter-chip gap is a margin
     between chips instead — and it is the uniform chip gap token, which
     is what it always meant. */
  column-gap: 0;
  row-gap: 4px;
  height: var(--fs-bar-control-height);
  cursor: text;
}
.fs-combobox .fs-combobox-value.has-chips {
  /* AN EQUAL OPTICAL INSET ON ALL FOUR SIDES (D-121, owner's ruling),
     from the field's own vertical air — see --fs-chipfield-inset.

     This replaces two numbers. The right side was 24px, which was the
     clear-all ×'s room and became dead space when that control was
     removed; with the chip also capped short of it, 80px of a 200px
     field stood empty. The left was `--fs-control-inset - --fs-chip-lead`
     = 8, the G2.3 rule that landed a chip's TEXT on the placeholder's
     16px inset — superseded here: the chip's own surroundings win over
     matching the empty state's text position. */
  padding-left: var(--fs-chipfield-inset);
  padding-right: var(--fs-chipfield-inset);
}
/* the gap BETWEEN chips — never before the caret, so one chip can reach
   the field's inner right edge */
.fs-combobox .fs-combobox-value .fs-chip + .fs-chip {
  margin-left: var(--fs-chipfield-gap);
}
/* THE CLICKABLE STRIP BESIDE A CHIP (D-122). The caret keeps the
   reserve less the gap in front of it, so there is real field to click
   into next to a chip — and typed text never touches the chip, which it
   did while the two were flush. */
.fs-combobox .fs-combobox-value.has-chips .fs-combobox-input {
  margin-left: var(--fs-chipfield-gap);
  flex: 1 1 auto;
  min-width: calc(var(--fs-chipfield-reserve) - var(--fs-chipfield-gap));
  width: 0;
}
.fs-combobox-input {
  flex: 1 1 24px;
  min-width: 24px;
  border: none;
  background: none;
  outline: none;
  font-size: 14px;
  font-weight: 300;
  color: var(--color-text);
  /* G.5: the INSET is the value box's own --fs-control-inset (16px, the
     control-kit register every other bar control uses). The input added
     8px of its own on top, so Film and Standort sat 24px in while the
     selects sat 16px in. The box owns the inset; the input owns none. */
  padding: 0;
}

/* chip: production select2 choice (extracted) — grey box, white 14/300
   text, 4px radius, 3px self-colored border, bold ×. NEVER wraps
   (round 3): long titles ellipsize; the title attr shows the full name.
   Only the dropdown panel entries wrap. */
.fs-chip {
  display: inline-flex;
  /* BASELINE, not centre (D-121, owner's ruling): the × sits on the
     text's baseline the way it does in the reference, where it is
     simply the next character in a line of running text. Centred
     against the chip box it read as slightly off. */
  align-items: baseline;
  gap: var(--fs-remove-x-gap);
  /* one-line rule: past the row's space the chips COMPRESS and their
     labels ellipsize (the label carries the ellipsis; the x never
     shrinks) — a second line is impossible by construction */
  flex-shrink: 1;
  min-width: 0;
  /* full-length like production (401px chips measured); only a chip
     longer than the box maximum ellipsizes */
  max-width: 100%;
  min-width: 0;
  background-color: var(--color-text);
  border: 3px solid var(--color-text);
  border-radius: 4px;
  padding: 0 5px;
  color: var(--color-surface);
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  white-space: nowrap;
}
.fs-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* THE CHIP THAT IS NEVER CUT (D-131, owner's ruling) — the grant page's
   recipients, and nothing else. The one-line rule above exists so a
   FILTER row cannot grow: a bar chip's label repeats a filter that is
   also in the address, so an ellipsis costs nothing. This chip names a
   person a film is about to be sent to, and it is read to check exactly
   that, so it keeps its full width and the field wraps around it
   (.screener-recipients). One modifier, both halves of the reason. */
.fs-chip--whole {
  max-width: none;
  flex-shrink: 0;
}
.fs-chip--whole .fs-chip-label {
  overflow: visible;
  text-overflow: clip;
}
/* THE REMOVE ×, IN ONE PLACE (D-121, owner's ruling). The reference is
   the film conversions row's delete ×, which sets NO font of its own —
   it is the next character in its line of text, so it carries that
   line's size, weight and baseline. Everything here follows from that,
   and both sites wear this class so the two cannot drift.

   What each site still owns is its COLOUR, because that is context and
   not design: the conversions × is the disabled grey on white and must
   not compete with the links beside it; the chip's × is on a dark chip. */
.fs-remove-x {
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  /* the reference's whole typography rule: inherit */
  font: inherit;
  color: inherit;
  /* one-line rule: the x never compresses — the label does */
  flex-shrink: 0;
  white-space: nowrap;
  cursor: pointer;
}
/* THE CHIP'S × IS BOLD (D-122, owner's correction): it is a control,
   not text, so it may look like one. What it keeps from D-121 is
   everything else the reference gave it — the size, the family, the
   baseline it sits on and the word-space before it. Only the weight is
   its own. */
.fs-chip-x {
  color: var(--color-surface);
  font-weight: 700;
}
/* the field's clear-all × is gone (D-121, owner's ruling — Reset covers
   that job), and its styling with it. */
/* Panel: taller and wider than the trigger so long titles read — Tom's
   spec (production keeps the panel at trigger width and wraps,
   max-height 300px). Entries wrap like production. */
.fs-combobox-dropdown {
  z-index: 1100;
  /* ONE WIDTH, WHATEVER ARRIVES (D-123) — see --fs-suggest-panel-width.
     The viewport still clamps it, because a panel wider than the window
     is not a panel; that is the window's doing, never the content's. */
  width: min(var(--fs-suggest-panel-width), calc(100vw - 32px));
  /* FIFTEEN ROWS, NO SCROLLBAR (D-120 R1). A row is 7+7 padding on a
     21px line = 35px, so fifteen need 525px; the panel held 480 and
     scrolled at ~13.7. The number is the owner's, so the panel gives
     way, not the rule.

     It still yields to the WINDOW: on a short viewport the panel would
     otherwise run off the bottom, so the cap is whichever is smaller.
     The panel opens below a bar that sits ~150px down, hence the
     subtraction — at the 900px height the suite pins there is room for
     all fifteen, and below roughly 700px it scrolls again, which is the
     honest behaviour for a window that cannot show fifteen rows. */
  max-height: min(525px, calc(100vh - 160px));
  overflow-y: auto;
  /* THE PAGE BEHIND NEVER MOVES (D-123, owner's ruling).
     
     Measured cause: with the opening set the panel holds exactly
     fifteen rows and is exactly 525px, so scrollHeight === clientHeight
     — there is nothing to scroll, and a wheel over it chained straight
     through to the pane behind, which moved 601px. The same happens at
     either end of a list that CAN scroll. `contain` stops the chain in
     both cases and for every gesture — wheel, trackpad and touch —
     because it is the scroll container's own property rather than a
     handler on one kind of event.

     `none`, not `contain` (D-123, owner's correction): `contain` stops
     the chain but still allows the elastic bounce at the panel's own
     ends. At the end of the list the scroll stops, hard — no bounce, no
     give. */
  overscroll-behavior: none;
  background: var(--color-surface-muted);
}
.fs-combobox-option {
  display: block;
  width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
  padding: 7px 16px;
  border: none;
  background: none;
  text-align: left;
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  color: var(--color-text);
  cursor: pointer;
}
/* the "already selected" paint is gone with the entries it painted
   (D-122, owner's ruling): a chipped value leaves the panel rather than
   being shown again in bold. */
/* ONE HIGHLIGHT (D-117). `:hover` used to paint this same accent beside
   `.is-active`, so the entry the pointer was on and the entry the panel
   had lit were blue AT THE SAME TIME — and Enter took the lit one. The
   pointer now moves `.is-active` itself (controls.tsx onMouseEnter), so
   there is one state, one blue entry, and Enter can only take what is
   on screen. A :hover rule here would restore the defect. */
.fs-combobox-option.is-active {
  color: var(--color-surface);
  background: var(--color-accent);
}
:is(.fs-filterbar, .fs-scope) .fs-group {
  display: inline-flex;
  align-items: center;
  margin-right: 16px;
  vertical-align: middle;
}
/* Single line in its resting state; chip growth may wrap it —
   user-provoked, like production select2 (round 5). Controls stay
   top-aligned against a grown box. */
.fs-filterbar-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  /* wrapped bar lines breathe like production (extracted 17px between
     legacyref's wrapped rows) — no effect while single-line */
  row-gap: 17px;
}
/* ONE gap token between every bar element (round 5) — matches the
   16px between groups, asserted by the sweep's equal-gap check */
:is(.fs-filterbar, .fs-scope) .fs-group > * + * {
  margin-left: 16px;
}
/* the trailing group margin would push the line 0.1px past the form edge */
.fs-filterbar-form .fs-group:last-child {
  margin-right: 0;
}
/* EVERY pane reserves its scrollbar gutter permanently (stability
   doctrine): a scrollbar (dis)appearing must never reflow content, and
   all panes must share the same content width so switching tabs moves
   nothing. */
.app-pane {
  scrollbar-gutter: stable;
}
/* Reset = production's OWN bar reset (round 23, D-028 — supersedes the
   nav-tab derivation): legacyref a.btn.btn-primary in the filter bar
   computes 11.5px/500 uppercase, line-height 14.375, WHITE text,
   0-width solid border tracking the background, hover #0d65a0
   (border #0c5f96), box 71x34.375. NOTE: production's standard
   .btn-primary elsewhere (login, profile save) stays 14px — the bar
   reset is production's one SMALL primary, so this rule is scoped,
   not global; .fs-btn--primary is untouched. The 34.375 height is
   production's own 0.375 offset above the bar's 34px control line. */
:is(.fs-filterbar, .fs-scope) .fs-reset {
  border: 0 solid var(--color-accent);
  border-radius: 0;
  background: var(--color-accent);
  color: var(--color-surface);
  font-size: 11.5px;
  font-weight: 500;
  /* D-121, owner's ruling: EVERY control on this bar is the same
     height, from the one token. This was 34.375px — production's own
     0.375 offset above the bar's 34px control line, extracted in round
     23 — and the owner measured it against the filters. The centring is
     done by the flex box rather than by a vertical padding, so the
     label sits in the middle of whatever the token says. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 14.375px;
  height: var(--fs-bar-control-height);
  padding: 0 16px;
  cursor: pointer;
  text-transform: uppercase;
}
:is(.fs-filterbar, .fs-scope) .fs-reset:hover {
  background: #0d65a0;
  border-color: #0c5f96;
}

/* production custom-checkbox-compact/-light.
   O6: --compact no longer means "smaller" — there is one size and the
   base rule above already carries it. The class stays because surfaces
   name it and because the glyph below is its own (15px, not the base
   check), but it can no longer make a box a different size from any
   other box in the app. */
:is(.fs-filterbar, .fs-scope) .fs-toggle--compact input::after,
.fs-checkrow.fs-toggle--compact input::after {
  line-height: var(--fs-checkbox-size);
  font-size: 15px;
}
:is(.fs-filterbar, .fs-scope) .fs-toggle--light input,
.fs-checkrow.fs-toggle--light input {
  background-color: var(--color-surface);
}

/* Mobile burger dropdown (D-005: production's open menu overlays content
   SEMI-transparently — a glitch; ours is opaque). */

/* production gap between the Trailer/Features toggles is 16px
   (legacy .custom-control+.custom-control margin-left 1rem) */
:is(.fs-filterbar, .fs-scope) .fs-group--toggles > * + * {
  margin-left: 16px;
}
/* films Sort by: plain inline label, select flush after it (production:
   label [869..928], select at 928 — no padded chip, no extra gap) */
.films-sort-label {
  color: var(--color-text);
  font-size: 14px;
  font-weight: 300;
  margin-right: 8px;
}
/* the Sort-by pair: the label's own 8px right margin governs inline —
   no group rhythm between label and select */
.fs-filterbar .fs-group--sort > * + * {
  margin-left: 0;
}
/* round 22 (D-027): in the INLINE bar the Sort-by pair rides the bar's
   RIGHT edge like production (legacyref 1600: select right = 1568 =
   viewport - 32 margin; label on the text baseline, 8px text->select
   gap — ours via the label's margin-right, production's via label
   padding; visually identical). Stacked view keeps label-above. */
@media (min-width: 927px) {
  .fs-filterbar-form .fs-group--sort {
    display: flex;
    align-items: baseline;
  }
}
/* Sort-by right-aligns ONLY while it shares the row (round-22 rule,
   scoped in D-032): the films bar fits one row from 1149 up —
   controls 220 (intrinsic Distributor, D-038) + 206 toggles + 176 +
   159 combobox + 245 sort = 1006, + 4x16 gaps + 64 margins + 15
   scrollbar = 1149 (derived per bar: only Films HAS a sort group;
   D-038 re-based the derivation from the old 176px distributor =
   1117). Below 1149 the group wraps and sits flush at the shared
   LEFT edge like a stacked control.

   M4X: RE-DERIVED, and it was a real 12px hole. The toggles group is
   206 wide, not the 218 the D-038 derivation assumed — D-050 gave every
   checkbox in the app one size (--fs-checkbox-size 34, M4c/P1) and the
   two toggles came out 12px narrower between them. The content
   therefore fits from 1149, while this query still said 1161: in that
   band the group shared the row WITHOUT riding its right edge, which is
   the one thing the round-22 rule exists to prevent. Measured, not
   guessed — the bar wraps at 1148 and fits with zero slack at 1149.

   D-111 part 4 (item 7): the EN pair label is "Trailers" now — the
   toggles group measures 213 (was 206), so the one-row fit moved
   1149 -> 1156. Measured again, not guessed: the bar wraps at 1155 and
   fits at 1156 (parity/geometry.mjs pins both sides). */
@media (min-width: 1156px) {
  .fs-filterbar-form .fs-group--sort {
    margin-left: auto;
  }
}

/* production: EVERY profile-page panel is the muted var(--color-text) (film/user
   admin forms keep the darker --color-text-strong) — color audit R3-3g */
form.profile .fs-panel {
  color: var(--color-text);
}


/* Bar items never SHRINK — they WRAP (design pass 2): a growing chip
   field pushes Site/Reset to the next row via normal flex wrap; every
   item's base is capped at the row width, so nothing can overflow.
   Without this, flex-shrink crushed Site to a sliver beside a wide
   Film field instead of wrapping it. */
.fs-filterbar-form > * {
  flex-shrink: 0;
}

/* STACKED transfers bar below the master 768 breakpoint (round 18):
   every control shares ONE full width like production's mobile stack
   (extracted: all controls 350px at 380, incl. the select2s) with
   production's 18px control-to-control gap. Placed after the legacy
   543px mobile-bar media so its margins (16px) are neutralized for
   the transfers bar; the Trailer/Features pair keeps its line. */
@media (max-width: 926px) {
  .fs-filterbar-form {
    row-gap: 18px;
  }
  .fs-filterbar-form .fs-group {
    display: flex;
    flex-wrap: wrap;
    row-gap: 18px;
    width: 100%;
    margin: 0;
  }
  /* Trailer/Features SIDE BY SIDE in every view (round 18 reversal of
     the round-16 own-row rule — production's mobile behavior is now
     the spec; the pair fits the 320 floor) */
  .fs-filterbar-form .fs-group--toggles {
    width: auto;
  }
  .fs-filterbar-form select.fs-control,
  .fs-filterbar-form .fs-combobox,
  .fs-filterbar-form .fs-combobox .fs-control {
    width: 100%;
    max-width: none;
  }
  .fs-filterbar-form .fs-combobox {
    display: block;
    margin: 0;
  }
  /* Sort by: label on its own line above its select, 6px apart
     (extracted from production's stacked films bar) */
  .fs-filterbar-form .fs-group--sort {
    flex-wrap: wrap;
    row-gap: 6px;
  }
  .fs-filterbar-form .fs-group--sort .films-sort-label {
    width: 100%;
    margin-right: 0;
  }
}

/* legacy App.jsx floating scroll-to-top (all pages, all viewports):
   48px var(--color-surface-muted) square fixed bottom-right, shown by ScrollToTop.tsx once
   the active pane scrolls past 100px (reference computed 2026-07-16) */
.scrollToTop {
  display: none;
  position: fixed;
  z-index: 10;
  right: 16px;
  bottom: 13.44px;
  padding: 12.8px 16px;
  text-align: center;
  background: rgb(242, 242, 242);
  color: rgb(77, 77, 77);
  transition: 0.3s;
}
.scrollToTop:hover {
  background: rgb(217, 217, 217);
  color: rgb(77, 77, 77);
}

/* deliver CPL select: the reference's custom-select filterbar-select-light
   (the 34px filterbar select on a WHITE surface) */
:is(.fs-filterbar, .fs-scope) .fs-select.fs-select--white {
  background-color: var(--color-surface);
}

/* FORM (panel) chip fields (design pass): production's select2 renders
   the chips INSIDE a white input box spanning the field width, like
   every neighboring input. Bar fields are untouched — this is the
   block variant only (the bar's shrink-to-fit growth + viewport cap
   stay scoped to .fs-filterbar-form). */
.fs-combobox--block {
  display: block;
  width: 100%;
  max-width: none;
}
.fs-combobox--block .fs-combobox-value {
  width: 100%;
  max-width: none;
  background-color: var(--color-surface);
}


/* A FRAGMENT CHIP LOOKS LIKE EVERY OTHER CHIP (D-121, owner's ruling).
   The asterisks and the italics that marked it as a pattern are gone —
   same shape, same weight, same colour. It is a chip, not an
   annotation, so there is no modifier class left to style. */


/* THE FIRST CHIP DOES NOT MAKE THE FIELD GROW (D-121).
   A chip's label is capped so that ONE of them fits inside the resting
   width together with the field's furniture and the caret; the field
   grows only from the SECOND chip onward, which is expected. The cap is
   derived from the resting width in control-kit.css — change the width
   and the cap follows. */
.fs-filterbar-form .fs-combobox-value .fs-chip {
  max-width: var(--fs-chip-max);
}
/* App-owned structural kit — the replacement for the vendored legacy CSS.
   Every value here was extracted from the deployed pre-migration build
   (parity/foundation-styles.json.txt) which is itself the extracted
   production impression (parity/design-tokens.md, controls-reference.md).
   Shared patterns live here; one-off styling belongs in components as
   Tailwind token utilities. */

/* --- brand font (files in public/static/fonts, weights 300/400/500/700)

   woff2 first — a lossless repackaging of the SAME ttf (verified: 772
   glyphs and identical vertical metrics per weight), ~73% smaller
   (116KB -> ~31KB). The ttf stays as the fallback src for anything too
   old to know woff2. All four files are also preloaded from index.html,
   so they are in flight before this stylesheet is even parsed.

   font-display: OPTIONAL, decided by the stability doctrine, not by
   default. `swap` guarantees Gotham but allows a LATE swap — text
   reflowing after paint, which is exactly the "niemals springen" class,
   and exactly what Chrome's slow-network intervention was doing to us
   uninvited. `optional` inverts the promise: with preload + 31KB files
   the font wins the block period on any ordinary connection, and on a
   genuinely slow first visit the fallback simply STAYS for that
   pageload — no swap, no jump, no intervention (there is nothing left
   to intervene in) — while the font finishes downloading at low
   priority and every later document paints Gotham from cache. Wrong
   font beats moving text; that ranking is the doctrine's, made once. */
@font-face {
  font-family: 'Gotham';
  src:
    url('/static/fonts/Gotham-Light.woff2') format('woff2'),
    url('/static/fonts/Gotham-Light.ttf') format('truetype');
  font-weight: 300;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: 'Gotham';
  src:
    url('/static/fonts/Gotham-Book.woff2') format('woff2'),
    url('/static/fonts/Gotham-Book.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: 'Gotham';
  src:
    url('/static/fonts/Gotham-Medium.woff2') format('woff2'),
    url('/static/fonts/Gotham-Medium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: 'Gotham';
  src:
    url('/static/fonts/Gotham-Bold.woff2') format('woff2'),
    url('/static/fonts/Gotham-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: optional;
}

/* --- document base (ex bootstrap reboot subset we actually rely on) */
html,
body,
#app {
  height: 100%;
}
#app {
  /* the app covers the full document: min-width matches the hard 320
     floor; 100vh includes the strip a horizontal scrollbar occupies —
     without it the dark body canvas showed as a band below the page
     (round 18) */
  min-width: 320px;
  min-height: 100vh;
}
body {
  margin: 0;
  background-color: var(--color-ink);
  /* the exact production stack (per-element audit compares the string) */
  font-family: Gotham, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    Arial, sans-serif;
  font-size: 16px;
  font-weight: 300;
  line-height: 1.5;
  color: var(--color-text);
}
/* form controls inherit the document font like the legacy reboot did —
   without this they fall back to Arial/monospace (audit finding 2026-07-13) */
button,
input,
optgroup,
select,
textarea {
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}
b,
strong {
  /* production computes 500, not the browser's bolder→700 */
  font-weight: 500;
}
small {
  font-size: 80%;
  font-weight: 400;
}
* ,
*::before,
*::after {
  box-sizing: border-box;
}
a {
  color: var(--color-accent);
  text-decoration: none;
}
img {
  max-width: 100%;
  vertical-align: middle;
}
h1, h2, h3, h4, h5, p, ul, figure {
  margin: 0 0 8px;
}
/* weight only on headings — on ul it broke the inherited 500 of the
   mobile value-box cells (reference bolds those values). line-height 1.1
   is the bootstrap-reboot heading value the reference computes. */
h1, h2, h3, h4, h5 {
  font-weight: 300;
  line-height: 1.1;
}
h1 { font-size: 40px; line-height: 44px; }
h2 { font-size: 32px; }
h3 { font-size: 28px; }
h4 { font-size: 24px; }
h5 { font-size: 20px; }
button {
  font-family: inherit;
}
fieldset {
  min-width: 0;
  padding: 0;
  margin: 0;
  border: 0;
}
table {
  border-collapse: collapse;
}
label {
  margin-bottom: 8px;
  display: inline-block;
}

/* --- centered container (production bootstrap-alpha ladder) */
.fs-container {
  width: 100%;
  margin-right: auto;
  margin-left: auto;
  padding-right: var(--fs-page-inset-mobile);
  padding-left: var(--fs-page-inset-mobile);
}
/* round 20: the ladder rides the unified breakpoint — mobile keeps
   production's 576 cap, the desktop tiers (940/1140) start at X1;
   the old 720 tier sat between the retired 768 and 992 steps and is
   unreachable under the unified model */
@media (min-width: 544px) { .fs-container { max-width: 576px; } }
@media (min-width: 927px) { .fs-container { max-width: 940px; } }
@media (min-width: 1200px) { .fs-container { max-width: 1140px; } }
/* full-width variant with the page gutter (ex container-fluid).
   ROUND 16 (supersedes round 15's single edge), re-homed to the
   unified X1 in rounds 19/20: above it the desktop 32px edge, below
   it the legacyref-extracted 15px mobile edge; no further margin
   steps at any width on either side. */
.fs-container-fluid {
  width: 100%;
  padding-right: var(--fs-page-inset);
  padding-left: var(--fs-page-inset);
}
@media (max-width: 926px) {
  .fs-container-fluid {
    padding-right: var(--fs-page-inset-mobile);
    padding-left: var(--fs-page-inset-mobile);
  }
}

/* --- the scrolling pane (ex .content): keep-alive scroller under the
       fixed header; the transparent variant lets the dark body back the
       film-detail hero AND macOS elastic overscroll */
.app-pane {
  position: relative;
  z-index: 2;
  flex: 1;
  height: 100%;
  width: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  padding: var(--fs-pane-pad-top) 0 0;
  margin-bottom: -24px;
  background-color: var(--color-surface);
}
.app-pane--transparent {
  background: none;
}

/* --- buttons (production .btn: 10px 16px, uppercase, w500, radius 0) */
.fs-btn {
  display: inline-block;
  padding: 10px 16px;
  border: none;
  border-radius: 0;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.25;
  text-transform: uppercase;
  text-align: center;
  vertical-align: middle;
  white-space: nowrap;
  cursor: pointer;
  background: transparent;
  color: var(--color-text);
  /* legacy .btn carried an 8px bottom margin everywhere */
  margin-bottom: 8px;
}
.fs-btn--primary {
  background-color: var(--color-accent);
  color: var(--color-surface);
}
.fs-btn--primary:hover {
  background-color: #0e6cab;
  color: var(--color-surface);
}
.fs-btn--success {
  background-color: var(--color-action-success);
  color: var(--color-surface);
}
.fs-btn--success:hover {
  background-color: #4cae4c;
  color: var(--color-surface);
}
.fs-btn--danger {
  background-color: var(--color-danger);
  color: var(--color-surface);
}
.fs-btn--danger:hover {
  background-color: #b00217;
  color: var(--color-surface);
}
.fs-btn--sm {
  padding: 8px 10px;
  font-size: 12px;
  line-height: 15px;
}
.fs-btn--link {
  /* legacy .btn-link keeps the .btn 14/500/uppercase; only surface and
     paddings reset (reference: deliver BACK / SHOW ITEMS, 17.5px tall) */
  background: transparent;
  color: var(--color-accent);
  padding: 0;
  margin-bottom: 0;
}
.fs-btn:disabled,
.fs-submit--blocked {
  /* THE disabled look — ONE definition (2026-07-28: the class variant
     joined the existing :disabled register for GuardedSubmit, whose
     button stays CLICKABLE while blocked so the bubble can explain;
     CREATE ORDER's old inline utilities carried these same values). */
  opacity: 0.65;
}
/* ...but the CURSOR splits (D-111 part 4 correction, item 2): a truly
   disabled button is INERT — default cursor, no hand, no promise. The
   blocked submit keeps not-allowed because its click still fires and
   explains. */
.fs-btn:disabled {
  cursor: default;
}
.fs-submit--blocked {
  cursor: not-allowed;
}
/* blocked ≠ disabled: the click still fires, but hover must not react
   either — pin the resting surface (both consumers are accent submits) */
.fs-submit--blocked:hover {
  background-color: var(--color-accent);
  color: var(--color-surface);
}

/* --- data table (production .table impression: uppercase bold headers,
       14px/300 cells, hairline row separators drawn by row borders) */
.fs-table {
  width: 100%;
  max-width: 100%;
  margin-bottom: 16px;
  border-collapse: collapse;
  /* production: the table inherits the 16px document font; only th/td set
     14px — content outside cells (group headings) renders at 16px */
  font-size: 16px;
  line-height: 24px;
}
.fs-table th {
  padding: 12px 8px;
  /* font-size lives once in kit-tables.css (.fs-table th = 0.875rem =
     14px); the redundant 14px copy here was deleted 2026-07-27 (D-041). */
  font-weight: 700;
  line-height: 21px;
  text-transform: uppercase;
  text-align: left;
  vertical-align: bottom;
  color: var(--color-text);
}
.fs-table td {
  /* bootstrap base 0.75rem narrowed by the stack rule; the transfers
     table overrides to 0.35rem 0.5rem in kit-tables */
  padding: 12px 8px;
  vertical-align: top;
  /* font-size: single source in kit-tables.css (.fs-table td = 0.875rem
     = 14px); redundant 14px copy deleted 2026-07-27 (D-041). */
  line-height: 21px;
  font-weight: 300;
}

/* --- panel: ONE definition lives in kit-forms.css (the form/system
   surface — forms own it). This kit.css copy was deleted 2026-07-27
   (D-041): it duplicated .fs-panel background-color across files, the
   silent cross-file override pattern. */

/* --- text input (production .form-control impression on white) */
.fs-input {
  display: block;
  width: 100%;
  /* KIT variant: pre-consolidation geometry restored (verdict);
     horizontal inset = THE token */
  padding: var(--fs-input-pad-y) var(--fs-control-inset);
  font-size: var(--fs-input-font-size);
  font-weight: var(--fs-control-font-weight);
  line-height: 20px;
  color: var(--color-text-strong);
  background-color: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: 0;
  outline: none;
}
/* dark variant (header search: gray field, light text) */
/* KIT variant: production nav geometry restored (verdict). */
.fs-input--dark {
  min-height: var(--fs-search-height);
  padding: var(--fs-search-pad-y) var(--fs-control-inset);
  border: none;
  background-color: var(--color-text);
  color: var(--color-surface-muted);
  font-weight: 400;
  line-height: 16px;
}
/* bootstrap-alpha's .form-control::placeholder — the reference computes
   the input's own color at 0.54 (modern Chrome's UA default is opaque
   #757575, so this must be explicit) */
.fs-input--dark::placeholder {
  color: inherit;
  opacity: 0.54;
}

/* --- icon metrics: all icons are exact FA 4.7 outlines (faGlyphs.ts);
   fs-icon--fa is the operative sizing (height-true 1em like the font
   glyph, baseline at -0.143em = the font's 256/1792 descent) --- */
.fs-icon {
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  vertical-align: -0.245em;
  flex-shrink: 0;
}
/* exact-FA-outline icons (faGlyphs.ts): height-true to 1em like the font
   glyph they replicate; the font's descent puts the baseline at -0.143em */
.fs-icon--fa {
  width: 1em;
  height: 1em;
  vertical-align: -0.143em;
}
.fs-icon--fw {
  width: 1.28em;
}
.fs-icon--lg {
  /* legacy body .icon-lg: font-size 20px in a 25px line (rows sized to
     36.19px in the admin tables) */
  width: 20px;
  height: 20px;
  vertical-align: -0.25em;
  margin-top: -2px;
  margin-bottom: -2px;
}

/* --- app header (extracted: two dark bars, fixed, z 20) --- */
.app-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  /* fixed positioning tracks the VIEWPORT, so body's min-width cannot
     hold it — the round-17 gap (round 18): clamp the header itself */
  min-width: 320px;
}
/* ROUND 14 (Tom's spec, replaces production-matching for the header):
   ONE header styling at every width — same type, same icons, same
   paddings, one meta height and one nav height, no breakpoint jumps.
   The only responsive rule the header owns is the email cutoff. */
.app-navbar-meta {
  position: relative;
  z-index: 30;
  display: flex;
  align-items: center;
  height: 57.5px;
  padding: 0 32px;
  background-color: var(--color-ink);
}
.app-navbar-main {
  /* no right padding: the search field runs flush to the window edge */
  padding-left: 32px;
  padding-right: 0;
}

.app-navbar-main {
  position: relative;
  display: flex;
  align-items: stretch;
  height: 48px;
  background-color: rgba(77, 77, 77, 0.9);
}
.app-customer {
  display: inline-block;
  flex-shrink: 0;
  /* G.8: a long company name TRUNCATES; it never disappears, never
     wraps, never pushes the layout. Hand-set caps per REGISTERED
     breakpoint (md 927 / lg 1586 below), no runtime measurement — the
     collapse hook uses the same three numbers. */
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 20px 16px 20px 0;
  color: var(--color-surface);
  font-size: 14px;
  font-weight: 500;
  line-height: 17.5px;
  text-transform: uppercase;
  white-space: nowrap;
  /* the divider next to the customer name: production puts a subtle
     1px #4d4d4d border-right here (audit 2026-07-13), not a var(--color-text)
     border-left on the brand */
  border-right: 1px solid rgb(77, 77, 77);
}
@media (min-width: 927px) {
  .app-customer {
    max-width: 240px;
  }
}
@media (min-width: 1586px) {
  .app-customer {
    max-width: 320px;
  }
}
.app-brand {
  display: inline-block;
  /* round 16: renders whole or not at all (the runtime collapse hides
     it) — round 12's ellipsizing removed */
  white-space: nowrap;
  flex-shrink: 0;
  padding: 20px 16px;
  color: var(--color-surface-muted);
  font-size: 14px;
  font-weight: 300;
  line-height: 17.5px;
  text-transform: uppercase;
}
.app-nav-link {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 16px;
  color: var(--color-surface-muted);
  font-size: 14px;
  font-weight: 500;
  line-height: 14px;
  text-transform: uppercase;
}
/* G.2: the film-detail tabs (THEATRICAL / HOMEVIDEO) take the
   MAIN MENU's hover — the same rule, not a copy of its values. */
.app-nav-link:hover,
.fd-tab:hover {
  /* production: the blue lands already on hover (extracted: bg
     rgb(17,131,207), text stays var(--color-surface-muted), no transition) — round 11 */
  background-color: var(--color-accent);
  color: var(--color-surface-muted);
}
.app-nav-link--active {
  background-color: var(--color-accent);
  color: var(--color-surface-muted);
}
/* THE CLICK IS ACKNOWLEDGED, THE SCREEN IS NOT CLAIMED (D-068).
   The highlight says "this is what you are looking at" and may only move
   when the surface does. A click still has to answer at once, so it gets
   its own state on the entry that was CLICKED, while --active stays where
   the reader still is. Deliberately not the accent fill: the two must not
   be mistaken for each other, which is the whole reason the highlight was
   not allowed to move early. */
.app-nav-link--pending {
  background-color: color-mix(in srgb, var(--color-accent) 30%, transparent);
  color: var(--color-surface-muted);
}
.app-toggler {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  /* flush at the shared 32px edge (round 15) — the nav bar's own
     padding provides the offset; the box is 52.6px wide */
  padding: 0;
  border: none;
  background: transparent;
  color: var(--color-surface);
  cursor: pointer;
}
.app-toggler-box {
  display: inline-flex;
  align-items: center;
  padding: 16px;
}
.app-toggler--open .app-toggler-box {
  background-color: var(--color-accent);
}
/* mobile burger dropdown (opaque per D-005) */
.app-nav {
  display: flex;
  flex: 1;
  align-items: stretch;
}
/* Mobile burger STRUCTURE only (justified survivor: which nav variant
   renders — tabs vs burger — is structure, not styling; closed heights
   are identical). Open-menu structure extracted from production at a
   burger width: solid opaque OVERLAY (content does not move), items
   48px tall with ZERO gaps and equal widths (the active highlight
   spans exactly the item width), first item 16px below the bar. The
   burger-view search constant lives here too (round 15: the search
   width may change only at this breakpoint). */
@media (max-width: 926px) {
  /* the master breakpoint switches margins with the layout (round 16) */
  .app-navbar-meta {
    padding: 0 var(--fs-page-inset-mobile);
  }
  .app-navbar-main {
    position: relative;
    height: 48px;
    padding-left: var(--fs-page-inset-mobile);
  }
  .app-toggler { order: 1; }
  /* G3.3: the field keeps THE width in the mobile layout too and gives way
     only for the hamburger. THE GAP IS THE HARD CONSTRAINT AT EVERY WIDTH
     (reviewer 2026-07-30): a width FLOOR would win over max-width in the
     cascade (min-width beats max-width by spec), and at 320px that is
     exactly what collapsed the gap to 0.5px — the field jumped into the
     hamburger at the very end of the curve. There is no floor any more:
     the field is THE width, capped by what is left beside the hamburger,
     so the curve is continuous and the gap holds everywhere.
     min-width 0 is what lets a flex item shrink past its content. */
  .app-navbar-main .app-search {
    order: 2;
    flex: 0 1 var(--fs-search-width);
    min-width: 0;
    max-width: calc(
      100% - var(--fs-search-toggler) - var(--fs-search-gap-min)
    );
  }
  .app-nav { display: none; }
  .app-nav--open {
    display: block;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 40;
    background-color: rgb(77, 77, 77);
    padding: 16px var(--fs-page-inset-mobile);
  }
  .app-nav--open .app-nav-link {
    width: 100%;
    height: 48px;
    padding: 16px;
  }
}

/* --- header dropdown menus (extracted .dropdown-menu impression) --- */
.app-menu-toggle {
  display: inline-flex;
  align-items: center;
  /* height comes from padding + line-height like production (57.5px
     desktop, 55px mobile via the smaller type) — a fixed 57.5px here
     was the round-13 overflow cause at the mobile bar */
  padding: 20px 16px;
  border: none;
  background-color: transparent;
  color: rgb(245, 245, 245);
  font-size: 14px;
  font-weight: 300;
  line-height: 17.5px;
  cursor: pointer;
}
/* :last-of-type doubles beat the ported global
   `.fs-icon:last-of-type { margin-right: 0 }` (kit-film.css). Production's
   fa-fw box (18px incl. its 8px padding) already contains the gap — no
   extra margin, or the toggles run 8px wider than production. */
.app-menu-toggle .fs-icon,
.app-menu-toggle .fs-icon:last-of-type {
  margin-right: 0;
}
/* bootstrap-style solid dropdown caret (production: ~4.2px triangle, not a
   14px chevron glyph) */
.app-caret {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 0.3em;
  vertical-align: middle;
  border-top: 0.3em solid;
  border-right: 0.3em solid transparent;
  border-left: 0.3em solid transparent;
}
.app-menu-toggle[aria-expanded='true'] {
  background-color: rgb(77, 77, 77);
}
/* Dropdown anchor (round 19, seam fix): the wrapper stretches to the
   FULL meta-bar height (the toggle stays centered inside), so the
   panel's top: 100% is exactly the bar's bottom edge. Anchoring the
   panel to the toggle's own box let the nav bar bleed through in a
   1.8px strip whenever the collapsed (icon-only) toggle was shorter
   than the bar and got flex-centered. */
.app-menu-wrap {
  position: relative;
  align-self: stretch;
  display: inline-flex;
  align-items: center;
}
.app-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 2000;
  min-width: 160px;
  padding: 5px 0;
  background-color: rgb(77, 77, 77);
  text-align: left;
}
.app-menu-item {
  display: block;
  width: 100%;
  padding: 8px 32px 8px 16px;
  color: var(--color-surface-muted);
  font-size: 14px;
  font-weight: 400;
  line-height: 21px;
  white-space: nowrap;
  text-align: left;
  border: none;
  background: transparent;
  cursor: pointer;
}
.app-menu-item:hover {
  color: var(--color-surface);
  background-color: var(--color-ink);
}
/* Stacked icon-column label lead (SHARED — user menu, /contact card):
   every label starts at ONE x = the column edge (MarkIcon axis) +
   GAP_ICON. GAP_ICON arrives as --mk-gap (fed from the registry on the
   column container) — the SAME "following element carries the gap" token
   the deliver-tree name cell and the film-detail column use; no
   page-local value, no per-item gap. */
.mk-col-label {
  padding-left: var(--mk-gap);
}
/* A label that runs to a SECOND line (the /contact address). Inline
   padding applies to the first line box only, so a wrapped line would
   start back under the glyph; as its own box every line starts at the
   text column — the same x, from the same --mk-gap, with no second
   value to keep in step. */
.mk-col-label--lines {
  display: inline-block;
  vertical-align: top;
}
.app-menu-divider {
  height: 1px;
  margin: 8px 0;
  background-color: rgb(229, 229, 229);
  opacity: 0.25;
}

/* --- header search (dark field + magnifier addon + results) --- */
/* G3.1: THE FOOTER IS A PAGE'S CLOSING BAND, NEVER A PAGE — one rule, for
   EVERY page, in one home.
   While a route is still loading (or renders something out of flow, like
   the map's absolutely-positioned canvas), the pane's content is empty and
   the footer moved up under the nav bar: the dark claim band standing in
   for the page. The first attempt gave the outlet's FIRST CHILD a
   min-height, which missed exactly those two cases — an out-of-flow first
   child creates no flow height, and a page that renders several siblings
   only stretched the first one. The pane owns it now: the closing band
   sits at the BOTTOM of the pane's box whatever the page does, and no
   router state or timing is involved. */
.app-pane {
  display: flex;
  flex-direction: column;
}
.app-pane > footer {
  margin-top: auto;
}
/* THE PAGE AREA — one rule, three guarantees (J0, after the D-048 rule
   broke two of them).

   1  THE BOX IS NEVER SHORTER THAN THE PAGE. This is what went wrong: the
      pane is a flex column with a definite height, so this box is a flex
      item, and a flex item SHRINKS by default. It was being squeezed down
      to its own min-height — measured at exactly 100vh on a film detail
      whose content was 1304px and on /films whose grid was 246121px — and
      the closing band, sitting right after that clamped box, landed on top
      of the page. `flex: none` is the fix: the box is its content, always.
   2  AND NEVER SHORTER THAN THE PAGE AREA. A screenful MINUS what the pane
      has already spent on its top padding AND minus the band itself — so
      on a SHORT page the band is ON SCREEN at the bottom of the first
      viewport, without scrolling, which is where production puts it (K0;
      H3 stopped one band short of that and left it just under the fold).
      On a long page it simply follows the content.
   3  WHICH IS WHY THE BAND CAN NEVER BE WRONG. It has exactly two
      legitimate places: directly after the content, or at the bottom of
      the viewport. It can never be ABOVE both — which is what "over the
      page" and "mid-page" meant. A pane whose page is still loading, or
      whose page renders out of flow (the map's canvas), still has a full
      page area, so the band is at the fold from the first frame and never
      higher. No router state and no timing is involved.

   The inner flex column is what lets a full-bleed page (the map) take the
   whole height. */
.app-pane-content {
  display: flex;
  flex-direction: column;
  flex: none;
  min-height: calc(100vh - var(--fs-pane-pad-top) - var(--fs-footer-band));
}

.app-search {
  position: relative;
  display: flex;
  /* ONE width, never fluid (rounds 15/16; G3.3 dropped the separate
     mobile value): the field is --fs-search-width in both layouts, and in
     the mobile layout it shrinks only as far as the hamburger's minimum
     gap requires. */
  flex: 0 0 var(--fs-search-width);
  margin-left: auto;
}
.app-search-addon {
  display: flex;
  align-items: center;
  /* production input-group-addon: 16px left, 8px right (42px with the
     18px fa-fw glyph box); z-index lifts it above the results backdrop —
     without it the dim overlay darkened just the addon cell */
  padding: 0 8px 0 16px;
  position: relative;
  z-index: 10;
  background-color: var(--color-text);
  color: var(--color-surface-muted);
  font-size: 14px;
}
.app-search-addon .fs-icon,
.app-search-addon .fs-icon:last-of-type {
  margin-right: 0;
}
/* production ul.typeahead__list: var(--color-surface-muted), 1px #ccc border, 5px vertical
   padding, 2px below the bar, NO shadow; rows 16px on a normal line
   (31px rows), hover var(--color-line-strong) */
.app-search-results {
  position: absolute;
  top: 50px;
  left: 0;
  right: 0;
  z-index: 999;
  padding: 5px 0;
  background: rgb(242, 242, 242);
  border: 1px solid rgb(204, 204, 204);
}
.app-search-result {
  display: block;
  padding: 6px 12px;
  color: var(--color-ink);
  font-size: 16px;
  font-weight: 400;
  line-height: normal;
  cursor: pointer;
}
.app-search-result:hover,
.app-search-result--active {
  background-color: rgb(217, 217, 217);
  color: rgb(60, 60, 60);
}
.app-search-result-sub {
  font-size: 12px;
  font-weight: 400;
  line-height: normal;
  color: rgb(128, 128, 128);
}

/* --- film grid (ex .movielist-*, ported from _movielist.scss) --- */
.film-grid {
  display: flex;
  flex-wrap: wrap;
  /* G.12: the grid is WINDOWED — the spacers above and below the rendered
     rows change height as the window moves. Chrome's scroll anchoring
     "helpfully" compensates for that by moving the scroll offset, which
     silently dragged a restored position away (measured: a restore landed
     exactly on 6000px and was then pulled to 4982px). The app owns the
     offset here; the browser must not adjust it. */
  overflow-anchor: none;
  /* M4M/O2a+b: THE GRID'S OUTER EDGE IS THE PAGE'S CONTENT EDGE. The
     tiles carry an 8px gutter each side (16 between neighbours), so the
     grid has to start exactly one gutter OUTSIDE the content box for the
     first card to land on it — and end one gutter outside on the right,
     for the last one. The old -15/+8 pair came from a Bootstrap row and
     matched neither edge: the grid box hung 15px past the content edge
     on the left and 7px on the right, while the cards themselves sat 1px
     inside at both ends. Cards now span the content box exactly, which
     is also the size increase — the row has 16px more to divide. */
  padding: 0;
  margin: 0 calc(var(--fs-grid-gutter) * -1);
  /* content-visibility on tiles + containment: memory/resize (PART C) */
  contain: layout style;
}
/* round 22 (D-027): the films content sits the SAME extracted 51.5px
   off the bar as the transfers table. The full 51.5 is set here: it
   COLLAPSES with the grid's own 18px internal margin (max wins). */
#content-films .fs-filterbar-section + .fs-container-fluid {
  margin-top: 51.5px;
}
.film-grid-title {
  flex: 0 0 100%;
  margin: 24px 0 16px;
  /* M4T/O8: THE HEADING STARTS WHERE THE COVERS START. It spans the grid
     full-width, and the grid hangs one tile gutter outside the content
     box on each side so that the CARDS land on it (M4M/O2) — so the
     heading and the rule above it inherited that overhang and ran 8px
     into the page margin at every band, while the covers under them were
     correct. Putting the gutter back here is the whole fix: the rule now
     begins on the cover's outer edge and ends on the content edge. */
  padding: 0 var(--fs-grid-gutter);
}
.film-grid-title-heading {
  font-size: 20px;
  padding: 16px 0 8px;
  border-top: 2px solid var(--color-line-strong);
  margin: 0;
}
/* Windowed grid (list round): the spacers that stand in for the rows
   outside the window. Full-width flex items, so the wrap pattern of the
   visible rows is exactly the wrap pattern of the full list. */
.film-grid-pad {
  flex: 0 0 100%;
}
.film-grid-offscreen {
  width: 100%;
}
.film-tile {
  width: 50%;
  padding: 0 var(--fs-grid-gutter);
  content-visibility: auto;
  contain-intrinsic-height: auto 420px;
}
@media (min-width: 600px) { .film-tile { width: 33.3333%; } }
@media (min-width: 800px) { .film-tile { width: 25%; } }
@media (min-width: 960px) { .film-tile { width: 20%; } }
@media (min-width: 1200px) { .film-tile { width: 16.6667%; } }
@media (min-width: 1500px) { .film-tile { width: 14.2857%; } }
@media (min-width: 1900px) { .film-tile { width: 12.5%; } }
@media (min-width: 2200px) { .film-tile { width: 11.1111%; } }
@media (min-width: 2500px) { .film-tile { width: 10%; } }
@media (min-width: 2800px) { .film-tile { width: 9.0909%; } }
@media (min-width: 3100px) { .film-tile { width: 8.3333%; } }
.film-card {
  position: relative;
  display: block;
  margin-bottom: 16px;
}
/* M4O: THE COVER'S FRAME IS THE COVER'S OUTER EDGE.
   There were two rings: this box carried 2px of --color-surface
   (#ffffff, invisible on a white page) and the image inside it carried
   2px of --color-line-strong (#d9d9d9), which is the grey frame a
   reader sees. So the box measured 32 — the page inset — while the
   first painted pixel was at 34, and the cover read as indented by 2px
   against the FILMS tab and the distributor pulldown. Sampled from the
   screenshot, not from the box: tab's first blue pixel at 32, cover's
   first grey pixel at 34.
   ONE ring now, the same grey, the same 2px, on the OUTER box — so the
   frame's outer edge is the cover's box edge and lands on the inset,
   and the image gains the 4px the second ring was taking. Nothing about
   the grid moves; the covers grow into the space they already owned.
   The frame is a BORDER on a border-box element, i.e. drawn inside the
   footprint: turning it blue on selection cannot move anything. */
.film-card-poster {
  position: relative;
  background-color: var(--color-text);
  border: var(--fs-cover-frame) solid var(--color-line-strong);
}
.film-card-poster img {
  width: 100%;
}
/* M4P: THE SELECTION BAND IS AS THICK AS IT EVER WAS, AND IT GROWS
   INWARD. Before M4O the cover had two rings and both turned blue, so
   the band measured 4px — but it started 2px OUTSIDE the cover's own
   visible edge, on the page-coloured ring, which is the overhang M4M
   objected to. Merging the rings put the edge right and left the band
   at 2px.
   An overlay carries the band now. It is absolutely positioned, so it
   is out of flow and can have no effect on the footprint whatever its
   width; `inset` pulls it out by the ring's width to reach the cover's
   OUTER edge, and its border grows from there inward — over the grey
   ring and the first pixels of the image, which is where Tom asked for
   it. Transparent when unselected, so the grey ring shows through
   unchanged. Not an outline (outlines are drawn outside), not a wider
   border on the poster (that would shrink the image on selection). */
.film-card-poster::after {
  content: '';
  position: absolute;
  inset: calc(var(--fs-cover-frame) * -1);
  border: var(--fs-cover-select) solid transparent;
  pointer-events: none;
  z-index: 1;
}
.film-card:hover .film-card-poster {
  border-color: var(--color-accent);
}
.film-card:hover .film-card-poster::after {
  border-color: var(--color-accent);
}
.film-card-poster .film-card-image {
  position: absolute;
  top: 0;
  left: 0;
}
.film-card-overlay {
  position: absolute;
  top: 0;
  height: 100%;
  width: 100%;
  text-align: center;
}
.film-card-overlay-title {
  position: absolute;
  width: 100%;
  padding: 32px 8px;
  color: var(--color-surface);
}
.film-card-overlay-logo {
  position: absolute;
  left: 20%;
  bottom: 32px;
  width: 60%;
  max-height: 64px;
  margin: 0 auto;
  opacity: 0.8;
}
.film-card-overlay-logo img {
  max-height: 64px;
  border: none;
  width: auto;
  max-width: 100%;
}
/* two-column text row under the poster (title left, count right) */
.film-card-text {
  float: left;
  margin-top: 8px;
  width: calc(100% - 30px);
  color: var(--color-text-heading);
  font-size: 14px;
  line-height: 21px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.film-card-text--wide-count {
  width: calc(100% - 60px);
}
.film-card-count {
  float: left;
  width: 30px;
  margin-top: 8px;
  text-align: right;
  color: var(--color-text-heading);
  font-size: 14px;
  line-height: 21px;
  white-space: nowrap;
  overflow: hidden;
}
.film-card-count--wide {
  width: 60px;
}
.film-card-updated {
  float: left;
  width: 100%;
  color: var(--color-accent);
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 700;
  line-height: 18px;
}

/* bootstrap-style row/column shims for the ported page grids */
.fs-row {
  display: flex;
  flex-wrap: wrap;
  margin-left: -15px;
  margin-right: -15px;
}
.fs-col {
  padding-left: 15px;
  padding-right: 15px;
  width: 100%;
}

.fs-btn--light {
  background-color: var(--color-surface-muted);
  color: var(--color-text-heading);
}
.fs-btn--light:hover {
  background-color: #e5e5e5;
}
/* bare button (legacy <a class="btn btn-light"> resolved to the base .btn:
   transparent, link-blue text — the film-row PLAY/SCREENER look) */
.fs-btn--bare {
  background-color: transparent;
  color: var(--color-accent);
}
.fs-btn--bare:hover {
  color: #0e6cab;
}

/* type helpers used on dark surfaces (ex display-5 / lead) */
.fs-display {
  font-size: 40px;
  font-weight: 300;
  line-height: 44px;
}
.fs-lead {
  font-size: 20px;
  font-weight: 300;
}
.fs-table thead {
  border-bottom: 4px solid var(--color-surface-muted);
}
.fs-table th {
  font-size: 0.875rem;
  text-transform: uppercase;
}
/* G.7: the transfer-profile matrix's count line under each profile name
   is data, not a heading — it keeps the header cell's position and loses
   the header cell's weight. */
.fs-table th.fs-th-count {
  font-weight: 400;
  text-transform: none;
}
.fs-table td {
  font-size: 0.875rem;
}
.fs-table td .fs-icon {
  margin-right: 0.5rem;
}
.fs-table td .fs-icon:last-child {
  margin-right: 0;
}

.fs-table .fs-table {
  margin-bottom: 0;
}
/* M4d/P1 — THE CHAIN, on this surface too. The collapse cell is the
   chevron column and is exactly the open chevron's ink; the icon cell is
   the box slot (--fs-checkbox-size, whatever mark it happens to hold).
   M4e/O1: the two gaps are no longer one number — the cell's LEAD is
   --fs-tree-gap-chevron (6, chevron -> box) and the gap after the box
   is --fs-checkrow-gap (10, box -> text). They were both 10 under M4d,
   which is why one token used to do both jobs. The old 40px columns and
   the 12px pl lead are gone — the page-edge inset is the only lead, and
   the numbers come from the same tokens the tree and the conversion
   rows read. */
.fs-table .ft-cell--collapse {
  width: var(--fs-chain-chevron);
  min-width: var(--fs-chain-chevron);
  padding-left: 0;
  padding-right: 0;
  padding-bottom: 1.4px;
}
/* M4e/O3a: the chevron's PAINT is not layout. The mark box is 12.56 in
   both states (CHEVRON_AXIS is the open mark's width, so the two states
   advance identically), but the glyph's paint seat is 17.91 and hangs
   out of it — and an auto table counts that overhang, which differs
   between the two states, when it sizes the column. The anchor states
   the column's width as a block, so the cell asks for exactly the mark
   in both states and expanding a row cannot renegotiate the columns.
   No overflow clipping: the paint must stay free to overshoot (it does,
   visibly, through the whole rotation). */
.fs-table .ft-cell--collapse > a {
  display: block;
  width: var(--fs-chain-chevron);
}
/* M4N/O1: the cells that span the spec row sit at the TOP of what they
   span — on the version line, which is where they belong and where they
   already were. */
.fs-table .ft-row--asset > .ft-cell--icon,
.fs-table .ft-row--asset > .ft-cell--spacer {
  vertical-align: top;
}
/* M4R/O2: and so does the actions cell. M4Q gave it `baseline`, which
   is a ONE-LINE-BAND idea — on mobile the cell spans the spec row and
   has to sit on the version line like the others. The baseline the
   controls share with the labels above 927 comes from the cell padding
   and the line-height below, not from this. */
.fs-table .ft-row--asset > .ft-cell--actions {
  vertical-align: top;
}
.fs-table .ft-cell--icon {
  /* M4d/P2: the slot is GAP + BOX, not a 34 that swallows its own gap.
     Border-box made `width: 34` mean "10 of padding and 24 of box", so
     the spec line and the CPL landed 27px left of the target names in
     the expanded block below, which read their chain as chevron + gap +
     box + gap. Same arithmetic on both now — one text edge. */
  width: calc(var(--fs-checkbox-size) + var(--fs-tree-gap-chevron));
  min-width: calc(var(--fs-checkbox-size) + var(--fs-tree-gap-chevron));
  padding-left: var(--fs-tree-gap-chevron);
  padding-right: 0;
}
.fs-table .ft-cell--icon-column {
  padding-left: 0;
}
/* beats `.fs-table td .fs-icon`'s margin-right by specificity —
   no !important needed (hygiene cleanup 2026-07-26) */
.fs-table td.ft-cell--icon-column .fs-icon {
  margin: 0;
}
.fs-table .ft-cell--actions {
  text-align: right;
  padding-top: 0.3rem;
}
/* M4Q/O2: THE CONTROLS ARE TYPESET LIKE THE ROW THEY SIT IN, and that is
   what puts their text on the labels' line.
   The label cells are the table's own: 14px type on a 21px line, 12px of
   cell padding above — so a label's text centre sits 22.5px below the
   cell's top. The controls were 12px on a 15px line inside a cell with
   4.8px of padding, which put their text 1.7px higher at every width;
   the eye reads that as the buttons floating above the run.
   Same type, same line, and the cell's padding is the table's own less
   the button's own (12 − 8): the control's text centre lands on 22.5 as
   well. One-line bands only — the mobile band shows marks, not labelled
   buttons (M4c/P9), and its controls keep their own box. */
@media (min-width: 927px) {
  /* M4R/O1: THE CONTROL KEEPS ITS OWN SIZE AND ITS OWN HEIGHT — both
     enlarging the type and stretching the line were the wrong lever and
     are reverted. The baseline is an ALIGNMENT question, and the answer
     is this cell's top padding, written as the difference between the
     two things being aligned:
        the label's text centre   = 12 (the table's cell padding)
                                  + 10.5 (half its 21px line)
        the control's text centre =  8 (the button's own padding)
                                  +  7.5 (half its 15px line)
     so the cell opens 12 + 10.5 − 8 − 7.5 = 7 above the control, and the
     two texts sit on one line at the control's own size. */
  .fs-table .ft-cell--actions {
    padding-top: 7px;
    /* M4R: AND THE CONTROLS ASK THE TABLE FOR NOTHING. Fixed labels plus
       captions that may not wrap means the row can want more than it
       has — and an auto table answers that by growing, which drags its
       right edge and everything anchored to it (the group heading's
       UPDATED line) by a different amount on each tab and in each
       language. A zero-width cell with the block positioned against the
       row's right edge takes the controls out of the negotiation
       altogether: the table is the labels, always exactly the content
       box, and the controls grow leftward into whatever is free. */
    position: relative;
    width: 0;
    padding-left: 0;
    padding-right: 0;
  }
  .ft-actions {
    position: absolute;
    top: 7px;
    right: var(--fs-row-inset);
  }
}
/* M4Q/O3: the controls line up FROM THE RIGHT and wrap when the row has
   no more room to give — so a longer caption grows the block leftward
   into free space and, when there is none, on to a second line. Either
   way it takes no width from the label columns, which carry their own
   floor. The gap is THE button gap (M4c/P11), stated rather than
   inherited from whatever whitespace the markup left. They do not wrap.
   M4R/O2: ONE-LINE BANDS ONLY. Mobile shows marks, not captions, and
   keeps the arrangement Tom accepted — a band's construct stays in its
   band. */
@media (min-width: 927px) {
  .ft-actions {
    display: flex;
    /* M4R: the controls never break across lines — a caption that does
       not fit takes the row's free width leftward, and when there is
       none the table is the thing that gives, not the button. */
    flex-wrap: nowrap;
    justify-content: flex-end;
    align-items: baseline;
    gap: var(--fs-button-gap);
  }
}
/* below the band the wrapper is not there at all: `display: contents`
   leaves the controls exactly the inline children of the cell they were
   before, which is the mobile arrangement Tom accepted in M4P. */
@media (max-width: 926px) {
  .ft-actions {
    display: contents;
  }
}
/* M4h/O3b: THE ROW'S RIGHT INSET — the same token as the left one, on
   every band. M4f landed the right-hand column flush ON the content
   edge; the rule now is that it stops one inset short of it, so a row
   is inset by the same 10 on both sides. They still share ONE edge —
   that edge moved in by 10. */
.fs-table td.ft-cell--actions,
.fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-cell--asset-detail,
.fd-assets .ft-body--asset-heading td[colspan],
.fd-assets .ft-body--asset-heading td:last-child {
  padding-right: var(--fs-row-inset);
}

/* M4h/O3a: THE ROW OPENS WITH ITS INSET, ON EVERY BAND. M4g put it on
   mobile only, on the reading that the large page inset supplies the air
   above 926 — Tom's ruling is that the 10 is a rule of its own and the
   page inset is a different thing it sits inside. The chain on every
   band is: content edge, THIS inset, the chevron column, the chain gap,
   the box, the box->text gap, content. Everything downstream (spec
   block, CPL filename, the expanded sub-rows) travels with it, because
   they all follow this column. */
.fd-assets .fs-table .ft-cell--collapse {
  width: calc(var(--fs-chain-chevron) + var(--fs-row-inset));
  min-width: calc(var(--fs-chain-chevron) + var(--fs-row-inset));
  padding-left: var(--fs-row-inset);
}

.ft-stack {
  width: 100%;
}
/* over-p95 CPLs (round 24, D-029): when the CPL column pushes the
   table past the container, the STACK scrolls horizontally — shared
   columns keep their positions, CPL renders in full. Desktop only:
   below X1 the cells are blocks. */
@media (min-width: 927px) {
  #content-transfers .ft-stack {
    overflow-x: auto;
  }
}
/* set-off between the filter bar and the content (round 22, D-027):
   ONE extracted constant on Films AND Transfers — legacyref shows
   51.5 on films (bar bottom -> first cover) and 42.4 on transfers
   (their export row -> table); per Tom the LARGER value applies to
   both. The margins differ per view because the internal lead-ins
   differ (inline 8px, stacked 16px) — the 51.5 VISUAL gap is what the
   sweep asserts. Supersedes round 5's 41px transfers extraction. */
#content-transfers .ft-stack {
  margin-top: 43.5px;
}
@media (max-width: 926px) {
  #content-transfers .ft-stack {
    margin-top: 35.5px;
  }
}
.fs-table .ft-body--asset-details td {
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
/* recipient rows: icon + date + name in one cell (see RecipientsTbody).
   The cell starts at the icon gutter (205, padding 0); the date sits a
   fixed 12px off the icon ink — D-007's approved tighter run. */
/* M4d/P1: a detail row is a row — it starts on the chain like every
   other, with the chevron column and its gap reserved even though a
   detail row has no chevron of its own. The conversion rows are
   excluded: their grid carries the whole chain itself. */
/* M4e/O3a: the surplus has ONE home — the spacer column. M4g/O3a
   corrects HOW: `width: 100%` did absorb the surplus, but it also made
   every other column fall back to its CONTENT width, so the spec
   columns silently stopped being fixed and drifted from film to film
   (measured: the language column 30 on one film, 29 on another). The
   spacer is simply the only column that asks for nothing, which makes
   it where the leftover lands; the expand-additive property comes from
   the three causes M4e/O3a actually fixed — the detail row's classed
   cell, the zero-width colspan cells, and this column existing at all. */
.fs-table .ft-cell--spacer {
  width: auto;
  /* M4Q: and NO PADDING. The spacer's whole job is to hold the row's
     leftover width; the table's generic cell padding on it was 16px the
     row could not give back, which at the narrow end of the tablet band
     was enough to push the table past the page — by a different amount
     on each tab, since each tab's controls are a different width. With
     the spacer weightless the table is exactly the content box on both,
     so everything that ends on its right edge — the controls and the
     group heading's UPDATED line — ends on ONE x. */
  padding: 0;
}
/* M4e/O3a: EXPANDING MUST ADD, NEVER MOVE.
   The inserted rows (the CPL title and the target block) carry wide
   colspan cells — a CPL filename, a column of e-mail addresses — and an
   AUTO table re-negotiates every column when the width demand changes.
   Measured on a cinema row: the collapse column went 12.55 -> 16 and
   every cell of every row slid 3.45px right, which is a "niemals
   springen" violation even though nothing about the chevron changed
   (the mark advances 12.56 in BOTH states — CHEVRON_AXIS is the open
   mark's width, so the glyph swap is layout-neutral by construction).
   Asking for zero width takes these cells out of the negotiation: they
   still render and still take the whole row, but the columns keep the
   widths the version rows gave them. */
.fs-table .ft-body--asset-details .ft-cell--asset-detail,
.fs-table .ft-row--asset-title td[colspan] {
  width: 0;
}
/* M4e/O3b: the target sub-rows (status icon | date | site | email) sit
   ON the chain, not indented beside it. This cell already FOLLOWS the
   collapse column (the row opens with an empty cell there), so its lead
   is the chevron gap alone — adding the chevron column again put the
   status icons a full column right of the box edge (measured 38.55
   against the chain's 26). Icon at the box column, and .ft-detail-icon
   (box + --fs-checkrow-gap) then puts the date on the content edge. */
.fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-cell--asset-detail {
  padding-left: var(--fs-tree-gap-chevron);
}
.fs-table .ft-body--asset-details tr.fd-conversion-row .ft-cell--asset-detail {
  padding-left: 0;
}
.ft-detail-icon {
  /* M4d/P1: the BOX SLOT again — a status mark sits in the same 34 a
     checkbox would, so the text after it lands on the chain's content
     edge like everything else. */
  display: inline-block;
  width: var(--fs-checkbox-size);
  margin-right: var(--fs-checkrow-gap);
}
/* the version block's icon column = the tree's column arithmetic:
   cell width = widest mark (marks center on the axis, so the widest
   mark's edges ARE the column edges), and the FOLLOWING cell carries
   GAP_ICON as its padding — one gap definition, shared with the
   deliver tree (horizontal-unification round; supersedes D-034's
   24px column + 8px lead). Scoped by the film page's .fd-assets
   wrapper: the column contains icon cells WITHOUT the transfer-icon
   class too, and any of them at 2.5rem would pin the auto-layout
   column back at 40. */
/* M4d/P1: this column is THE BOX SLOT of the chain — gap + box — not
   the mark's own width. A 17px mark and a 34px checkbox occupy the same
   slot, which is what makes the spec line, the CPL and the target names
   below share one text edge (P2). The following cell carries the
   trailing gap. */
.fd-assets .fs-table .ft-cell--icon {
  width: calc(var(--fs-tree-gap-chevron) + var(--fs-checkbox-size));
  min-width: calc(var(--fs-tree-gap-chevron) + var(--fs-checkbox-size));
  padding-left: var(--fs-tree-gap-chevron);
}
.fd-assets .fs-table td.ft-cell--icon + td {
  padding-left: var(--fs-checkrow-gap);
}
/* group headings: the heading ink starts flush with the icon column's
   mark-left edge (= the heading cell's own left edge — both sit at
   the collapse column's right edge). Layout-level flush, no indent. */
/* M4e/O2: the group title ("Trailer A") stands on the chain like every
   other row: chevron column, THE chevron gap, then the title. It was
   flush against the chevron (measured gap 0) because this cell zeroed
   its lead to sit on the icon column's mark edge — that was the M4d
   reading of "no indent", and it read as glued. Collapsed and expanded
   alike: the heading row is the same row in both states. */
.fd-assets .ft-body--asset-heading td[colspan] {
  padding-left: var(--fs-tree-gap-chevron);
}
.fd-assets .ft-heading {
  padding-left: 0;
}
/* M4h/O2: A FILENAME WRAPS AS FAR AS IT NEEDS TO. These are single
   unbroken tokens, so a rule that only breaks at separators cannot help
   them: `anywhere` lets the break fall inside the token, and there is no
   line limit and no ellipsis — the row grows downward instead of the
   name running off to the right. Same rule wherever a CPL renders. */
.fs-table .ft-row--asset-title td,
.fs-table .ft-cell--transfer-cpl,
.fs-table .ft-cell--transfer-playlists,
.dt-cpl-entry,
.fd-conversion-name,
/* an address is the same shape of problem as a filename: one long token
   with nowhere to break, running off the right at 360 */
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-email {
  overflow-wrap: anywhere;
  word-break: normal;
  max-width: 100%;
}
/* production row rhythm on the film-detail asset table (per-element audit
   2026-07-14): version rows close with 1.4px; the filename row hugs the
   version row (1.6px top) and carries the 8px gap to the next entry */
.fs-table .ft-row--asset td {
  padding-bottom: 1.4px;
}
.fs-table .ft-row--asset-title td {
  padding-top: 1.6px;
  padding-bottom: 8px;
}
/* O4/O5 (M4b): the playlist header's text is NEVER shrunk. A
   `font-size: 0.8rem` below 991px used to live here — that was the
   "murksy" middle state: between 927 and 991 the header came out
   smaller AND the one-line cells had already been swapped for the
   stacked value-box. There are exactly three representations now and
   the type is the same size in all of them; on mobile the header wraps
   instead of shrinking. */
.fs-table .ft-cell--asset-info {
  padding-bottom: 0;
  padding-right: 0;
  font-weight: 500;
  white-space: nowrap;
}
/* O4: the switch is the REGISTERED breakpoint (md 927), not the legacy
   991 — that eight-pixel-wide band was the only place a third layout
   existed. Tablet (927..1585) keeps the one-line desktop cells. */
@media (max-width: 926px) {
  /* M4i/O1: the one-line cells are EMPTIED on mobile, not removed. A
     `display: none` cell is gone from the table's column structure, and
     the spec row's block spans those columns — with them absent the
     block's cell landed after the action controls instead of before
     them. Zero width, no padding, nothing painted: the columns exist
     for the arithmetic and take up nothing. */
  .fs-table .ft-cell--asset-info {
    width: 0;
    max-width: 0;
    padding: 0;
    font-size: 0;
    /* and no LINE BOX: with the inherited 21px each of these cells held
       the version row 24.39px tall, which is the distance the block's
       first line was sitting below the mark. */
    line-height: 0;
    overflow: hidden;
    white-space: nowrap;
  }
  /* the row's own 1.4px bottom rhythm is for cells that RENDER; on these
     it was the last 3.39px holding the version row open. */
  .fs-table .ft-row--asset > td.ft-cell--asset-info {
    padding-bottom: 0;
  }
}
/* M4i/O1 + O4a: THE SPEC ROW IS ALWAYS THERE, and above the mobile band
   it is EMPTY rather than absent.
   M4h switched the row itself with `display: none`, which meant the
   table had three rows per version on mobile and two above it — and the
   chevron's rowSpan is one number for both. A hidden row is supposed to
   drop out of the span, and it does not do so dependably: on desktop the
   span reached into the NEXT version row, whose cells then started one
   column late — the second row of a group sitting further right than the
   first, its DELIVER button outside the grey block. That is O4a.
   With the row always present the row count is constant, so every span
   is exact at every band. Above 926 the block inside it is hidden and
   the cell carries no padding, so the row is zero high and nothing on
   those bands changes. */
/* M4N/O1: THE LABEL MOVES UP ONTO THE VERSION LINE — the version line
   does not move. Two things held it down. The emptied one-line cells
   still carried a 21px line box each, so the version row measured 24.39
   tall and the block began below it; and this cell had its padding
   zeroed, so even with the row collapsed the block would have started
   12px above the mark rather than beside it.
   Both now read the table's OWN cell padding (kit.css: .fs-table td =
   12px 8px): the version row's cells start 12px down, and so does the
   block's first line, which puts them on one line with no second
   number to keep in step. Above the mobile band the row is empty and
   flat, so its top padding goes. */
.ft-row--asset-specs > td {
  padding-bottom: 0;
}
@media (min-width: 927px) {
  .ft-row--asset-specs > td {
    padding-top: 0;
  }
}
@media (min-width: 927px) {
  .ft-row--asset-specs .value-box {
    display: none;
  }
}
@media (max-width: 926px) {
  .fs-table .ft-cell--asset-info--xs {
    font-weight: 500;
    padding-bottom: 0;
    /* M4c/P10: the value-box's first column starts on the PLAYLIST
       HEADER's text edge — one token, one edge.
       M4h/O1: the block is its OWN row now and opens at the chevron
       column's right edge (the chevron spans all three rows), so the
       lead is the rest of the chain: the chain gap, the box, the
       box->text gap. Same content edge, stated from where it now
       starts. */
    /* M4i/O1: the block's cell begins at the icon column's right edge
       now (the icon spans into this row), so the lead is the last link
       of the chain alone — the box->text gap. Same content edge. */
    padding-left: var(--fs-checkrow-gap);
  }
  /* M4d/P6: THE SECOND SPEC COLUMN DOES NOT MOVE ("xx soll nicht
     springen"). The stacked box was a flex row of PERCENTAGES
     (33.33 / 66.67) of a cell whose width is whatever the ACTIONS
     column leaves over — and that column is content-sized, so it
     differs per tab and per film. Measured on /films/4787 at 390px:
     the subtitles item ("XX") sat at 115.31 on theatrical and 140.31
     on homevideo; on /films/1225 both sat at 128.2. Three surfaces,
     three x's, for one column.

     Two fixed columns from the SAME tokens the one-line cells use, so
     the stacked box and the desktop table put language and subtitles
     on the same edge, on every tab, every film and every mobile width.
     Grid rather than flex with fixed widths: flex-wrap would fit a
     third item on a line as soon as the cell is wide enough, and the
     two-per-row reading is the layout. `order` still drives placement
     (1,1,1,1 / 2 / 3 -> language+subtitles, format+aspect, audio+date),
     which is the arrangement the percentages produced. */
  /* M4e/O7: THREE columns, TWO rows — there is width for it on mobile
     and the block reads better short.
         language | subtitles | aspect
         format   | audio     | duration
     The column widths are the same two tokens the one-line cells use
     (48 / 48 / 96): the narrow pair carries codes ("DE", "XX", "2D",
     "5.1"), the wide one the two long values ("Scope 2.39",
     "01:42:18:22" — measured 80 and 83 natural). `order` drives the
     placement, so an absent value leaves its cell empty and nothing
     reflows. Identical on both tabs and across films (P6's rule). */
  .ft-cell--asset-info--xs .value-box {
    display: grid;
    /* M4g/O3b: the three SLOTS, with the gap stated as a gap instead of
       hidden inside the column widths — the two rows then share one set
       of column edges by construction and the air between them is one
       number rather than whatever each value happened to leave over. */
    grid-template-columns: var(--fs-spec-col-1) var(--fs-spec-col-2) var(--fs-spec-col-3);
    column-gap: var(--fs-spec-gap-mobile);
    justify-content: start;
  }
  /* the block is the last column before the action controls, and the
     row has to fit the page: no trailing padding to spend. */
  .ft-cell--asset-info--xs {
    padding-right: 0;
  }
  .ft-cell--asset-info--xs .value-box .vb-item {
    width: auto;
  }
  .ft-cell--asset-info--xs .value-box .value-box-item--language { order: 1; }
  .ft-cell--asset-info--xs .value-box .value-box-item--subtitles { order: 2; }
  .ft-cell--asset-info--xs .value-box .value-box-item--aspect { order: 3; }
  .ft-cell--asset-info--xs .value-box .value-box-item--format { order: 4; }
  .ft-cell--asset-info--xs .value-box .value-box-item--audio { order: 5; }
  /* M4f/O5: row 2 / column 3 is the DURATION. The end-credit time is
     not shown on mobile at all — no cell and no fallback position, so
     an absent duration leaves the cell empty rather than borrowing a
     different field's value. */
  .ft-cell--asset-info--xs .value-box .value-box-item--time {
    display: block;
    order: 6;
  }
  .ft-cell--asset-info--xs .value-box .value-box-item--date {
    display: none;
  }
}
.fs-table .ft-body--asset-details {
  display: table-row-group !important;
}
.fs-table .ft-body--asset-details .ft-row--asset-detail:last-child td {
  padding-bottom: 0.75rem;
}
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-date {
  display: inline-block;
  width: 8rem;
  border-right: 1px solid var(--color-line-strong);
  padding-right: var(--fs-detail-divider-gap);
  white-space: nowrap;
}
/* M4T/O1: THE GAP AFTER THE DIVIDER IS THE DIVIDER'S, not the
   organisation's. Whatever follows the date starts the same distance
   from the rule — an organisation where there is one, the address where
   there is not. The gap used to hang on .ft-detail-name, so a web
   download (which has no organisation and therefore no name element at
   all, M4b/O8) rendered "date |address" with the address glued to the
   line. Selecting the date's NEXT SIBLING states the relation itself, so
   neither case can be forgotten. */
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-date + * {
  padding-left: var(--fs-detail-divider-gap);
}
@media (max-width: 926px) {
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-cell--asset-detail .ft-detail-date {
    border-right: 0;
  }
}
/* M4g/O6b: no trailing padding — the address follows by ONE word-space
   and the space is in the markup. The leading padding stays: that is
   the organisation's distance from the DATE, a different relation. */
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-name {
  display: inline;
  width: auto;
}
@media (max-width: 926px) {
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-cell--asset-detail .ft-detail-name {
    padding-left: 0;
    padding-right: 0;
    display: inline-block;
  }
}

/* ── M4/N3a: THE CINEMA-TAB RECIPIENT ROW ────────────────────────────
   The site name and the address are their own elements. O1 removed the
   truncation the first pass gave them: this tab always has room, so
   both render whole.

   Desktop and tablet keep the parts on one line. Mobile stacks them,
   following the /transfers mobile card: the first line carries the
   status mark, the SITE NAME and the x; the date goes under it, then
   the address — never beside the name, never wrapped around it. */
/* O1 (M4b): NO TRUNCATION here — there is always room on this tab, so
   the site name and the address render whole. The max-widths and the
   ellipsis the previous round added are gone, at every width. */
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-name,
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-email {
  display: inline-block;
  vertical-align: bottom;
  white-space: nowrap;
}
@media (max-width: 926px) {
  /* M4h/O2: on the stacked card the address gets its own line and has to
     be allowed to use more than one — nothing runs out to the right. */
  .fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-email {
    white-space: normal;
  }
}
/* M4g/O6b: the address follows the organisation by ONE WORD-SPACE, the
   same running-text treatment the x already has (M4c/P5) — the space is
   a real space node in the markup, so this rule adds no lead of its
   own. It was a 0.5rem column-style gap, which read as a third column
   on a line that is a sentence. */
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-email {
  color: var(--color-text);
}
/* M4c/P5: the x is the LAST WORD of the email line — one word-space
   after the address, inline. No offset token: the space is a real space
   in the markup. (Mobile keeps the x right-aligned on the first line;
   see the stack block below — Tom's explicit exception.) */
.fs-table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-actions {
  white-space: nowrap;
}

@media (max-width: 926px) {
  /* the stack. The cell becomes a two-column grid so the x can sit on
     the first line, right-aligned, while everything else runs down a
     single left-aligned column under the site name. */
  /* NOT the conversion rows: they share this cell class and bring
     their own mobile stack (kit-film.css). Without the :not() the
     grid below collapsed a conversion row to 72px. */
  /* M4f/O3: THE CHAIN, on mobile too. The stack's first column was the
     17px status-mark column, so the name, the date and the e-mail began
     27px into the cell while the spec block and the CPL filename above
     them begin on the chain's content edge (measured 45.55 against
     62.55). The column is the BOX column now — the mark sits under the
     version row's mark — and every line starts one box-plus-gap after
     it, which is that same content edge. */
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack {
    display: grid;
    grid-template-columns: var(--fs-checkbox-size) 1fr auto;
    align-items: baseline;
    row-gap: 2px;
  }
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack .ft-detail-icon {
    grid-column: 1;
    grid-row: 1;
  }
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack .ft-detail-name {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
    max-width: none;
    padding-left: var(--fs-checkrow-gap);
  }
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack .ft-detail-actions {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
  }
  /* M4g/O6a: a WEB DOWNLOAD has no organisation, and the stack must
     lose that LINE rather than render it blank. The first line is the
     one beside the status mark; with no organisation to put there the
     DATE takes it, on the same edge the organisation would have used,
     and the address follows on the next line. Same principle as the
     sealed transfers rule for web downloads. */
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack--no-org .ft-detail-date {
    grid-column: 2;
    grid-row: 1;
    padding-left: var(--fs-checkrow-gap);
  }
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack .ft-detail-date,
  .fs-table .ft-body--asset-details tr:not(.fd-conversion-row) .ft-detail-stack .ft-detail-email {
    grid-column: 1 / -1;
    min-width: 0;
    max-width: none;
    width: auto;
    /* under the SITE NAME's text: the BOX column plus THE icon-to-text
       gap, the same construction the deliver tree's stacked lines use
       (M4f/O3 — it was the 17px mark column, which is not the chain) */
    padding-left: calc(var(--fs-checkbox-size) + var(--fs-checkrow-gap));
    padding-right: 0;
  }
}

td.ft-cell--actions {
  padding-bottom: 0;
}
td.ft-cell--actions .fs-btn {
  margin-bottom: 0;
}
td.ft-cell--actions .fs-btn:last-child {
  margin-bottom: 0;
}
/* M4c/P9: THE WHOLE MOBILE BAND shows the small icons — play, screener,
   deliver — with no labels and no large DELIVER button. The rule used to
   start at an unregistered 543, so between 544 and the md edge the row
   still rendered text buttons: a third treatment inside the mobile band.
   It is the registered breakpoint now, like everything else. */
@media (max-width: 926px) {
  td.ft-cell--actions .fs-icon {
    padding: 0;
    margin: 0;
  }
  td.ft-cell--actions span {
    display: none;
  }
  /* and they sit at the row's right edge, the way delivery mobile puts
     its marks */
  td.ft-cell--actions {
    text-align: right;
    white-space: nowrap;
  }
/* M4f/O4: ONE RIGHT EDGE, and it is the page's content edge — the
     same number delivery mobile's marks land on (measured 360 at a
     390 window). Two things were in the way: the table did not fit the
     page (404.63 wide in a 345 content box, so its right edge was off
     screen and everything "right-aligned" was right-aligned to that),
     and the cells that carry the right-hand content each held 8px of
     generic padding inside it. Zeroing the padding on the three
     right-hand cells sheds exactly the width the table was over by, so
     the table fits, its right edge IS the content edge, and the UPDATED
     line, the PLAY/ORDER pair, the small action marks and the x on the
     sub-rows all end on it. The pair keeps --fs-button-gap and icon
     pairs keep GAP_ICON: only the cell padding goes. */
  .fs-table .ft-cell--spacer {
    padding-left: 0;
    padding-right: 0;
  }
  td.ft-cell--actions {
    padding-left: 0;
  }
  /* M4g/O1: A BUTTON KEEPS ITS BOX. M4f took the horizontal padding
     off every control here to buy the width the table was short of,
     which left the deliver control as a clipped blue sliver — the
     filled square needs its padding to BE a square. Only the BARE
     variant loses it, and only because a bare link has no box by
     definition: the play triangle is a mark, the cart is a button.
     The width M4f was after comes from the spec columns' own budget
     instead (O3b). */
  td.ft-cell--actions .fs-btn--bare {
    padding-left: 0;
    padding-right: 0;
  }
  td.ft-cell--actions .fs-btn + .fs-btn {
    margin-left: var(--fs-gap-icon);
  }
  .fd-assets .ft-body--asset-heading td:last-child {
    padding-right: var(--fs-row-inset);
  }
  /* the group heading is the last cell that was sizing the table: its
     title and its UPDATED line share one line, so the cell asked for
     both widths at once (measured 392 of a 345 content box). On mobile
     the date takes its own line under the title — where it is also the
     only thing that can carry the right edge — and the cell stops
     dictating the columns, the same treatment the other colspan cells
     got in M4e/O3a. */
  .fd-assets .ft-body--asset-heading td[colspan] {
    width: 0;
  }
  .fd-assets .ft-body--asset-heading .film-updated {
    display: block;
    text-align: right;
  }
}

/* chevron rotation lives in the ONE .mk-chevron definition
   (kit-forms.css) — the local .ft-cell--collapse rules this replaced
   were the extraction source (all 0.5s). */

.ft-body--assetgroup {
  background-color: var(--color-surface-muted);
}
.ft-body--assetgroup .ft-row--asset-title:not(:last-child) td {
  padding-bottom: 0;
}
.ft-body--assetgroup + .ft-body--asset.ft-body--assetgroup {
  border-top: 4px solid var(--color-surface);
}

.ft-body--asset-heading td {
  border-bottom: 4px solid var(--color-surface-muted);
  /* 1.4px bottom = production's asset-row rhythm on the heading row
     too (collapsed group pitch 64, extracted film 2660) */
  padding: 2rem 0 1.4px 0;
}
.ft-body--asset-heading td:last-child {
  padding-right: 0.5rem;
}
.ft-body--asset-heading:first-child td {
  padding-top: 0;
}

/* THE LIST TABLE (D-111 part 4): what the transfers rows and the
   issued-screeners rows SHARE, in one place — cell padding, alignment,
   the no-wrap hard rule and the row separators. Both tables carry
   .fs-table--list beside their own class; their own class carries ONLY
   column widths and layout switches. The style-parity gate compares a
   live row of each against the other. */
.fs-table--list td {
  /* round 6: PRODUCTION GENEROSITY — the reference's extracted 5.6px on
     all sides (round 5's 2px bottom is rolled back; cramped reads
     petty, production reads calm) */
  padding: 0.35rem 0.5rem;
  /* reference: all cells top-aligned */
  vertical-align: top;
  /* HARD RULE (round 9): no cell ever wraps — a second text line inside
     any cell is impossible by construction, in every layout. Overlong
     content ellipsizes (per-cell overflow rules). */
  white-space: nowrap;
}
/* A ROW THAT OPENS ITS FILM SAYS SO (D-181).

   The click was added in D-180 and the cursor stayed the default arrow,
   so nothing on screen said the row was clickable. The hand goes where
   the behaviour is — on the row itself, not on the table — which is why
   this is its own class rather than a rule on .ft-list-row: the mobile
   transfers row carries the handler without carrying that class, and a
   list row somewhere else must not grow a promise it cannot keep.

   THE HAND MEANS "THIS OPENS THE FILM", so anything that answers the
   click ITSELF must not wear it. A value cell filters, a version link
   opens the grant page, an input takes text — the same hand on those
   would be telling the reader the film page is one click away when it is
   not. They take the plain arrow instead.
   
   THE SELECTOR MIRRORS lib/rowOpensFilm's OWN_CONTROLS, which is the
   list the click itself stands aside for; source-checks holds the two
   together, because a control added to one and not the other would draw
   a hand that lies or refuse a click that should land. */
.ft-row--opens-film {
  cursor: pointer;
}
.ft-row--opens-film :is(a, button, input, select, textarea, label, [role='button'], [data-no-row-open]) {
  cursor: default;
}

/* ONE separator rule for every list row: 2px between desktop rows, the
   heavier 4px between the stacked mobile cards — exactly what the
   transfers list has always drawn (its own mobile rule keeps the same
   value; this one is what the screeners cards ride). */
.ft-list-row {
  border-top: 2px solid var(--color-surface-muted);
}
.ft-list-row:first-child {
  border-top: none;
}
@media (max-width: 926px) {
  .ft-list-row {
    border-top: 4px solid var(--color-surface-muted);
  }
  .ft-list-row:first-child {
    border-top: none;
  }
}
/* reference rows are 36.2px tall (extracted; 5.6 + 25px icon line box
   + 5.6). Our icon line collapsed shorter, so the status cell pins the
   row's minimum height directly (round 6, production generosity). */
.ft-cell--transfer-status {
  height: 36.2px;
}
/* M4d/P1, judgement item: the STATUS COLUMN is the chain's (chevron +
   gap + box, derived above instead of the old hand-set 58). The chain's
   TRAILING gap is deliberately NOT forced here — the cell after status
   is a date column carrying a sealed 2px lead from the transfers column
   derivation (D-014/D-015), whose promise is that no data change ever
   moves a column edge. Overriding it would move every date column on
   the page. Transfers' content edge therefore sits ~8px tighter than
   the film surfaces'; flagged for Tom rather than resolved here. */
/* Layout stabilization: fixed table layout with explicit column widths on
   the header cells, so no data change (progress ticking, live prepends,
   cursor pages) can move a column edge. Desktop only — below 768px the
   cells switch to display:block (see kit-port.css) and fixed layout would
   fight that. Content-measured widths (parity/elements/transfers-*.json):
   Round 2 (Tom): Progress reserves exactly "100% 226 Mbit/s" = 118px,
   dates exactly "23.12.2026 14:34" = 119px, User/Site their real data
   maxima (widest email 270px, widest site 244px over the full clone
   dataset), all + 16px cell padding; a live value beyond the reserve
   ellipsizes rather than moving the column. */
@media (min-width: 927px) {
  .fs-table--transfer {
    /* round 25 FLUID model (D-030, REVERSES D-029's no-spread — that
       spec originated in review, not from the user): the table ALWAYS
       spans 100% of the content width, columns compressed to their
       content minima under pressure, surplus distributed natively by
       the fixed-layout algorithm (proportional to the specified
       minima — production's auto-layout character, kept on FIXED
       layout so virtualized rows can't move edges and the User/Site
       ellipsis reservations hold). Shared minima sum = 874. */
    table-layout: fixed;
    width: 100%;
  }
  /* DESIGN PASS 2 (unsealed): FIXED experience-based minima from the
     user — 58/120/4x80/200/150 (+CPL 620), sum 848; switches static:
     table->stacked 927 (848+79), CPL column 1547 (848+620+79).
     Surplus becomes an EQUAL EXTRA GAP between all columns: each
     column except the last carries + (100vw - switch)/gaps on its
     trailing edge (contents stay at minima, left-aligned), so the
     page relaxes uniformly; the sum stays exactly 100%. */
  /* DESIGN PASS 3 (unsealed): WEIGHTED surplus — status 0 (never
     grows, nor its trailing gap), progress/dates 1 each ("nur ein
     bisschen luftiger"), user/site 5 each, cpl 6. Tail total /15,
     CPL layout /21. Exact fractions inside calc keep the sum at
     100%. */
  /* M4d/P1: the chain, on a surface with no chevron — the column still
     reserves the chevron and its gap, then the box slot, so the content
     edge lands where it lands on the film pages. Was a hand-set 58. */
  .ft-heading--transfer-status {
    width: calc(
      var(--fs-chain-chevron) + var(--fs-tree-gap-chevron) +
        var(--fs-checkbox-size)
    );
  }
  .ft-heading--transfer-progress {
    /* round 19: 4px lead-in + the widest possible "NNN% NNN Mbit/s"
       shape ("100% 800 Mbit/s" = 117px, brute-forced over all 3-digit
       speeds at the cell font) + 2px right (round 25 near-zero gap);
       rare wider mid-tick values ellipsize (stability rule intact). */
    width: calc(120px + (100vw - 927px) * 1 / 11);
  }
  .ft-heading--transfer-progress--compact {
    width: 6rem;
  }
  .ft-heading--transfer-date {
    /* round 18 squeeze: the requested "12.12. 12:23" measures 69px,
       but real same-shaped values reach 84px ("20.10. 20:00", on
       screen in the December fixtures — zeros render wide); shipping
       81px would wrap/clip them, so the honest minimum is 84 + 2x6px
       gaps = 96; round 25 shrinks the sides to 2px ("NULL Abstand"
       target; 4px keeps adjacent dates legible): 88.

       D-121 U3, MEASURED (not estimated) in this table's own register:
       the per-digit advances are 0:10 8:10 2/3/4/6/9:9 5/7:8 1:4, and
       the formatter does NOT pad day, month or hour
       (lib/format#formatDateTimeShortYear), so the widest shape that
       can ever render is "20.10.00 20:00" = 104px, measured as one
       string. Real data reaches only 92px ("20.8.26 16:38"), which is
       why 106 looked safe and was not: the honest floor is
       104 + the table's own 2+2px sides = 108.

       AND IT IS FIXED. The date columns take NO share of the surplus:
       a column that grows past its text puts air between dates and
       nothing else (measured: 124 at 1920, 154 at 2560, against 104 of
       ink). Their four weights leave the denominator — /15 becomes /11
       and /21 becomes /17 — so the freed slope goes back to the columns
       that paid for the year, User and Site, rather than to whichever
       column happens to expand. */
    width: 108px;
  }
  /* USER AND SITE ARE ONE WIDTH, BY CONSTRUCTION (D-121 U3, the
     owner's third correction — "they cannot have separate widths in the
     CSS at all").
     
     ONE RULE, BOTH SELECTORS, and the base is a token. There is no
     second number to drift: changing the token moves both columns, and
     nothing here can move one without the other. Two rules carrying the
     same figure would not be this — the next person changes one.

     THE NUMBER. The pair held 200 + 150 = 350 before the year. The year
     costs 4 x (108 - 80) = 112px on the date columns, the table sums
     exactly to the pane's content width, and CPL pays nothing by
     ruling — so the pair holds 238, and half of that is 119.

     WHAT IT COSTS, measured at 1547 over 40 rows of clone data
     (truncated cells, User / Site):

         146 / 100  (before)      27 / 10
         146 /  92                27 / 10
         134 / 104                34 / 10
         119 / 119  (landed)      39 /  8

     Equal pixels are not equal damage: Site names cluster short with a
     long tail no width in this budget rescues (between 92 and 119 only
     two cells cross), while User is a wall of e-mail addresses sitting
     just over the width, so every pixel there crosses several. The
     owner has seen these numbers and ruled for equal widths regardless:
     the two columns reading as one pair outranks the count. Both
     ellipsize, as they always have. */
  .ft-heading--transfer-user,
  .ft-heading--transfer-site {
    width: calc(var(--fs-transfer-people-col) + (100vw - 927px) * 5 / 11);
  }
}
/* CPL column <-> tail row is RUNTIME-MEASURED (round 25, D-030 —
   supersedes the static 1646 constant): TransfersPage compares the
   available content width against 874 + widest LOADED CPL + 4 (D-020
   header-collapse pattern) and sets .ft-stack--cpl-column. The CPL
   minimum is the widest actually-loaded CPL (NOT p95); --cpl-col
   carries it as the column's specified width, so the fluid table
   compresses to it and distributes any surplus natively. CPL never
   truncates: below the fit the tail row takes over. */
@media (min-width: 927px) and (max-width: 1546px) {
  .ft-heading--transfer-cpl--lg,
  .ft-cell--transfer-cpl--lg {
    display: none;
  }
  /* .fs-table--transfer prefix: must beat the LATER base
     .ft-row--transfer--sm { display: none } at any rule order */
  .fs-table--transfer .ft-row--transfer--sm {
    display: table-row;
  }
  .ft-cell--transfer-cpl--sm {
    display: table-cell !important;
    padding-top: 0 !important;
    /* the tail's LEAD lives with its rule in kit-port (M4g/O5) — it is
       the progress column's lead, read from the token, not a second
       copy of the number here. */
  }
}
@media (min-width: 1547px) {
  /* weighted /17 once CPL is a column: (0,1,5,5,6) over progress,
     user, site and CPL. The four date columns are FIXED and take no
     share (see .ft-heading--transfer-date), which is what took them
     0,1,1,1,1,1,5,5,6 = /21 down to /17. */
  .ft-heading--transfer-status {
    width: calc(
      var(--fs-chain-chevron) + var(--fs-tree-gap-chevron) +
        var(--fs-checkbox-size)
    );
  }
  .ft-heading--transfer-progress { width: calc(120px + (100vw - 1547px) * 1 / 17); }
  /* the same ONE rule for both, at this breakpoint too */
  .ft-heading--transfer-user,
  .ft-heading--transfer-site {
    width: calc(var(--fs-transfer-people-col) + (100vw - 1547px) * 5 / 17);
  }
  .ft-heading--transfer-cpl--lg { width: calc(620px + (100vw - 1547px) * 6 / 17); }
  .fs-table--transfer .ft-row--transfer--sm { display: none; }
}

/* round 25 (D-030): NEAR-ZERO separation — 2px sides = 4px between
   adjacent contents at full compression ("NULL Abstand"; literal 0
   merges adjacent dates, 4px ~ one space glyph keeps them distinct).
   Surplus width flows back into the columns via the fluid table. */
.fs-table--transfer td.ft-cell--transfer-ordered,
.fs-table--transfer td.ft-cell--transfer-started,
.fs-table--transfer td.ft-cell--transfer-completion,
.fs-table--transfer td.ft-cell--transfer-duedate,
.fs-table--transfer th.ft-heading--transfer-date {
  padding-left: 2px;
  padding-right: 2px;
}
/* the new 6px sides are TABLE-layout only — the stacked view keeps its
   flush left edge (round 12) */
@media (min-width: 927px) {
  .fs-table--transfer td.ft-cell--transfer-user,
  .fs-table--transfer td.ft-cell--transfer-user-info,
  .fs-table--transfer td.ft-cell--transfer-cpl,
  .fs-table--transfer th {
    padding-left: 2px;
    padding-right: 2px;
  }
}
/* M4d/P1: THE CHAIN'S TRAILING GAP, on transfers too. The status column
   already reserves chevron + gap + box (56.56), but the cell after it
   took the transfers-wide 2px column lead, so content began at 58.59
   while every film surface begins at 66.55 — the chain was complete
   except for its last gap. D-030's 2px is a SEPARATION rule between
   adjacent data columns (so two dates stay distinct at full
   compression); it is not the icon->text gap, and only the one cell
   that closes the chain is taken off it. Consequence, flagged in the
   round report: the columns after the status column sit ~8px further
   right than before. Nothing moves with DATA, which is what D-014/D-015
   pinned. */
/* M4e/O8a: TABLE layout only. On mobile the row is a stacked card with
   one left edge for every line, and this lead pushed the "100% <speed>"
   line 10px in from the dates, email and filename under it (measured 25
   against their 15). */
@media (min-width: 927px) {
  .fs-table--transfer td.ft-cell--transfer-status + td,
  .fs-table--transfer th.ft-heading--transfer-status + th {
    padding-left: var(--fs-checkrow-gap);
  }
}
/* in the column layout the CPL never wraps mid-column */
.ft-cell--transfer-cpl--lg {
  /* CPL KEEPS ITS WIDTH AND DOES NOT TRUNCATE (D-121 U3, the owner's
     correction — this round briefly cut it 620 -> 516 and it is given
     back). The CPL name is what a person reads to identify the row, and
     it is the one column whose TAIL carries meaning: the SMPTE/IOP and
     OV/FM suffixes sit at the end, so an ellipsis there removes exactly
     the part being looked for. The year is funded by Site and User
     instead, which already ellipsize. */
  white-space: nowrap;
  overflow: visible;
}
.ft-cell--transfer-cpl--lg a {
  white-space: nowrap;
}
/* Reference status-cell anatomy: both icon anchors are fa-fw slots
   (1.28571em at 20px = 25.71px), glyphs centered — that spacing is the
   visual gap between the status and type icons. */
.ft-cell--transfer-status .transfer-icon,
.ft-cell--transfer-status .transfer-type-icon {
  display: inline-block;
  width: 25.71px;
  text-align: center;
}
.ft-cell--transfer-status .transfer-icon .fs-icon,
.ft-cell--transfer-status .transfer-type-icon .fs-icon {
  margin-right: 0;
}
.ft-row--transfer--sm {
  border-top: none;
  /* hidden as a ROW by default: its empty first td used to render a
     phantom ~8px strip between the data row and the divider whenever
     the stacked layout was off — the actual source of the too-large
     CPL bottom gap (round 5). The stacked-layout media queries below
     and in kit-port.css re-enable it. */
  display: none;
}
.ft-row--transfer + .ft-row--transfer-group {
  border-top: none;
}
.ft-row--transfer-group + .ft-row--transfer-group {
  border-top: 4px solid var(--color-surface) !important;
}
.ft-row--transfer-group + .ft-row--transfer-group.ft-row--transfer--sm {
  border-top: none !important;
}
.ft-row--transfer-group td {
  background-color: var(--color-surface-muted);
}
.ft-cell--transfer-status {
  /* round 15: the column gives back the old 8px left pad (68 -> 60) so
     the icons->percentage gap keeps its round-2 12.6px */
  width: 60px;
  max-width: 60px;
  white-space: nowrap;
}
/* the list's leftmost content sits ON the shared 32px edge (round 15);
   the base td padding rule would win at equal class specificity */
.fs-table--transfer td.ft-cell--transfer-status {
  padding-left: 0;
}
/* progress cell width comes from .ft-heading--transfer-progress* (fixed
   table layout sizes columns at the header) */
.ft-cell--transfer-progress span {
  white-space: nowrap;
}
/* a live value wider than the reserved column must not move it */
.ft-cell--transfer-progress {
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right: 2px;
}
/* 4px lead-in instead of the 8px rhythm: % text 12.6px off the icon
   ink (reference: 28.6) — round-2 "tighter still" */
.fs-table--transfer td.ft-cell--transfer-progress {
  padding-left: 4px;
}

.ft-cell--transfer-ordered {
  max-width: auto;
  width: auto;
  white-space: nowrap;
}
.ft-cell--transfer-started {
  max-width: auto;
  width: auto;
  white-space: nowrap;
}
.ft-cell--transfer-duedate {
  max-width: auto;
  width: auto;
  white-space: nowrap;
}
.ft-cell--transfer-completion {
  max-width: auto;
  width: auto;
  white-space: nowrap;
}
.ft-cell--transfer-user {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* round 9: the site cell no longer wraps (hard rule) — ellipsizes */
.ft-cell--transfer-user-info {
  overflow: hidden;
  text-overflow: ellipsis;
}
.ft-cell--transfer-cpl {
  word-wrap: break-word;
  word-break: break-all;
}
.ft-cell--transfer-cpl--sm {
  display: none;
}
@media (max-width: 926px) {
  .ft-cell--transfer-cpl--sm {
    display: none !important;
  }
}

/* M4i/O4b: ONE CLEAN RECTANGLE. The grey belongs to the CARD, not to
   its cells. On mobile the row is a flex container, so every cell was
   painting its own box: the percentage line carried a short grey strip,
   the stacked lines below a wider one, and the status marks — a flex
   item held right — sat outside the grey altogether. The row paints it
   now, with the row inset on all four sides, and the cells paint
   nothing. */
@media (max-width: 926px) {
  .fs-table--transfer .ft-row--transfer-group {
    background-color: var(--color-surface-muted);
    padding: var(--fs-row-inset);
  }
  .fs-table--transfer .ft-row--transfer-group > td {
    background-color: transparent;
  }
}

/* MOBILE stacked view for the TRANSFERS table: below the 1219px
   mid-breakpoint (round 11, D-016) — the intermediate table layout
   truncated Site; the table renders only where every column fits
   (round 20, D-025: minimum columns 934px + 79px chrome = 927 —
   the SAME width switches the page chrome; the unified lower
   breakpoint X1). */
@media (max-width: 926px) {
  .ft-row--transfer {
    border-top: 4px solid var(--color-surface-muted);
    /* M4g/O4: the card is a flex row — delivery mobile's mechanism, and
       the only one that reliably puts two things on ONE line here. The
       status cell floated right and the percentage still began on the
       line below it (measured 485.5 against 512.09), because a
       `width: 100%` block does not shorten to a float's side. Order
       puts the progress first and the marks after it, `margin-left:
       auto` holds them on the content edge, and every other cell takes
       a full basis so the stack below keeps its left edge and its
       reading order. */
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
  }
  /* the stacked lines first, so the two first-line cells below can be
     the exceptions to it — same specificity means source order decides,
     and the general rule has to come first */
  .fs-table--transfer .ft-row--transfer > td {
    order: 3;
    flex-basis: 100%;
  }
  .fs-table--transfer .ft-row--transfer > td.ft-cell--transfer-progress {
    order: 1;
    flex: 0 1 auto;
    width: auto !important;
    flex-basis: auto;
  }
  .fs-table--transfer .ft-row--transfer > td.ft-cell--transfer-status {
    order: 2;
    flex: 0 0 auto;
    flex-basis: auto;
    margin-left: auto;
  }
  .ft-row--transfer.ft-row--head {
    display: none;
  }
  [class*=ft-cell--transfer] {
    display: block;
    width: 100% !important;
    max-width: 100% !important;
    padding-bottom: 0 !important;
  }
  [class*=ft-cell--transfer]:last-child {
    padding-bottom: 0.75rem !important;
  }
  /* M4d/P7 — THE STATUS ICONS SIT AT THE CARD'S RIGHT EDGE.
     Round 12 put them on their own line at the shared left edge; Tom's
     confirmed override moves them right, matching delivery mobile,
     where an org row reads "name left, marks right". Floating rather
     than right-aligning is what makes them SHARE the first line: the
     percentage and everything under it flow beside and below the float,
     exactly as the tree's name flows beside its marks.
     This REVERSES D-016's mobile icon placement (ledger, D-050); the
     rest of the card anatomy — stacked %+speed, dates, email, filename —
     is untouched, and the icon pair keeps its own GAP_ICON spacing. */
  .fs-table--transfer td.ft-cell--transfer-status {
    height: auto;
    /* M4g/O4: the float is gone — the row is a flex container now and
       the cell is its second item, held right by margin-left: auto. */
    width: auto !important;
    max-width: none !important;
    text-align: right;
    padding-left: var(--fs-checkrow-gap) !important;
    /* M4h/O3b: one inset short of the content edge, like every other
       row's right-hand column. */
    padding-right: var(--fs-row-inset) !important;
    /* M4e/O8b: right-aligned means the CONTENT's right edge — the same
       edge the filter selects above the list end on. The pair used to
       stop 10.9px short of it: 8px of cell padding plus the whitespace
       text node between the two anchors, which an inline row cannot
       drop. A flex row ends the last mark ON the edge and states the
       pair's spacing explicitly, at its sealed GAP_ICON value, instead
       of inheriting whatever a space glyph happens to measure. */
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: var(--fs-gap-icon);
    padding-right: 0 !important;
  }
  /* THE FLEX ITEMS ARE THE MARKS. Each icon anchor is a constant
     25.7px wide — font-awesome's fixed-width advance, the same number
     whichever glyph it holds — while the marks inside are 17.19 and
     18.55, so aligning the ANCHORS left the ink 7px short of the edge
     and inflated the pair's gap. `display: contents` drops the anchor's
     box and promotes its mark, which is the alignment unit this system
     aligns on everywhere else. The anchors already carry `outline:
     none` on focus (control-kit, production parity), so no focus ring
     is lost with the box. */
  .fs-table--transfer td.ft-cell--transfer-status > * {
    display: contents;
  }
  /* every mobile line sits ON the shared 32px edge (round 15) */
  .fs-table--transfer td,
  .fs-table--transfer td.ft-cell--transfer-progress,
  .fs-table--transfer td.ft-cell--transfer-ordered,
  .fs-table--transfer td.ft-cell--transfer-started,
  .fs-table--transfer td.ft-cell--transfer-completion,
  .fs-table--transfer td.ft-cell--transfer-duedate {
    padding-left: 0;
  }
  /* Missing data reserves its line (Tom; legacyref collapses empties to
     5.6px — recorded deviation): every field renders at the normal
     26.6px line (5.6 padding + 21 line-height), so entries keep a
     constant structure and nothing jumps when data streams in. */
  .fs-table--transfer td {
    min-height: 26.6px;
  }
  /* MOBILE EXCEPTION to the no-wrap doctrine (D-016): the CPL renders
     fully and wraps when needed — including its LINK, which carries
     nowrap in the table layouts. */
  .fs-table--transfer td.ft-cell--transfer-cpl,
  .fs-table--transfer td.ft-cell--transfer-cpl a {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
  }
}
@media (max-width: 926px) {
  .ft-row--users {
    border-top: 4px solid var(--color-surface-muted);
  }
  .ft-row--users.ft-row--head {
    display: none;
  }
  [class*=ft-cell--users] {
    display: block;
    width: 100% !important;
    max-width: 100% !important;
    padding-bottom: 0 !important;
  }
  [class*=ft-cell--users]:last-child {
    padding-bottom: 0.75rem !important;
  }
  [class*=ft-cell--organization] {
    display: block;
    width: 100% !important;
    max-width: 100% !important;
    padding-bottom: 0 !important;
  }
  [class*=ft-cell--organization]:last-child {
    padding-bottom: 0.75rem !important;
  }
  [class*=ft-cell--search] {
    display: block;
    width: 100% !important;
    max-width: 100% !important;
    padding-bottom: 0 !important;
  }
  [class*=ft-cell--search]:last-child {
    padding-bottom: 0.75rem !important;
  }
}

.ft-row--users {
  border-top: 2px solid var(--color-surface-muted);
}
.ft-row--users:first-child {
  border-top: none;
}
.ft-cell--search-date {
  width: 10rem;
  min-width: 10rem;
}
.ft-cell--search-name {
  width: 12rem;
  min-width: 12rem;
}
.ft-cell--search-ip {
  width: 8rem;
  min-width: 8rem;
}
.ft-cell--users-role {
  width: 10rem;
  min-width: 10rem;
}
.ft-cell--users-region {
  width: 5rem;
  min-width: 5rem;
}
.ft-cell--users-active {
  width: 2rem;
  min-width: 2rem;
}
.ft-cell--users-transfers {
  width: 5rem;
  max-width: 5rem;
}
.ft-cell--organization-logo {
  width: 8rem;
  min-width: 8rem;
}
.ft-cell--organization-logo .logo {
  background-color: var(--color-line-strong);
  padding: 1rem;
  text-align: center;
  height: 8rem;
  width: 8rem;
  max-height: none;
  max-width: none;
  margin-right: 0;
}
.ft-cell--organization-logo .logo img {
  max-height: 6rem;
  max-width: 6rem;
}
.ft-cell--organization-screen {
  width: 5rem;
  min-width: 5rem;
}
.ft-cell--organization-transfers {
  width: 5rem;
  min-width: 5rem;
}
.ft-cell--organization-actions {
  width: 10rem;
  max-width: 10rem;
}

.value-box {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  width: 100%;
}
.vb-item {
  width: 50%;
}
@media (min-width: 927px) {
  .vb-item {
    width: 25%;
  }
}
.value-box-item--language {
  order: 1;
  width: 33.3333333333%;
}
@media (min-width: 927px) {
  .value-box-item--language {
    width: 20%;
  }
}
.value-box-item--subtitles {
  order: 1;
  width: 66.6666666667%;
}
@media (min-width: 927px) {
  .value-box-item--subtitles {
    width: 20%;
  }
}
.value-box-item--time {
  display: none;
  order: 3;
}
@media (min-width: 927px) {
  .value-box-item--time {
    display: block;
    width: 30%;
  }
}
.value-box-item--date {
  order: 3;
  width: 66.6666666667%;
}
@media (min-width: 927px) {
  .value-box-item--date {
    width: 30%;
  }
}
.value-box-item--resolution {
  display: none;
  order: 1;
}
@media (min-width: 927px) {
  .value-box-item--resolution {
    display: block;
    width: 15%;
  }
}
.value-box-item--format {
  order: 1;
  width: 33.3333333333%;
}
@media (min-width: 927px) {
  .value-box-item--format {
    display: block;
    width: 15%;
  }
}
.value-box-item--frames {
  display: none;
  order: 3;
}
@media (min-width: 927px) {
  .value-box-item--frames {
    display: block;
    width: 20%;
  }
}
.value-box-item--audio {
  order: 2;
  width: 33.3333333333%;
}
@media (min-width: 927px) {
  .value-box-item--audio {
    order: 2;
    width: 20%;
  }
}
.value-box-item--aspect {
  order: 1;
  width: 66.6666666667%;
}
@media (min-width: 927px) {
  .value-box-item--aspect {
    width: 30%;
  }
}

/* action buttons sit side by side at the row end (legacy column sizing) */
.ft-cell--actions {
  white-space: nowrap;
}

/* ── THE ISSUED-SCREENERS LIST (D-111) ───────────────────────────────
   The transfers table's system, shared where it can be shared: the
   separators, cell padding, typography and no-wrap rule ride
   .fs-table--list / .ft-list-row (one home, above) — THIS block holds
   nothing but the column widths and the layout switches. Fixed layout,
   hand-set minima (from experience, like the transfers columns, D-050:
   nothing measured at runtime), EXACTLY the two breakpoints (926/927,
   1546/1547), weighted fluid surplus (title 3, recipient 2, version 1,
   issuer 2, dates 0, /8 — the transfers /15 idiom). Titles and
   addresses ellipsize at the column width. Below 927 the column rows
   hide and each screener's --sm twin renders as a stacked card (the
   transfers each-row-renders-twice pattern), separated by the SAME
   .ft-list-row line. */
.ft-cell--screeners {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* THE FILTER WIDTHS (part 4, third review): the three name fields ride
   THE shared bar-field standard (--fs-chipfield-width = the films
   Distributor pulldown, control-kit) — no screeners-only floor. The
   two pulldowns are INTRINSIC like the Distributor itself (D-038):
   sized by their widest option, per language, so no label can
   truncate in any of the four. */
@media (min-width: 927px) {
  .fs-table--screeners {
    table-layout: fixed;
    width: 100%;
  }
  /* second review (item 5): the three date columns hold the full
     "31.12.26 23:59" at an EXACT 112px and never truncate — the width
     came out of the Title minimum, which ellipsizes anyway. The minima
     now sum to 848 (= 927 − 79 chrome), so with the /8 slope the
     columns total the content width EXACTLY at every viewport and the
     fixed-layout algorithm has no surplus to smear over the fixed
     date columns (that smear is what the old two-tier block did — the
     second tier mirrored transfers' CPL switch, which this table never
     had, and its minima fell 344 short of the width). One continuous
     formula, 927 up. */
  /* D-119: VERSION IS FIXED, like the date columns and for the same
     reason — its values come from a small known vocabulary (spoken
     language plus the compacted subtitle pair: "DE", "EN de",
     "GSW de-fr"), not from free text, so a share of the fluid surplus
     buys it nothing.

     92px is measured, not chosen: the widest value ANY playlist can
     produce is "GSW gsw-fr" at 86.22px in this table's own register
     (Gotham 16/300), plus the 2+2px the other fixed columns pad with =
     90.22, and one more pixel of clearance against font-rendering
     variation. The widest value the list actually shows today is
     "GSW de-fr" at 75.56px, so the column also has room for a longer
     one appearing tomorrow. The value set is language codes out of
     playlist data, not catalog text, so it does not vary by locale.

     WHERE THE RELEASED SPACE WENT, per D-111's ruling that Title pays
     and Title receives: version's 1/8 slope share is now Title's
     (3/8 -> 4/8), and the 28px of MINIMUM width version gained came out
     of Title's minimum (168 -> 140), so the minima still sum to 848 —
     927 minus 79 of chrome — and the slope weights still sum to 8. The
     columns therefore still total the content width exactly at every
     viewport, which is what keeps the fixed layout from smearing. Above
     roughly 1100px Title is WIDER than before; only at the breakpoint
     itself is it narrower, and Title is the column that ellipsizes by
     design. */
  .ft-heading--screeners-title { width: calc(140px + (100vw - 927px) * 4 / 8); }
  .ft-heading--screeners-recipient { width: calc(140px + (100vw - 927px) * 2 / 8); }
  .ft-heading--screeners-version { width: 92px; }
  /* third review (item 4): more air for date+time — Title pays */
  .ft-heading--screeners-date { width: 112px; }
  .ft-heading--screeners-issued { width: calc(140px + (100vw - 927px) * 2 / 8); }
  .fs-table--screeners .ft-row--screeners--sm { display: none; }
  .fs-table--screeners th,
  .fs-table--screeners td.ft-cell--screeners {
    padding-left: 2px;
    padding-right: 2px;
  }
}
/* part 2 parity (ruling 4): the table sits the SAME extracted set-off
   under its bar as the transfers table — the transfers literals
   (43.5 / 35.5 below 927), mirrored, and gated to the pixel against the
   live transfers page (screeners-transfers-parity.mjs). */
.screeners--list .ft-stack {
  margin-top: 43.5px;
}
@media (max-width: 926px) {
  .screeners--list .ft-stack {
    margin-top: 35.5px;
  }
}
@media (max-width: 926px) {
  .fs-table--screeners {
    table-layout: fixed;
    width: 100%;
  }
  /* the column rows AND the heading row hide; the --sm cards carry the
     list (spacer rows have no row class and keep the virtual heights) */
  .fs-table--screeners .ft-row--screeners { display: none; }
  .fs-table--screeners .ft-row--screeners--sm { display: table-row; }
  .ft-cell--screeners--sm {
    padding: 8px 0;
  }
}
.screeners-sm-line {
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.screeners-sm-version {
  margin-left: 8px;
}
/* Film-detail page system (hero, quickinfo, facts, tabs, excerpt, player
   box, status/type icons): mechanically extracted from the flattened
   legacy cascade, colors -> tokens, classes renamed (see git history for
   the map). Values are the production impression. */
.fs-feedback {
  margin-top: 0.25rem;
}
.fs-has-danger .fs-feedback,
.fs-has-danger .checkbox,
.fs-has-danger.checkbox label {
  color: var(--color-danger);
}
.fs-has-danger .fs-field {
  border-color: var(--color-danger);
}
.fs-has-danger .fs-feedback {
  color: var(--color-danger);
}
.fd-tabpanes > .fd-tabpane {
  display: none;
}
.fd-tabpanes > .active {
  display: block;
}
.fd-facts {
  padding-left: 0;
  margin-bottom: 0;
}
.fd-fact {
  position: relative;
  display: block;
  padding: 0.75rem 1.25rem;
  margin-bottom: 0px;
  background-color: var(--color-surface);
  border: 0px solid #ddd;
}
/* THE RIGHT COLUMN IS A PLAIN LIST (D-111 part 4, fourth pass — Tom's
   ruling supersedes the bottom-edge anchoring entirely: it does not
   matter where the column ends). Content stacks from the top — the
   release-date blocks, then the links — with ONE uniform gap between
   the blocks. Fewer links or fewer date blocks simply make the list
   shorter: nothing stretches, nothing anchors, nothing compensates.
   The RHYTHM (fifth pass, item 1): the LINK list keeps the app's
   normal 8px text rhythm — the fourth pass's 4px margins are reverted
   there — with ONE exception: the gap between the last release-date
   block and the first link is LARGER (the group separator). Two
   values total, both pinned by geometry: the 8px link gap, the
   group-gap margin below. The date blocks give back a little air so
   the FULL list (three date blocks + all four links) still ends above
   the cover's lower edge (Tom's ceiling, fourth pass) — measured, not
   derived. The cover-box design-ratio pinning on .fd-poster is
   unrelated and stays. */
@media (min-width: 927px) {
  .fd-info-col .fd-fact {
    padding-top: 0.375rem;
    padding-bottom: 0.375rem;
  }
  /* the DATE blocks keep the fourth pass's rhythm; the LINKS revert to
     the base .fd-fact-text rhythm (margin 0, 1.3 lines — what they
     always were before the fourth pass enlarged them) */
  .fd-info-col .fd-fact:not(:last-child) .fd-fact-text {
    margin-bottom: 4px;
  }
  .fd-info-col .fd-fact-heading {
    margin-bottom: 4px;
  }
  /* the group separator: dates | links */
  .fd-info-col .fd-fact:last-child {
    margin-top: 10px;
  }
}
.fd-fact:last-child {
  margin-bottom: 0;
}
.fd-fact.disabled, .fd-fact.disabled:focus, .fd-fact.disabled:hover {
  color: var(--color-text);
  cursor: not-allowed;
  background-color: var(--color-line-strong);
}
.fd-fact.disabled .fd-fact-heading, .fd-fact.disabled:focus .fd-fact-heading, .fd-fact.disabled:hover .fd-fact-heading {
  color: inherit;
}
.fd-fact.disabled .fd-fact-text, .fd-fact.disabled:focus .fd-fact-text, .fd-fact.disabled:hover .fd-fact-text {
  color: var(--color-text);
}
.fd-fact.active, .fd-fact.active:focus, .fd-fact.active:hover {
  z-index: 2;
  color: var(--color-surface);
  text-decoration: none;
  background-color: var(--color-accent);
  border-color: var(--color-accent);
}
.fd-fact.active .fd-fact-heading,
.fd-fact.active .fd-fact-heading > small,
.fd-fact.active:focus .fd-fact-heading,
.fd-fact.active:focus .fd-fact-heading > small,
.fd-fact.active:hover .fd-fact-heading,
.fd-fact.active:hover .fd-fact-heading > small {
  color: inherit;
}
.fd-fact.active .fd-fact-text, .fd-fact.active:focus .fd-fact-text, .fd-fact.active:hover .fd-fact-text {
  color: rgb(179.2232142857, 220.9553571429, 248.7767857143);
}
.fd-fact-heading {
  margin-top: 0;
  margin-bottom: 5px;
}
.fd-fact-text {
  margin-bottom: 0;
  line-height: 1.3;
}
/* reference .readmore: a block-level link on the body 16px/1.5 line */
.fd-more,
.fd-less {
  display: block;
  line-height: 1.5;
}
.table td .fs-icon {
  margin-right: 0.5rem;
}
.table td .fs-icon:last-child {
  margin-right: 0;
}
/* ── THE CONTENT BLOCK'S WIDTH (M4d/P5) ──────────────────────────────
   The playlist block used the app-wide .fs-container ladder (576 / 940 /
   1140 at 544 / 927 / 1200) plus its own 1540 at 1600 — four steps, none
   of them at a breakpoint this app declares, and two of them inside the
   tablet band. The hero is capped at this block's width, so every one of
   those steps reached the hero as well.

   It is the same two-band model as the hero now: fluid inside each band,
   and the only step is at the desktop switch, where the block widens to
   its 1540 and the hero stays at its fixed width — the block is then the
   wider of the two, which is the relationship Tom described. */
.fs-container--wide {
  max-width: none;
}
@media (min-width: 927px) {
  .fs-container--wide {
    max-width: 1140px;
    /* M4f/O2: the LARGE margin, from 927 up. The block inherited
       .fs-container's mobile 15 at every width, which put the tablet
       page 15px from the window — the small inset is a mobile value
       and nothing above the master breakpoint may use it. */
    padding-left: var(--fs-page-inset);
    padding-right: var(--fs-page-inset);
  }
}
@media (min-width: 1547px) {
  .fs-container--wide {
    max-width: 1540px;
  }
}

/* ── THE FILM HERO'S WIDTH (M4d/P5) ──────────────────────────────────
   M4c swapped the hero onto .fs-container-fluid to kill an unrequested
   jump at 1200. That overshot: at desktop the hero is meant to be a
   FIXED width, slightly narrower than the playlist block below it, and
   not to grow with the window at all ("Desktop war ok vorher").

   So the hero gets its own width rule with exactly the two breakpoints
   /transfers uses (926/927 and 1546/1547) and nothing in between:

     mobile   fluid, small page inset
     tablet   fluid, capped at the content block's width
     desktop  the previous fixed width — static

   The app-wide .fs-container ladder (576 / 940 / 1140 at 544 / 927 /
   1200) is what put a third layout inside the tablet band; the hero no
   longer reads it. */
/* M4h/O1: the hero's blur layer is decorative paint and must never be
   able to widen the page — its own box is clipped by the hero, but a
   scaled-up backdrop still reported width to the pane. */
.fd-hero-blur {
  max-width: 100%;
}
.fd-hero-width {
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--fs-page-inset-mobile);
  padding-right: var(--fs-page-inset-mobile);
}
/* M4e/O4 + M4f/O2: ONE inset for the hero and the content block below
   it — and above 927 that inset is the LARGE one. M4e made them share
   an edge by putting the hero on the block's inset; the block's inset
   was the mobile 15 at every width, so sharing the edge dragged the
   whole tablet page against the window. Both read the same two tokens
   now: the small one below the master breakpoint, the large one above
   it. They stay flush with each other at every width where they share
   a cap; above the desktop switch the block widens to 1540 and the
   hero keeps its fixed 1140, centred (D-050, approved M4d). */
@media (min-width: 927px) {
  .fd-hero-width {
    padding-left: var(--fs-page-inset);
    padding-right: var(--fs-page-inset);
    /* fluid up to the content block's cap, then it simply stops — a
       cap is continuous, not a step */
    max-width: 1140px;
  }
}
.fs-icon {
  margin-right: 0.5rem;
}
.fs-icon--lg {
  font-size: 1.25rem;
}
.fs-icon:last-of-type {
  margin-right: 0;
}
.fs-btn .fs-icon {
  /* legacy set padding-right: .5rem for the <i> glyph gap; on an SVG that
     padding EATS the drawing area (border-box) and shrank button icons to
     ~6px (per-element audit). The centered svg drawing carries the gap. */
  padding-right: 0;
}
.fd-facts {
  text-align: right;
}
.fd-fact {
  background: none;
  padding: 0 0 2rem 0;
}
.fd-fact-heading {
  font-size: 0.75rem;
  text-transform: uppercase;
}
.fd {
  margin-top: -6.5rem;
  width: 100%;
}
.fd-container {
  position: relative;
  z-index: 9;
  background-color: var(--color-surface);
  padding-bottom: 1rem;
}
.fd-tabs {
  margin-bottom: 2.5rem;
  /* reference: the tab row is a full-width var(--color-surface-muted) band behind the tabs */
  background-color: var(--color-surface-muted);
}
.fd-header {
  position: relative;
  overflow: hidden;
  width: 100%;
}
.fd-title {
  position: relative;
  padding: 7rem 0;
  z-index: 2;
  min-height: 30rem;
}
/* M4e/O5: on mobile the band under the distributor logo measured 81px
   of nothing before the cover began — the 7rem bottom padding (a
   desktop-scale value) plus the slack a 30rem min-height leaves once
   the stacked hero is only 239px tall. The TOP padding is the
   backdrop's breathing above the title and is untouched; the bottom is
   2.5rem, and the min-height comes down to what the stacked hero
   actually needs so it stops manufacturing slack. One literal, one
   home, the value judged in the look. */
@media (max-width: 926px) {
  .fd-title {
    padding-bottom: 4.5rem;
    min-height: 26rem;
  }
}
@media (min-width: 927px) {
  .fd-title {
    min-height: 21rem;
  }
}
.fd-title .logo {
  max-width: 100%;
}
@media (max-width: 926px) {
  .fd-title .logo {
    max-width: 10rem;
  }
}
.fd-title .logo img {
  max-width: 100%;
}
@media (max-width: 926px) {
  .fd-title .logo img {
    max-width: 10rem;
    /* M4c/P8: LEFT-ALIGNED under YEAR. The mark was sitting flush right
       inside its 10rem block (measured 61 against the page inset's 15),
       which read as an indent nobody asked for. */
    margin-left: 0;
    margin-right: auto;
    float: none;
  }
}
.fd-content {
  width: 100%;
  z-index: 2;
  color: var(--color-surface-soft);
}
.fd-heading {
  font-weight: 300;
  /* production assets-heading: 16px on a 17.6px (1.1) line */
  line-height: 1.1;
}
.fd-description {
  position: relative;
  z-index: 2;
  padding: 1.5rem 0;
  color: var(--color-surface-soft);
  background-color: rgba(51, 51, 51, 0.5);
  min-height: 22rem;
}
.fd-description .fd-desc-col {
  margin-bottom: 1.5rem;
}
.fd-description .fd-desc-col a {
  font-weight: bolder;
  color: var(--color-surface);
}
.fd-description .fd-desc-col a:hover {
  color: var(--color-accent);
  text-decoration: none;
  font-weight: bolder;
}
.fd-poster {
  margin-top: -4.5rem;
  /* THIRD REVIEW (item 1): the cover BOX is design, not data — always
     the full column at the 40:57 variant ratio (region.rb), whatever
     the source file does (a dead legacy URL rendered a 16px broken
     icon and left the right column aligning to nothing). object-fit
     cover mirrors resize_to_fill for any non-conforming source. */
  display: block;
  width: 100%;
  aspect-ratio: 280 / 399;
  object-fit: cover;
}
@media (max-width: 926px) {
  .fd-poster {
    margin-bottom: 2rem;
  }
}
.fd-poster--empty {
  width: 100%;
  background-color: var(--color-text);
}
@media (max-width: 926px) {
  .fd-poster--empty {
    display: none;
  }
}
.fd-assets {
  margin-bottom: 2.5rem;
}
@media (max-width: 926px) {
  .fd-info-col .fd-facts {
    text-align: left;
  }
}
.fd-info-col a {
  font-weight: bolder;
  color: var(--color-surface);
}
.fd-edit {
  font-size: 1.25rem;
  color: var(--color-surface);
}
@media (max-width: 926px) {
  .fd-quickinfo {
    margin-bottom: 1rem;
  }
}
@media (max-width: 926px) {
  .fd-quickinfo-item {
    margin-top: 1rem;
  }
}
.fd-subheading {
  /* reference .section-moviedetail-subheading: 16px below the subtitle */
  margin-bottom: 1rem;
}
.ft-arrow.empty,
.ft-arrow-targets.empty {
  /* reference .transfers-arrow.empty: non-expandable rows show a passive
     light-gray chevron */
  cursor: default;
  color: #dcdcdc;
}
.fd-quickinfo {
  /* extracted (design pass, films 2660+4850): production's fact row
     starts EXACTLY at the title block's bottom (gap-above 0) — the
     title's own margin is the entire spacing; our extra 8px sat the
     GENRE/COUNTRY/YEAR row visibly lower than production */
  margin-top: 0;
}
/* extracted (design pass): production sets the version table off 59px
   below the Trailer/Features row (tableTop 951 - checkboxes 892); ours
   had only the 8px utility margin */
.fd-versions-filter {
  margin-bottom: 59px;
}
.logo-md {
  max-width: 15rem;
  max-height: 7rem;
}
@media (max-width: 926px) {
  .logo-md {
    max-width: 10rem;
    max-height: 4rem;
  }
}
.logo-md img {
  max-width: 15rem;
  max-height: 7rem;
}
@media (max-width: 926px) {
  .logo-md img {
    max-width: 10rem;
    max-height: 4rem;
  }
}
.fd-hero {
  min-height: 400px;
  background: transparent;
}
.fd-excerpt {
  width: 100%;
  display: block;
  /* reference: the More/Less link sits flush under the clamped text */
  margin-bottom: 0;
}
.fd-excerpt p {
  margin-bottom: 1.5rem;
}
.film-updated {
  float: right;
  color: var(--color-accent);
  text-transform: uppercase;
  font-size: 0.75rem;
  font-weight: bold;
}
/* (FA's default-white icon base dropped: token utilities color the svgs) */
.transfer-icon svg.grey {
  color: #b2b3b9;
}
.transfer-icon svg.red {
  color: #e00054;
}
.transfer-icon svg.green-i {
  color: #76c100;
}
a.grey {
  color: var(--color-text);
}
a.soft-gray {
  color: #dcdcdc;
}
.player-box {
  background: black none repeat scroll 0 0;
  margin-left: auto;
  margin-right: auto;
  width: 90%;
}
/* ROUND F: the computed backdrop. Inset beyond the box (~1.1x) so the
   blur's soft edges never reach a visible border — the standard edge
   treatment for a CSS-blurred backdrop. */
/* The blur is applied to a SMALL layer that is then scaled up: a blur
   costs per pixel, and blurring 1/25 of the pixels and scaling the result
   looks the same (the whole point of the layer is that it has no detail).
   Measured: promoting the full-size layer with will-change made it WORSE
   (median frame 16.9 -> 41.8ms); this is what brought the cost back to
   the downloaded-file variant. The box is 22% at scale(5) = 110% of the
   header, which is the ~1.1x edge treatment. */
.fd-hero-blur {
  position: absolute;
  left: -5%;
  top: -5%;
  width: 22%;
  height: 22%;
  transform: scale(5);
  transform-origin: top left;
  will-change: transform;
  z-index: 0;
  pointer-events: none;
}
.fd-hero:after {
  position: absolute;
  content: "";
  background-color: rgba(51, 51, 51, 0.5);
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
.fd-header {
  background: linear-gradient(to bottom, #aaa 0%, var(--color-ink) 100%);
}
.content--transparent .fd-header {
  background: transparent;
}
.fd-description {
  min-height: 400px;
}
/* (the legacy `.loading .fd-desc-col` clamp is gone: nothing in this build
   ever renders a `.loading` class — the film detail's description clamp is
   the character-threshold rule in FilmHeader. Dead-CSS gate, Phase 2.) */
body .fs-icon--lg {
  font-size: 20px;
}
.fd-excerpt {
  max-height: 260px;
  overflow: hidden;
}
a:not([href]):not([tabindex]).soft-gray {
  color: #dcdcdc;
}
.fd-excerpt p {
  margin-bottom: 1rem;
}
a.transfer-type-icon {
  color: inherit;
}
/* M4Q/O3: THE LABEL COLUMNS ARE RIGID. Each carries its width AND the
   same value as a min-width, because an auto table pays a width deficit
   out of every column at once — at the narrow end of the tablet band the
   row asked for more than it had and the labels gave some back, by an
   amount that depended on how wide the ACTION BUTTONS happened to be.
   That is why switching theatrical <-> homevideo moved the whole run in
   German and not in English: the German captions are longer, so the two
   tabs took different amounts. With a floor on each column the labels
   stand where they are told, and the actions area takes what is left —
   growing leftward into free space, wrapping when there is none, and
   moving no label either way. Fixed px from the left, side by side from
   the right, neither side able to reach the other. */
.film-spoken-language {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-subtitle-languages {
  width: calc(var(--fs-spec-col-2) + var(--fs-spec-gap));
}
.film-dimension {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-resolution {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-aspect-ratio {
  width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
}
.film-audio-type {
  width: calc(var(--fs-spec-col-audio) + var(--fs-spec-gap));
}
.film-fps {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-duration {
  width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
}
.film-end-credit {
  width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
}
.film-distributor-logo {
  float: right;
}
.vb-item {
  min-width: 16px;
}
@media (min-width: 927px) {
  .film-info {
    min-height: 108px;
  }
  .logo-md {
    height: 4rem;
  }
}
.film-playlist-transfer-icon {
  width: 40px;
}
.fs-feedback {
  white-space: pre-wrap;
}
.fs-error-fatal {
  margin-bottom: 16px;
}
.film-info {
  min-height: 38px;
}
/* light tab bar under the hero (THEATRICAL/HOMEVIDEO — the header
   nav-link look on a light surface) */
.fd-tabrow {
  display: flex;
  min-height: 48px;
}
.fd-tab {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 16px;
  color: var(--color-text);
  font-size: 14px;
  font-weight: 500;
  line-height: 14px;
  text-transform: uppercase;
}
.fd-tab--active {
  background-color: var(--color-accent);
  color: var(--color-surface-muted);
}

/* A NON-ACTIVATED PLAYLIST'S ORDER (G4b.1): production renders it as the
   same blue TEXT button PLAY is, struck through — not as a filled button and
   not greyed. The strike covers the cart glyph too, which is why the
   decoration sits on the button and not on its label span. */
.playlist-order-button-not-public,
.playlist-order-button-not-public:hover {
  text-decoration: line-through;
  text-decoration-thickness: from-font;
}

/* HOMEVIDEO conversion checklist (design pass, extracted legacyref film
   4910): 40px rows, production 29px checkbox (fs-toggle--compact via
   the fd-assets fs-scope), 300 14px/21px var(--color-text) names on the version
   block's shared left edge (collapse 40 + icon 24 + 8 = 72 — the D-034
   tightened column); existing conversions inline (Video link + date). */
.fd-conversion-row td {
  /* G2b: the rows ride THE row pitch (control-kit), and their breathing
     is derived from it the same way the deliver tree's is — a hand-set
     4px kept the row at 34+8=42 whatever the register said. */
  /* height + breathing come from THE pitch (control-kit) */
  vertical-align: middle;
}
.fd-conversion-check {
  display: inline-flex;
  align-items: center;
  /* G.4 kept the box on the collapse column's edge; G2b derives that
     edge instead of hand-setting it: chevron column (25) + the
     chevron->box gap (4) = 29, exactly where the deliver tree's own
     selection box sits. With THE global gap (14) after the 29px box the
     name lands on 72 — the version block's shared left edge, unchanged.
     No width here any more: the label sizes itself, and the distance to
     the text is the global seat's, not this surface's. */
  /* M4L/O2: the box column, opened by the row inset like every other
     surface's chain. */
  padding-left: calc(
    var(--fs-row-inset) + var(--fs-chain-chevron) +
      var(--fs-tree-gap-chevron)
  );
  vertical-align: middle;
}

.fd-conversion-name {
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  color: var(--color-text);
  vertical-align: middle;
}
.fd-conversion-name--plain {
  /* a target that already has a conversion has no checkbox, so its name
     has to reach the same left edge on its own: the chevron column and
     its gap, then the box width and THE global seat after it. */
  padding-left: var(--fd-conversion-left-chain);
}

/* ── THE CONVERSION ROW (M4b) ─────────────────────────────────────────
   Tom's order, one line, ONE SHARED BASELINE:

     target name │ ⎸ │ status / actions │ date + time │ creator │ ×

   HAND-SET PX, and the SAME SET at desktop and tablet (M4b/O2) — the
   literals here are the ones recorded in features/film/conversionRow.ts
   (CONVERSION_COLUMNS), and a source gate pins the two together. Below
   md the row STACKS instead; see the mobile block after this one.

   The EMAIL column is the rest, sized to its own text, because the x
   follows the ADDRESS and not the row edge (O3). Whatever width is left
   over after the x sits to its right, untouched.

   --fd-conversion-status-gap is the hand-set one: the name column ends,
   this gap, then the divider and the status. It is declared HERE, on the
   row, and nowhere higher — the deliver tree next door has its own
   sealed spacing and must never see this number. */
.fd-conversion {
  --fd-conversion-status-gap: 26px;
  /* M4c/P4: 310 is the NAME TEXT's own column. The left chain — row
     inset, chevron, its gap, the checkbox, THE icon-to-text gap — comes
     before it, so the track is the chain plus the text column. Written
     as the sum so neither half can be mistaken for the other again. */
  /* M4d/P1 -> 2026-08-10: 310 -> 233. The 77px went to the status
     column next door, which was overrunning the date. The row's first
     three tracks still sum to what they always did, so the email column
     (the `auto` track, and the only elastic one) is untouched. */
  --fd-conversion-col-name-text: 233px;
  /* M4d/P1: THE chain — chevron, gap, box, gap. Same four tokens the
     tree and the films table read, so one edit moves every surface. */
  /* M4L/O2: the chain OPENS with the row inset. Derived on the
     corrected build against ONE origin (the page content box): the
     block's checkbox measured 22.55 where the version row's status mark
     is at 32.56, and its label 66.55 where the CPL filename above it is
     at 76.56 — ten short at both, the row inset the block was not
     inheriting. M4i made this same change; its numbers were unreadable
     because the tokens it names had been dropped by the brace, so it
     was reverted and re-derived rather than trusted. */
  --fd-conversion-left-chain: calc(
    var(--fs-row-inset) + var(--fs-chain-chevron) +
      var(--fs-tree-gap-chevron) + var(--fs-checkbox-size) +
      var(--fs-checkrow-gap)
  );
  --fd-conversion-col-name: calc(
    var(--fd-conversion-left-chain) + var(--fd-conversion-col-name-text)
  );
  /* 220 -> 297 (2026-08-10). 220 left 181px of content space after the
     26px lead gap, the divider and its 12px — and VIDEO + SUBTITLES +
     reorder measured 204px, so the reorder link crossed into the date
     column by 23px. Fixed px, so that overlap was the same at 927 and at
     1920. 297 is the widest LANGUAGE, not the widest English: German
     renders "neu bestellen" where English renders "reorder", needing
     249px of content and 288 of track, and French 217/256. Sized for the
     language that needs most so the row does not depend on who is
     logged in. */
  --fd-conversion-col-status: 297px;
  --fd-conversion-col-date: 122px;
  /* where a stacked mobile line starts: exactly under the NAME's text,
     which is where the left chain ends */
  --fd-conversion-stack-indent: var(--fd-conversion-left-chain);

  display: grid;
  grid-template-columns:
    var(--fd-conversion-col-name)
    var(--fd-conversion-col-status)
    var(--fd-conversion-col-date)
    auto;
  /* THE shared baseline — every cell's text sits on it, whatever its
     weight or size */
  align-items: baseline;
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  color: var(--color-text);
}

/* O1 (M4b) SUPERSEDED FOR THE NAME, 2026-08-10 — see the @media block
   after this section. O1 said the columns are wide enough for every live
   target name, and at 310px that was true and still measures true: the
   widest label renders 300px. It stops being true at 233px, which is
   what the status column's 77px had to come from. So the name truncates
   with an ellipsis in the two banded columns and carries its full text
   in a title. The ADDRESS is untouched and still renders whole.
   `nowrap` stays: it is what keeps the row one line and the baseline
   shared.
   The TAIL is deliberately absent from this list: the address and its x
   are running text and may wrap together (M4c/P5). */
.fd-conversion-name,
.fd-conversion-state,
.fd-conversion-date {
  white-space: nowrap;
}

.fd-conversion-status {
  display: flex;
  align-items: baseline;
  gap: 12px;
  /* the gap the name column ends with, then the thin divider, then
     ordinary column space */
  margin-left: var(--fd-conversion-status-gap);
  border-left: 1px solid var(--color-line-strong);
  padding-left: 12px;
}

/* VIDEO / AUDIO / SUBTITLES — the links, production's weight */
.fd-conversion-file {
  font-weight: 500;
  text-transform: uppercase;
  white-space: nowrap;
}

/* the file is gone: the label stays, struck, and reorder appears beside
   it. This is the ordinary end state of a conversion, not an error. */
.fd-conversion-file--gone {
  color: var(--color-text);
  text-decoration: line-through;
  cursor: default;
}

.fd-conversion-reorder {
  white-space: nowrap;
}

/* M4c/P5: the x IS THE LAST WORD OF THE EMAIL LINE. It reads as
   "email@example.com ×" — one ordinary word-space after the address,
   inline, flowing with the text. M4b's --fs-x-after-text (18px) is gone
   with the idea behind it: the x was a thing positioned beside a column,
   and it is a character in a sentence. The address and the x share ONE
   cell so the space between them is a real space node. */
.fd-conversion-tail {
  min-width: 0;
}
a.fd-conversion-x {
  /* THE REFERENCE for every remove × (D-121) — it carries .fs-remove-x
     now, which is where the shared design lives. What stays here is the
     colour: the x rests in the disabled-icon grey and only darkens on
     hover, because it is a destructive control and must not compete
     with the links beside it. */
  color: var(--color-line-strong);
}
a.fd-conversion-x:hover {
  color: var(--color-text);
}

/* ── MOBILE: the row stacks (M4/N3b) ─────────────────────────────────
   The template is the /transfers mobile card: one clean left-aligned
   column, each part on its own line, in reading order — name, then what
   is happening to it, then when, then who. The x stays on the first
   line, right-aligned, so a destructive control never hides at the
   bottom of a block. */
@media (max-width: 926px) {
  .fd-conversion {
    grid-template-columns: 1fr auto;
    row-gap: 2px;
    /* M4e/O6: no card padding under the row — the 8px sat on top of the
       46 the box and its gap already make, so consecutive boxes stood
       20 apart instead of 12 (measured pitch 54). The separation
       between two cards IS the app-wide box-to-box gap. */
    padding-bottom: 0;
  }
  .fd-conversion-name {
    grid-column: 1;
  }
  /* M4T/O5: THE X SITS ON THE TARGET'S LINE, the way the transfers rows
     put theirs (.ft-detail-actions — grid row 1, last column, end). It
     was a float inside the TAIL, and the tail is a stacked line at the
     bottom of the card, so the float only ever reached the right of that
     last line: a destructive control ended up as far from its subject as
     the card allows (measured 69px below the name). `display: contents`
     dissolves the tail's box on this band, so its two parts become grid
     items in their own right — the address keeps the stacked line, the x
     takes the first row's right-hand column. DESKTOP IS UNTOUCHED: there
     the x is still the last word of the address line (M4c/P5). */
  .fd-conversion-tail {
    display: contents;
  }
  .fd-conversion-tail a.fd-conversion-x {
    float: none;
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }
  .fd-conversion-status,
  .fd-conversion-date,
  .fd-conversion-user {
    grid-column: 1 / -1;
    /* the stacked lines sit under the NAME's text, not under the row
       edge — the same indent the name itself carries */
    padding-left: var(--fd-conversion-stack-indent);
  }
  /* no divider and no lead gap when the status is on its own line */
  .fd-conversion-status {
    margin-left: 0;
    border-left: 0;
  }
}


/* ── THE TARGET LABEL TRUNCATES, TABLET AND DESKTOP ONLY (2026-08-10) ──
   The name column gave 77px to the status column, so a label that used
   to fit may not any more: the widest live one renders 300px into what
   is now 233. It clips with an ellipsis rather than running under the
   divider, and the full string is on the element as a title so nothing
   becomes unreadable — "Mp4 Cinema without Subs and Watermark" stays
   discoverable by hovering it.

   BANDED DELIBERATELY. Below 927 the row is not this grid at all: it
   restacks to `1fr auto` and the label has the full row to itself, so
   there is nothing to truncate and no ellipsis is wanted. That is why
   this is min-width and not a base rule with an override.

   Two shapes, because the cell has two: a plain span when a conversion
   exists, and the checkbox's label when one can be ordered. The checkbox
   is inline-flex and would otherwise size itself to its text and push
   past the track, so it is bounded here too — min-width:0 is what lets a
   flex item shrink below its content at all. */
@media (min-width: 927px) {
  .fd-conversion-name {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .fd-conversion-check {
    min-width: 0;
    max-width: 100%;
  }
}


/* buttons at the tab bottom: left-aligned under the table, 16px pair
   gap (production register) */
.fd-convert-actions {
  /* production renders the buttons in the table's last row: left edge
     = version-block edge + that cell's 8px padding (extracted 53 vs
     block 45 on legacyref) */
  margin: 16px 0 32px 8px;
  display: flex;
  /* M4c/P11: THE button gap, not a local 16 */
  gap: var(--fs-button-gap);
}
.fd-convert-actions .fs-btn {
  margin-bottom: 0;
}

/* M4R/O2: THE FLOOR IS A ONE-LINE-BAND CONSTRUCT. The label columns
   need a minimum so an auto table cannot borrow from them to pay for a
   longer button caption (M4Q/O3) — but only where those columns render.
   Below the master breakpoint the same cells are EMPTIED to nothing
   (kit-tables), and a floor there would hold a mobile row open to the
   width of a desktop label run. A value introduced for one band is
   declared inside that band. */
@media (min-width: 927px) {
  .film-spoken-language {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-subtitle-languages {
    min-width: calc(var(--fs-spec-col-2) + var(--fs-spec-gap));
  }
  .film-dimension {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-resolution {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-aspect-ratio {
    min-width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
  }
  .film-audio-type {
    min-width: calc(var(--fs-spec-col-audio) + var(--fs-spec-gap));
  }
  .film-fps {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-duration {
    min-width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
  }
  .film-end-credit {
    min-width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
  }
}
/* Forms system (ex bootstrap forms + legacy custom controls), extracted
   from the flattened legacy cascade; fs-field/fs-check/fs-panel naming,
   colors -> tokens. Shared by every admin form via components/forms. */
.fs-field {
  display: block;
  width: 100%;
  /* production box (2026-07-27): 8x12 + the 4px border = visual 16 */
  padding: var(--fs-field-pad-y) var(--fs-field-pad-x);
  font-size: var(--fs-field-font-size);
  line-height: 1.25;
  color: #474747;
  background-color: var(--color-surface);
  background-image: none;
  background-clip: padding-box;
  border: 0px solid rgba(0, 0, 0, 0.15);
}
.fs-field::-ms-expand {
  background-color: transparent;
  border: 0;
}
.fs-field::placeholder {
  color: #999;
  opacity: 1;
}
.fs-field:disabled, .fs-field[readonly] {
  background-color: var(--color-line-strong);
  opacity: 1;
}
.fs-field:disabled {
  cursor: not-allowed;
}
select.fs-field:not([size]):not([multiple]) {
  height: 2.5rem;
}
.fs-field--static {
  min-height: 2.5rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  margin-bottom: 0;
}
.fs-form-group {
  margin-bottom: 1rem;
}
.fs-feedback {
  margin-top: 0.25rem;
}
.fs-field--danger {
  padding-right: 2.25rem;
  background-repeat: no-repeat;
  background-position: center right 0.625rem;
  background-size: 1.25rem 1.25rem;
}
.fs-has-danger .fs-feedback,
.fs-has-danger .fs-field-label,
.fs-has-danger .checkbox,
.fs-has-danger.checkbox label,
.fs-has-danger .fs-check {
  color: var(--color-danger);
}
.fs-has-danger .fs-field {
  border-color: var(--color-danger);
}
.fs-has-danger .fs-feedback {
  color: var(--color-danger);
}
.fs-has-danger .fs-field--danger {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23d9274f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9274f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E");
}
.fs-input-group {
  position: relative;
  width: 100%;
  display: flex;
}
.fs-input-group .fs-field {
  position: relative;
  z-index: 2;
}
.fs-input-group .fs-field:focus, .fs-input-group .fs-field:active, .fs-input-group .fs-field:hover {
  z-index: 3;
}
.fs-input-group .fs-field {
  flex: 1;
  margin-bottom: 0;
  /* `flex: 1` is `flex: 1 1 0%` and reads as "shrink freely", but a flex
     item keeps `min-width: auto` — its floor is its own min-content. For
     the four search boxes that floor is an <input>'s default size and
     lands under the pane at 360, which is the only reason they have
     never overflowed. It is not a property of the group. The floor is
     removed here, next to the `flex` it belongs to (D-057). */
  min-width: 0;
}
.fs-input-group-btn {
  white-space: nowrap;
  vertical-align: middle;
}
.fs-input-group-btn {
  position: relative;
  font-size: 0;
  white-space: nowrap;
}
.fs-input-group-btn > .fs-btn {
  position: relative;
}
.fs-input-group-btn > .fs-btn + .fs-btn {
  margin-left: 0px;
}
.fs-input-group-btn > .fs-btn:focus, .fs-input-group-btn > .fs-btn:active, .fs-input-group-btn > .fs-btn:hover {
  z-index: 3;
}
.fs-input-group-btn:not(:last-child) > .fs-btn {
  margin-right: 0px;
}
.fs-input-group-btn:not(:first-child) > .fs-btn {
  z-index: 2;
  margin-left: 0px;
}
.fs-input-group-btn:not(:first-child) > .fs-btn:focus, .fs-input-group-btn:not(:first-child) > .fs-btn:active, .fs-input-group-btn:not(:first-child) > .fs-btn:hover {
  z-index: 3;
}
.fs-check {
  position: relative;
  display: inline;
  padding-left: 1.5rem;
  cursor: pointer;
}
.fs-check + .fs-check {
  margin-left: 1rem;
}
.fs-check-input {
  position: absolute;
  z-index: -1;
  opacity: 0;
}
.fs-check-input:checked ~ .fs-check-box {
  color: var(--color-surface);
  background-color: #0074d9;
}
.fs-check-input:focus ~ .fs-check-box {
  box-shadow: 0 0 0 0.075rem var(--color-surface), 0 0 0 0.2rem #0074d9;
}
.fs-check-input:active ~ .fs-check-box {
  color: var(--color-surface);
  background-color: #84c6ff;
}
.fs-check-input:disabled ~ .fs-check-box {
  cursor: not-allowed;
  background-color: #eee;
}
.fs-check-input:disabled ~ .fs-check-label {
  color: #767676;
  cursor: not-allowed;
}
.fs-check-box {
  position: absolute;
  top: 0.0625rem;
  left: 0;
  display: block;
  width: 1rem;
  height: 1rem;
  pointer-events: none;
  user-select: none;
  background-color: #ddd;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 50% 50%;
}
.fs-check--checkbox .fs-check-input:checked ~ .fs-check-box {
  background-image: none;
}
.fs-check--checkbox .fs-check-input:indeterminate ~ .fs-check-box {
  background-color: var(--color-surface-soft);
  background-image: none;
}
/* .fs-panel base moved to the single CARD-style block below (the one
   .fs-panel definition, D-041). The old base here + its @media 4rem
   companion were BOTH already overridden by the later .fs-panel rule
   (padding 2rem 2rem, bg surface-muted), so the @media was dead and the
   line-strong background never survived — deleted, 0-diff. */
/* (the verbatim duplicate of the .fs-check* block above — .fs-check /
   .fs-check-input / .fs-check-box and the checked/indeterminate rules —
   was deleted 2026-07-27 during the inner-check unification; block 1
   above is the single source.) */
.fs-check--checkbox {
  font-size: 0.875rem;
}
.fs-check--checkbox {
  margin: 0;
  padding-left: 0;
  display: inline-block;
}
/* O6 (M4b): the admin family's painted box joins THE one size. It drew
   2.3rem (36.8) here and 1.8rem (28.8) in --compact below — a third and
   fourth number for the same control. Both are --fs-checkbox-size now. */
.fs-check--checkbox .fs-check-box {
  position: relative;
  width: var(--fs-checkbox-size);
  height: var(--fs-checkbox-size);
  background-color: var(--color-surface-soft);
  padding: 0.4rem 0.7rem;
  color: var(--color-line-strong);
  font-size: 1rem;
  float: left;
}
.fs-check--compact {
  margin-bottom: 0;
  margin-top: -0.5rem;
}
.fs-check--compact .fs-check-box {
  width: var(--fs-checkbox-size);
  height: var(--fs-checkbox-size);
  padding: 0.5rem;
  padding: 0.2rem 0.3rem;
  margin-top: 0.2rem;
}
.fs-check--light .fs-check-box {
  background-color: var(--color-surface) !important;
}
.fs-check--light .fs-check-input:disabled ~ .fs-check-box {
  background-color: var(--color-surface-soft) !important;
}
.fs-check--checkbox .fs-check-label {
  float: left;
  padding: 0.625rem 0 0.625rem 1rem;
  line-height: 1.25;
}
.fs-check--checkbox .fs-check-input:checked ~ .fs-check-box {
  background-color: var(--color-surface-soft);
  color: var(--color-accent);
}
.fs-section-title {
  margin-bottom: 2.5rem;
}
.fs-panel--page {
  margin-top: -5.5rem;
  color: var(--color-text-strong);
}
.fs-panel--page hr {
  border-top: 4px solid var(--color-line-strong);
}
.fs-field {
  border: var(--fs-field-border);
}
.fs-field--light {
  border: none;
  /* borderless variant: no 4px frame, so the FULL visual inset (16)
     is padding — the doctrine is one visual inset, not one padding */
  padding-left: var(--fs-control-inset);
  padding-right: var(--fs-control-inset);
}
/* A field whose VALUE is one unbreakable run — the API token on /profile
   is the only one today. Removing the flex floor above lets the box
   shrink; without this the text simply spills out of the shrunken box
   and over the button beside it, which is a worse defect than the scroll
   it replaced (measured: group 251 wide, scrollWidth 265). Opt-in rather
   than applied to every .fs-field, because breaking mid-word is right
   for a token and wrong for prose (D-057). */
.fs-field--token {
  overflow-wrap: anywhere;
}
.fs-field--text {
  background: transparent;
  padding-left: 0;
  margin-bottom: 0;
}
/* deliver form rows: variants on the SHARED FormRow primitive.
   --center: label mid == control mid (the proven one-line rule beside
   44px picker fields), label-top pt neutralized. --deliver: exactly
   the deliver page's approved geometry (12rem label + 16px gap — the
   old grid-cols-[12rem_1fr] gap-4 math, so the approved selects keep
   their pixels); stacks below the 927 breakpoint. */
.fs-row--center {
  align-items: center;
}
.fs-row--center .fs-label-mini {
  padding-top: 0;
  /* the reboot's label margin-bottom skews the centering */
  margin-bottom: 0;
}
.fs-row--deliver {
  /* neutralize the bootstrap-shim gutters — the deliver geometry is
     label 12rem + 16px, flush at the panel edge */
  margin-left: 0;
  margin-right: 0;
}
.fs-row--deliver > .fs-col {
  padding-left: 0;
  padding-right: 0;
}
.fs-row--deliver > label.fs-field-label {
  flex: 0 0 12rem;
  width: auto;
  margin-right: 16px;
  /* the deliver page's approved label ink (text-strong, iter2) */
  color: var(--color-text-strong);
}
/* LABEL BASELINE MODEL (v6): the label's baseline sits ON the field's
   first text line. Centered rows get it from the centering; textarea
   rows get it explicitly — label offset = the textarea's top inset
   (the control token) with the same 14px/21px line metrics on both
   sides, in the shared row model (no per-field nudges). */
.fs-row--deliver:not(.fs-row--center) > label.fs-field-label {
  /* the field's first text line starts below border + pad-y (the
     production 44px box, 2026-07-27) — the label offset follows so
     the baselines stay paired */
  padding-top: calc(var(--fs-field-pad-y) + var(--fs-field-border-width));
  margin-bottom: 0;
  line-height: 21px;
}
/* SELECT ALIGNMENT in the deliver row model (reviewer crop
   2026-07-27): the bordered fields' VISIBLE white box starts at the
   border's inner edge (the 4px muted border vanishes on the grey
   panel). Borderless selects sit on that same inner edge — and keep
   their text on the shared x by giving back the border width from
   their inset. One x for every control's visible left edge AND for
   every first character. */
/* D-073: the same rule, on the transfer editor, which now has bordered
   date fields above its selects for the first time. NOT a second
   declaration — the rule is about a bordered field sharing a column with
   borderless controls, and it was scoped to `.fs-row--deliver` only because
   Deliver was the surface it was written on. Two selectors, one rule. */
.fs-row--deliver select.fs-select--light,
.fs-form--field-aligned select.fs-select--light {
  margin-left: var(--fs-field-border-width);
  padding-left: calc(var(--fs-control-inset) - var(--fs-field-border-width));
}
/* the deliver textareas: THE shared multiline control — all insets =
   the control token */
.fs-textarea {
  display: block;
  width: 100%;
  /* production box (2026-07-27): 8x12 + the 4px border = visual 16 */
  padding: var(--fs-field-pad-y) var(--fs-field-pad-x);
  border: var(--fs-field-border);
  background: var(--color-surface);
  font-size: var(--fs-control-font-size);
  font-weight: var(--fs-control-font-weight);
  line-height: var(--fs-field-line-height);
  color: var(--color-text);
  outline: none;
}
.fs-row--deliver > .fs-col:last-child {
  flex: 1;
  width: auto;
}
@media (max-width: 926px) {
  .fs-row--deliver {
    flex-direction: column;
    align-items: stretch;
  }
  .fs-row--deliver > label.fs-field-label {
    flex: none;
    margin: 0 0 4px;
    padding-top: 0;
  }
}
.fs-label-mini {
  padding-top: 0.6rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  font-weight: 500;
}
/* A plain TEXT value that has to sit on the label's line: the existing
   14px select register plus the label's own padding-top, so both boxes
   start at the same y and the two baselines coincide by construction
   (recipient count on the notification page, 2026-07-28). */
.fs-value-mini {
  padding-top: 0.6rem;
  font-size: var(--fs-select-font-size);
}
/* ============ PANEL — ONE DEFINITION (D-041) ============
   The single home for .fs-panel (the gray form/system surface). Carries
   the computed values that previously survived the kit.css + kit-forms
   cascade: bg surface-muted, padding 2rem 2rem, margin-bottom 2rem
   (=32px), color text-strong. No cross-file duplicate, no dead @media. */
.fs-panel {
  background-color: var(--color-surface-muted);
  padding: 2rem 2rem;
  margin-bottom: 2rem;
  color: var(--color-text-strong);
}
.fs-check--checkbox .fs-check-box .fs-icon {
  opacity: 0;
}
.fs-check--checkbox .fs-check-input:checked ~ .fs-check-box .fs-icon {
  opacity: 1;
}
.fs-check-input {
  position: absolute;
  z-index: -1;
  opacity: 0;
}
.fs-check--compact {
  margin-top: -8px;
  margin-bottom: 0px;
}
.fs-has-danger .fs-field--danger {
  border-color: var(--color-danger);
  border-style: solid;
}
.fs-check + .fs-check {
  margin-left: 1rem;
}
.fs-feedback {
  white-space: pre-wrap;
}
.fs-checkboxes {
  max-height: 256px;
  overflow: auto;
}
.fs-checkboxes-label {
  display: block;
  margin: 0;
  line-height: 1.25em;
}
.fs-error-fatal {
  margin-bottom: 16px;
}
.storage-table__cpl--group .fs-check-box {
  background-color: white !important;
}
/* admin-form select (production `custom-select filterbar-select-light`):
   white, borderless, 14px/300, bootstrap double-triangle chevron. The
   filterbar `.fs-select` rules are scoped to .fs-filterbar/.fs-scope and
   never reached the admin forms — their selects rendered browser-default
   (all-pages inventory, 2026-07-13). */
/* form-geometry tokens live in styles/control-kit.css (THE contract:
   pages consume, never define) */
select.fs-select--light {
  display: inline-block;
  max-width: 100%;
  appearance: none;
  /* selects keep their SEALED 37.5 line (production form selects too,
     measured 2026-07-27) — decoupled from the 44px field box */
  height: var(--fs-select-height);
  padding: 0 calc(2 * var(--fs-control-inset) + 8px) 0 var(--fs-control-inset);
  /* selects keep PRODUCTION's own 14 (--fs-select-font-size), not the
     16px input font — extraction 2026-07-27 */
  font-size: var(--fs-select-font-size);
  font-weight: var(--fs-control-font-weight);
  line-height: 17.5px;
  color: var(--color-text);
  border: 0;
  border-radius: 0;
  background: var(--color-surface)
    url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E")
    no-repeat calc(100% - var(--fs-control-inset)) 50% / 8px 10px;
}

/* dropdown panel (legacy .dropdown-menu; used by the playlist-form DCP
   search results) */
.fs-menu {
  position: absolute;
  z-index: 1000;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  background-color: var(--color-surface);
  background-clip: padding-box;
  border: 1px solid rgba(0, 0, 0, 0.15);
}

/* --- DateTimePicker (design pass, fresh design-system component) ---
   Field: production's deliver input register — 4px border var(--color-surface-muted),
   8px 12px padding; the focused/open frame is the EXTRACTED legacy
   focus state: 4px solid #66afe9. Text only, no glyph. Radius 0, no
   shadows, fs tokens throughout. */
.fs-dtp {
  position: relative;
  display: inline-block;
}
.fs-dtp-field {
  /* DATE_FIELD_W: hand-set 140px (v5). Left inset = THE control
     token (v6 collapsed it to 12px, so the v5 per-field deviation is
     gone); right padding 0 — the right air is the natural leftover:
     widest verdict date "30.12.2026 20:00" (120px) paints fully in
     the 128px content box. FLAGGED residual (standing): the
     pathological zero-heavy "20.02.2030 00:00" (129px) would scroll
     ~1px. Height = the shared field height; vertical air is the
     RESULT (inputs center their text). */
  width: var(--fs-date-field-width);
  height: var(--fs-field-height);
  /* production box (2026-07-27): 8x12 both sides — 175 total leaves a
     143px content box, widest date 130px + air */
  padding: var(--fs-field-pad-y) var(--fs-field-pad-x);
  border: var(--fs-field-border);
  border-radius: 0;
  background: var(--color-surface);
  font-size: var(--fs-control-font-size);
  font-weight: var(--fs-control-font-weight);
  line-height: var(--fs-field-line-height);
  color: var(--color-text);
  outline: none;
  text-align: left;
}
/* MOBILE DATE FIELD (our-format round 2026-07-26): the field box is
   .fs-dtp-field (above); this wrapper holds OUR formatted value and,
   on top of it, the real datetime-local input at opacity 0 covering
   the whole box, so a single tap opens the iOS picker. The input is
   position:absolute -> adds no metrics; the box keeps FIELD_HEIGHT +
   inset 16. No !important, no per-page variant. */
.fs-dtp-native {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.fs-dtp-native-value {
  white-space: nowrap;
  overflow: hidden;
}
.fs-dtp-native-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
}
.fs-dtp-panel {
  position: absolute;
  z-index: 50;
  top: calc(100% + 4px);
  left: 0;
  display: flex;
  background: var(--color-surface);
  border: 1px solid var(--color-line-strong);
  border-radius: 0;
  padding: 12px;
  gap: 16px;
}
.fs-dtp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.fs-dtp-month {
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-strong);
}
.fs-dtp-nav {
  border: none;
  background: none;
  padding: 0 8px;
  font-size: 18px;
  color: var(--color-accent);
  cursor: pointer;
}
.fs-dtp-grid {
  display: grid;
  grid-template-columns: repeat(7, 34px);
}
.fs-dtp-weekday {
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text);
  text-align: center;
  padding: 4px 0;
}
.fs-dtp-day {
  border: none;
  background: none;
  border-radius: 0;
  height: 32px;
  font-size: 14px;
  font-weight: 300;
  color: var(--color-text-strong);
  cursor: pointer;
}
.fs-dtp-day:hover {
  background: var(--color-surface-muted);
}
/* Grey means EXACTLY "not selectable" — nothing else (reviewer rule,
   idiot-proof round 2026-07-27). Off-month days are SELECTABLE (clicking
   navigates there), so they render BLACK like in-month days — no --off
   greying. Below-min days are grey and NOT struck through (the
   strikethrough is removed). */
.fs-dtp-day--disabled {
  color: var(--color-line-strong);
  cursor: default;
}
.fs-dtp-day--disabled:hover {
  background: none;
}
.fs-dtp-day--selected,
.fs-dtp-day--selected:hover {
  background: var(--color-accent);
  color: var(--color-surface);
}
.fs-dtp-time {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 8px;
}
.fs-dtp-time-input {
  width: 40px;
  padding: 4px 0;
  text-align: center;
  border: 1px solid var(--color-surface-muted);
  border-radius: 0;
  /* input surface -> THE control font (16, round 2026-07-27); the
     1px panel-internal border stays its own (not a form-field edge) */
  font-size: var(--fs-control-font-size);
  font-weight: var(--fs-control-font-weight);
  color: var(--color-text-strong);
  outline: none;
}
.fs-dtp-time-sep {
  color: var(--color-text);
}
/* Schnellwahl column: durations relative to VALID FROM */

/* --- deliver tree: MARK-BOX ALIGNMENT MODEL (pilot) ---
   All icon layout comes from treeIconRegistry.ts mark boxes via the
   MarkIcon primitive (MarkIcon.tsx); NO per-icon, per-state, per-pair
   or per-page compensation may exist here or anywhere else outside
   the registry. Columns: width = --dt-gap + mark width (set inline
   from the registry), so a cell's right edge IS its mark's right edge
   and the next cell's padding-left carries the ONE token. The chevron
   column right-aligns its mark (both chevron states share it).
   Vertical: cells share the row baseline; the TEXT sits naturally on
   it (no paint shift anywhere), and each .mk wrapper seats its mark
   center MARK_LINE_RISE_EM above that baseline via vertical-align
   (set inline by MarkIcon from the registry — the one relation).
   Lock column leaves the template entirely without a DKDM. */
.deliver-tree td,
.deliver-tree th {
  vertical-align: baseline;
}
/* ROW MODEL (iteration 2): one constant row height for every level, and
   it is THE app-wide checkrow pitch (--fs-checkrow-pitch, control-kit).
   M4c/P2: box 34 + 12px box-to-box gap = a 46px row, the breathing
   being half the gap on each side.
   The strut in the chevron cell carries the 34px mark-aligned extent
   in EVERY row, so height never depends on level, name class or which
   icons a row happens to have — and no row's paint can bleed into a
   neighbor (the box sits 4px inside its own row). */
/* M4c/P2: the breathing is half the box-to-box gap, so two boxes in
   consecutive rows sit exactly --fs-checkbox-gap apart. It was a
   hand-set 4px (which made the 42px row); with the 12px rule it is 6. */
.deliver-tree tbody td {
  padding-top: calc(var(--fs-checkbox-gap) / 2);
  padding-bottom: calc(var(--fs-checkbox-gap) / 2);
}
.dt-strut {
  display: inline-block;
  width: 0;
  /* the strut IS a box standing on the line — the row's extent is the
     box plus the breathing the cell padding adds, which is exactly the
     pitch. M4c/P2: expressed as the box, not as "pitch minus 8", so the
     two cannot disagree when either token moves. */
  height: var(--fs-checkbox-size);
  /* the strut IS a 34px mark standing on the line (17 = 34/2): it
     places the row's baseline via ordinary layout so the text lands
     on the iteration-3 optical line WITHOUT any text paint shift —
     same 42px row, same absolute text position as the sealed build.
     --mk-rise comes from the registry via the table's inline vars. */
  vertical-align: calc(var(--mk-rise) - 17px);
}
.deliver-tree td.dt-chevron {
  text-align: right;
  /* strut + button must share one line — wrapping dropped expanded
     chevrons to a second line and grew those rows to 63px */
  white-space: nowrap;
}
/* the UA stylesheet gives td padding: 1px; the icon columns need
   content-right = cell-right (a cell's right edge IS its mark's right
   edge), so kill the stray right padding there. Dates/emails keep
   their inherited spec untouched. */
.deliver-tree td.dt-chevron,
.deliver-tree td.dt-box,
.deliver-tree td.dt-check,
.deliver-tree td.dt-lock {
  padding-right: 0;
}
/* two gap tokens (iteration 3): chevron->box rides the tight token,
   everything after the checkbox rides the wide one. Values come from
   the registry via inline vars on the table. */
.deliver-tree td.dt-box {
  padding-left: var(--dt-gap-chevron);
}
.deliver-tree td.dt-check {
  padding-left: var(--dt-gap-icon);
}
/* G2b: the NAME is text after an icon, so it rides THE icon -> text
   distance (global), not the mark -> mark token its neighbours use. */
.deliver-tree td.dt-name {
  padding-left: var(--fs-checkrow-gap);
}
/* ONE-GAP round 2026-07-26: adjacent marks sit GAP_ICON apart —
   the lock rides the SAME token as every icon neighbor (supersedes
   iteration-4's tight-token arithmetic that read 3.81). */
.deliver-tree td.dt-lock {
  padding-left: var(--dt-gap-icon);
}
.deliver-tree td.dt-check,
.deliver-tree td.dt-lock {
  white-space: nowrap;
}
/* the reboot's label margin-bottom biased names inside the row line */
.deliver-tree td.dt-name label {
  margin-bottom: 0;
}
/* the mark-box primitive: layout box = mark box; paint is absolutely
   positioned by the registry offsets and overshoots freely */
.mk {
  display: inline-block;
  position: relative;
  /* vertical-align is set inline by MarkIcon: mark center at
     MARK_LINE_RISE_EM above the line's baseline — THE relation. */
}
/* THE expand chevron (film-detail standard, 2026-07-26): ONE
   definition for every expand/collapse chevron. Closed points right;
   open rotates 90° with the production transition (all 0.5s ease —
   extracted from the ported legacy playlist-toggle rule that fd used;
   the tree's Tailwind transition-transform 150ms read as "instant"
   and is gone). Indent is the axis rule: 12px column lead + marks
   centered on the 13px chevron axis (registry chevron-open width),
   passed as MarkIcon's axis by every site. Sites put mk-chevron
   (+ --closed) on the toggle anchor; NO local animation or indent
   values may exist at any chevron site. */
.mk-chevron svg {
  transform: rotate(90deg);
  transition: all 0.5s;
}
.mk-chevron--closed svg {
  transform: rotate(0deg);
}
.mk-paint {
  position: absolute;
  line-height: 0;
  white-space: nowrap;
}
.mk-paint svg,
.mk-paint .fs-icon {
  display: block;
  margin: 0;
}
/* contact sheet (dev flag 'fs-contact-sheet') */
.cs {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 60;
  background: var(--color-surface);
  border: 1px solid var(--color-line-strong);
  padding: 12px 24px;
  font-size: 14px;
}
.cs-row {
  position: relative;
  padding: 12px 0;
  white-space: nowrap;
}
.cs-line {
  display: inline-block;
  width: 100%;
  margin-right: -100%;
  height: 1px;
  background: rgba(255, 0, 0, 0.55);
  /* the reference line sits where mark centers sit: MARK_LINE_RISE_EM
     above the baseline (1px line -> minus half its height). */
  vertical-align: calc(var(--mk-rise) - 0.5px);
}
.cs-text {
  padding-left: 12px;
  /* text sits naturally on its baseline — the sheet shows the real
     relation with no mirroring needed. */
}
.cs-tag {
  color: #999;
  font-size: 11px;
  padding-left: 16px;
}
.deliver-tree td.dt-date,
.deliver-tree td.dt-email,
.deliver-tree th.dt-h-date {
  padding-left: 2px;
}
/* email tail row (tablet-only, TABLET round 2026-07-26): hidden at
   every width EXCEPT 927<=w<1547. Two-class selector so it beats the
   mobile `.deliver-tree tr { display: flex }` (0,1,1) — otherwise the
   tail would flex-show on phones and duplicate the stacked email. */
.deliver-tree tr.dt-email-tail {
  display: none;
}
/* legend icon -> label gap = GAP_ICON (fed as --mk-gap from the
   registry on the legend section); the MarkIcon seats the icon via
   the line rule, this carries the horizontal token — no legend-local
   value. The label follows the mark with no text-node space. */
.dt-legend-item .mk {
  margin-right: var(--mk-gap);
}
/* TABLET (927 <= w < 1547): recipients/email leaves its column and
   becomes a tail row flush under the NAME column — the Transfers
   tail-row pattern (D-031), same 1547 switch. */
@media (min-width: 927px) and (max-width: 1546px) {
  .deliver-tree td.dt-email--lg,
  .deliver-tree th.dt-h-email {
    display: none;
  }
  .deliver-tree tr.dt-email-tail {
    display: table-row;
  }
  .deliver-tree td.dt-email-tail-cell {
    /* O7 (M4b): flush under the NAME TEXT. The leading empty cells put
       this cell at the name column edge; the inset after it has to be
       the name cell's own, which is THE icon-right gap (14) — it was
       --dt-gap-icon (7.75, the mark-to-MARK gap), so every tail email
       sat 6.25px left of the organization above it. One gap is for two
       icons, the other for an icon and a word; this is the second. */
    padding-left: var(--fs-checkrow-gap);
    /* hand-set tail rhythm — its OWN row height, derived from the
       email line (21px = the tree's 14px/1.5 text line) + 6px bottom
       breathing. NOT the 42px data-row constant: the tail is a
       separate row that grows one 21px step per wrapped line. */
    padding-top: 0;
    padding-bottom: 6px;
    line-height: 21px;
    white-space: normal;
    overflow-wrap: anywhere;
    color: var(--color-text);
  }
}
/* the tree's page section: desktop keeps the 32px page edge the
   deliver page uses everywhere (ex mx-8); below the master 927
   breakpoint it sits on THE shared mobile inset. */
.dt-section {
  margin-left: 2rem;
  margin-right: 2rem;
}
/* padding variant (the breadcrumb strip uses padding as its edge) */
.dt-section-p {
  padding-left: 2rem;
  padding-right: 2rem;
}
/* MOBILE TREE (deliver-mobile round 2026-07-26, reviewer verdict;
   production reference adopted for ONE pattern: status icons
   right-aligned). Below the master 927 breakpoint the rows become
   baseline-aligned flex lines — baseline, not center, so every cell
   keeps the desktop table's shared-baseline construction and the
   sealed line rule seats the marks. Flush columns via the SAME
   registry constants (TREE_COLS, fed as --dt-col-* by the table):
     [chevron 25][box 38][name flex] ............ [check 24.94][lock 20.63]
   dates/emails wrap to full-width lines under the name, on the name's
   own lead (chevron + box + GAP_ICON — flush-column arithmetic from
   existing tokens only). All levels share every column — the old
   per-level checkbox drift is structurally impossible. */
@media (max-width: 926px) {
  .dt-section {
    margin-left: var(--fs-page-inset-mobile);
    margin-right: var(--fs-page-inset-mobile);
  }
  .dt-section-p {
    padding-left: var(--fs-page-inset-mobile);
    padding-right: var(--fs-page-inset-mobile);
  }
  /* CPL grouping (the two kit constants): when the name wraps under
     its pair it stays TIGHT (--dt-cpl-gap-in); groups separate with
     --dt-cpl-gap-between (margin shorthand also neutralizes the
     desktop mt-2 on the "Also book for" list so every entry rides
     the same rhythm). Desktop (>=927) keeps the utility values. */
  .dt-section .dt-cpl-entry {
    /* two-class specificity: the Tailwind gap/margin utilities sit
       later in the bundle, one class deep — this must win. */
    row-gap: var(--dt-cpl-gap-in);
    margin: 0 0 var(--dt-cpl-gap-between) 0;
  }
  .deliver-tree thead {
    display: none;
  }
  .deliver-tree,
  .deliver-tree tbody {
    display: block;
  }
  .deliver-tree tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    /* M4e/O6: no row padding. The row's extent is the strut (the 34px
       box) plus the cell breathing (half the box-to-box gap on each
       side) = THE pitch, exactly as on desktop; these 2px on top made
       every mobile tree row 50 instead of 46 — the larger pitch Tom
       saw on the tree. */
    padding: 0;
  }
  .deliver-tree td {
    display: block;
  }
  /* chevron MARK ink flush at the inset: the desktop column's 12px
     tree indent (pl-3) is a desktop-only lead — on mobile the column
     is exactly the chevron axis (registry chevron-open width, fed as
     --dt-chevron-axis), so the mark's left ink edge sits at 15. */
  /* STANDARD anchoring (reviewer revision of the left-flush
     experiment: the state jump was the defect). The chevron column
     starts at the inset and is exactly the chevron axis; marks
     axis-center via the sealed rule, so BOTH states share one axis
     and the state toggle moves nothing horizontally. The visible gap
     is whatever the standard yields — no special mobile value. */
  .deliver-tree td.dt-chevron {
    flex: 0 0 var(--dt-chevron-axis);
    padding-left: 0;
    order: 1;
  }
  .deliver-tree td.dt-box {
    flex: 0 0 var(--dt-col-box);
    order: 2;
  }
  .deliver-tree td.dt-name {
    flex: 1 1 0;
    min-width: 0;
    order: 3;
  }
  .deliver-tree td[colspan] {
    flex: 1 1 0;
    min-width: 0;
    order: 3;
  }
  .deliver-tree td.dt-check {
    flex: 0 0 var(--dt-col-check);
    order: 4;
  }
  .deliver-tree td.dt-lock {
    flex: 0 0 var(--dt-col-lock);
    order: 5;
  }
  /* M4/N3c: the stacked date and email sit under the SITE NAME's text,
     in one aligned column. They were indented with --dt-gap-icon (7.75,
     the mark-to-MARK gap) while the name cell is indented with
     --fs-checkrow-gap (14, the mark-to-TEXT gap) — so every date and
     email sat 6.25px to the left of the name above it. One gap is for
     two icons, the other is for an icon and a word; this is the second
     kind. */
  .deliver-tree td.dt-date,
  .deliver-tree td.dt-email {
    order: 6;
    flex-basis: 100%;
    padding-left: calc(
      var(--dt-chevron-axis) + var(--dt-col-box) + var(--fs-checkrow-gap)
    );
    padding-top: 0;
    padding-bottom: 0;
  }
  .deliver-tree td.dt-email {
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .deliver-tree td.dt-date:empty,
  .deliver-tree td.dt-email:empty {
    display: none;
  }
}
/* Sign-in pages: full port of new_design/_login.scss (mask over the photo
   slider, black logo plate, partner-logo flickity strip), colors -> tokens. */
.app-pane--login {
  position: absolute;
  overflow: hidden;
  display: table;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  /* G4.2: DARK FROM THE FIRST FRAME. The pane inherits .app-pane's white
     surface, and it covers the (black) body — so a cold sign-in showed
     white until the first photo painted. The ground is the one login
     register; the photos fade in over it. */
  background-color: var(--fs-login-ground);
}

.login {
  display: table;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}
.login-slider {
  background: rgba(51, 51, 51, 0.5);
  padding: 4rem 0;
  width: 100%;
  overflow-x: hidden;
}
.login-slider .fs-container-fluid {
  padding: 0 !important;
}
.login-logo {
  color: var(--color-surface);
  padding: 1rem;
  background: black;
  margin: 4rem 0;
  display: inline-block;
}
.login-logo .fs-lead {
  margin: 0;
}
@media (max-width: 991px) {
  .login-logo .fs-display {
    font-size: 2rem;
  }
  .login-logo .fs-lead {
    font-size: 1rem;
  }
}
/* K15: THE PANEL CARRIES THE INK. Legacy sets the text colour on the mask
   itself (form.login__mask__form computes rgb(255,255,255)), so everything
   inside inherits white over the dark translucent panel. We set it only on
   two label classes, and every paragraph fell back to the document's
   --color-text (rgb(115,115,115)) — grey text on a busy photo, which is
   the washed-out panel Tom photographed. Extracted from the legacy build
   served at legacyref, not guessed; background and padding already agreed. */
.login-form {
  padding: 4rem;
  background: rgba(51, 51, 51, 0.8);
  color: var(--color-surface);
}
/* and its links: legacy renders them white and UNDERLINED inside the mask,
   which is what makes them findable once the text around them is white
   too — the app's accent blue is for links on our own light surfaces. */
.login-form a:not(.fs-btn) {
  color: var(--color-surface);
  text-decoration: underline;
}
.login-form .fs-label-mini {
  color: var(--color-surface);
}
.login-form .fs-check-label {
  color: var(--color-surface);
}
@media (max-width: 991px) {
  .login-form {
    padding: 2rem;
  }
}
@media (max-width: 926px) {
  .login-form {
    padding: 1rem;
  }
}
.login-info {
  background: rgba(51, 51, 51, 0.8);
  padding: 2rem 0;
  color: var(--color-surface);
}
.login-infobox {
  padding: 1rem;
  width: 100%;
}
.login-infobox a {
  color: var(--color-surface);
  text-decoration: underline;
}
.login-infobox a:hover {
  text-decoration: none;
}
.login .fs-form-text a {
  color: var(--color-surface);
}

.carousel-cell {
  width: 50%;
  height: 5rem;
  padding: 0 2rem;
  float: left;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.carousel-cell img {
  max-width: 100%;
  max-height: 5rem;
  margin: 0 auto;
}
@media (min-width: 544px) {
  .carousel-cell {
    width: 33.3333333333%;
  }
}
@media (min-width: 927px) {
  .carousel-cell {
    width: 25%;
  }
}
@media (min-width: 992px) {
  .carousel-cell {
    width: 16.6666666667%;
  }
}
@media (min-width: 1200px) {
  .carousel-cell {
    width: 12.5%;
  }
}
.carousel-cell {
  width: 10%;
}

/*! Flickity v2.0.2
http://flickity.metafizzy.co
---------------------------------------------- */
.flickity-enabled {
  position: relative;
}

.flickity-enabled:focus {
  outline: none;
}

.flickity-viewport {
  overflow: hidden;
  position: relative;
  height: 100%;
}

.flickity-slider {
  position: absolute;
  width: 100%;
  height: 100%;
}

/* draggable */
.flickity-enabled.is-draggable {
  -webkit-tap-highlight-color: transparent;
  tap-highlight-color: transparent;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.flickity-enabled.is-draggable .flickity-viewport {
  cursor: move;
  cursor: -webkit-grab;
  cursor: grab;
}
/* Misc shared sections/controls extracted from the legacy cascade
   (page sections, modal close button, filter-bar strips, contact cards). */
/* ============ CARD — ONE DEFINITION ============
   Single home for the .fs-card system: the surface/ink backgrounds and
   the text colour that travels with them, every variant ordered so the
   modifier (.fs-card--inverse) wins by SOURCE ORDER — no !important
   (beyond the pre-existing link-colour reset carried verbatim), no
   specificity escalation. Consolidated 2026-07-27: kit-port.css — a
   production-EXTRACTION file — had re-declared .fs-card / .fs-card--
   inverse at equal specificity, and the later file silently won (the
   white-on-white /contact bug, then "fixed" with a third even-later
   override). The KIT files own the system; the PORT files only record
   extractions — so the card lives HERE and kit-port carries none. */
.fs-card {
  position: relative;
  display: block;
  margin-bottom: 2.5rem;
  background-color: var(--color-surface);
  border: 0px solid rgba(0, 0, 0, 0.125);
}
.fs-card--inverse {
  padding: 2rem;
  color: var(--color-surface);
  background-color: var(--color-ink);
}
.fs-card-block {
  padding: 0 2px;
}
.fs-card-block::after {
  content: "";
  display: table;
  clear: both;
}
.fs-card-title {
  margin-bottom: 2.5rem;
}
.fs-card--inverse .fs-card-title {
  color: var(--color-surface);
}
.fs-card a {
  color: var(--color-surface) !important;
}
.fs-card ul {
  margin-bottom: 0;
}
.fs-alert--dismissible .fs-close {
  position: relative;
  top: -2px;
  right: -21px;
  color: inherit;
}
.fs-close {
  float: right;
  font-size: 1.5rem;
  font-weight: bold;
  line-height: 1;
  color: #000;
  text-shadow: 0 1px 0 var(--color-surface);
  opacity: 0.2;
}
.fs-close:focus, .fs-close:hover {
  color: #000;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.5;
}
button.fs-close {
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 0;
  -webkit-appearance: none;
}
.fs-filterbar {
  margin-bottom: 1rem;
}
@media (min-width: 544px) {
  .fs-filterbar {
    margin-bottom: 0.5rem;
  }
}
.fs-filterbar .fs-form-group {
  display: inline-block;
  margin: 0 1rem 1rem 0;
  height: 2.25rem;
}
.fs-filterbar .fs-form-group:last-child {
  margin-right: 0;
}
/* (card rules consolidated into the single CARD block at the top of
   this file, 2026-07-27 — this second scattered copy is deleted.) */
.fs-section-title {
  margin-bottom: 2.5rem;
}
.fs-section-subtitle {
  margin-bottom: 1rem;
}
.fs-filterbar-section {
  overflow: auto;
}
.fs-filterbar .fs-form-group {
  display: inline-block;
  height: 2.25rem;
}
.fs-attach-file {
  margin: 6px;
  margin-left: 0px;
}
/* THE MAP CANVAS (ex maps.scss; G3.4d, corrected).
   It fills the pane's content box — which already begins under the header,
   so the old hand-set 110px top was a second, stale copy of the header
   height and showed as a white strip. IN FLOW (not absolute): out of flow
   the pane had no content height, so the pane's closing band came to rest
   inside the viewport, behind the canvas. In flow the map is exactly one
   screenful and the band follows it below the fold, like on every other
   page — same shared rule, no map exception. */
#map {
  position: relative;
  /* flex: none — the pane is a flex column (the shared closing-band rule),
     and as a shrinkable item the canvas gave up exactly the footer's height
     (744 instead of 964, measured). It takes its full screenful; the band
     follows below the fold. */
  /* the page area is at least a screenful (kit.css .app-pane-content), so
     the canvas states its own height from the two registers instead of
     stretching to it: exactly the viewport minus the bar, which is what
     "flush, one screen" means. */
  flex: none;
  /* FULL BLEED, BUT NOT UNDER THE BAR: the map is the only page with no air
     above it, so it cancels the pane's page AIR — the padding minus the
     header's own height, both from the one register each. It starts exactly
     at the header's edge: no white strip above the ground colour, and
     Google's top-right zoom control is fully in view (cancelling the whole
     padding put the canvas top behind the bar, and the control with it). */
  margin-top: calc(var(--fs-header-height) - var(--fs-pane-pad-top));
  height: calc(100vh - var(--fs-header-height));
  width: 100%;
}


/* Cleanup round 2026-07-26: consolidation classes replacing repeated
   inline px styles (one definition each). */
.fs-overlay-dim {
  background-color: rgba(0, 0, 0, 0.75);
}
.fs-rowact {
  margin-left: 0.3rem;
}
.fs-check-gap {
  margin-right: 30px;
}
.fs-modal-gap {
  margin-bottom: 12px;
}
.fs-modal-gap--both {
  margin: 12px 0;
}

/* G4.5: a query that found nothing is the point of the search log — it reads
   as a state, not as a number (the danger tone the forms already use). */
.search-histories-nohit {
  color: var(--color-danger);
  font-weight: 500;
}

/* ── M4h/O1: THE MINIMUM WIDTH IS 360 ────────────────────────────────
   Every page has to be usable there. Three surfaces cannot fit their
   content into 330 CSS pixels and are not meant to: the admin lists
   (organizations, users, disks) carry a column per attribute, and the
   film-edit form is a legacy stacked table. They get a scroller of
   their own rather than being clipped by the pane — nothing becomes
   unreachable, and the page itself stops overflowing. */
@media (max-width: 926px) {
  /* the admin lists carry a column per attribute and the film-edit form
     is a legacy stacked table: neither can be made to fit 330 CSS
     pixels without becoming a different page. They scroll inside their
     own box instead of being clipped by the pane — every cell stays
     reachable, and the page itself no longer overflows. */
  .ft-stack,
  .fd-assets.fs-container-fluid {
    overflow-x: auto;
  }
  /* the convert actions are buttons on one line; at 360 they wrap
     instead of running off the right */
  .fd-convert-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--fs-button-gap);
  }
  .fd-convert-actions .fs-btn {
    max-width: 100%;
  }
}

/* ── M4h/O5: THE MAP'S OWN CHROME KEEPS THE PAGE MARGINS ─────────────
   Google places its Map/Satellite toggle, its fullscreen button and its
   zoom pair hard against the canvas edge. The canvas fills its area —
   the CONTROLS move, by the page's own inset, so they line up with
   everything else on the page; and they clear the navigation above by a
   hand-set band that lives here and nowhere else. */
/* M4L: the inline-style hook that used to be in this list is gone. It
   was M4i's attempt to reach Google's own zoom wrapper; the zoom pair is
   OURS now (below), and the hook was also matching it — with !important,
   which is why our control kept the desktop inset at mobile widths. */
#map .gm-style .gmnoprint,
#map .gm-style .gm-fullscreen-control,
#map .gm-style .gm-bundled-control {
  margin-left: var(--fs-page-inset) !important;
  margin-right: var(--fs-page-inset) !important;
  margin-top: var(--fs-map-control-drop) !important;
}
@media (max-width: 926px) {
  #map .gm-style .gmnoprint,
  #map .gm-style .gm-fullscreen-control,
  #map .gm-style .gm-bundled-control {
    margin-left: var(--fs-page-inset-mobile) !important;
    margin-right: var(--fs-page-inset-mobile) !important;
  }
}

/* ── M4i/O5: THE ZOOM PAIR, ours ─────────────────────────────────────
   Google's own zoom control could not be moved off the window edge, so
   the map builds its own and pushes it as a control: same position
   (RIGHT_TOP), same page inset and the same clearance below the
   navigation as the Map/Satellite toggle and the fullscreen button,
   and Google's own idiom — a white card, its two buttons split by a
   hairline, at the map's control size. */
#map .fs-map-zoom {
  margin-right: var(--fs-page-inset);
  margin-top: var(--fs-map-control-drop);
  background: #fff;
  border-radius: 2px;
  box-shadow: rgba(0, 0, 0, 0.3) 0 1px 4px -1px;
  overflow: hidden;
}
@media (max-width: 926px) {
  #map .fs-map-zoom {
    margin-right: var(--fs-page-inset-mobile);
  }
}
#map .fs-map-zoom-button {
  display: block;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  background: transparent;
  color: #666;
  font-size: 17px;
  line-height: 26px;
  cursor: pointer;
}
#map .fs-map-zoom-button + .fs-map-zoom-button {
  border-top: 1px solid #e6e6e6;
}
#map .fs-map-zoom-button:hover {
  color: #000;
}
/* Feature-page rules ported from the legacy cascade (users/organizations/
   storage/suisa/targets/profile/transfers/screener-grant hooks, film info
   badges, contact cards, alerts, legacy selects) — BEM __ normalized to
   single-dash, colors -> tokens. */
.fs-fade {
  opacity: 0;
  transition: opacity 0.15s linear;
}
.fs-fade.in {
  opacity: 1;
}
.fs-dropdown {
  position: relative;
}
.fs-select-native {
  display: inline-block;
  max-width: 100%;
  /* KIT variant: pre-consolidation geometry restored (verdict);
     left inset = THE token */
  padding: var(--fs-native-pad-y) var(--fs-native-clearance) var(--fs-native-pad-y) var(--fs-control-inset);
  color: #474747;
  vertical-align: middle;
  background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
  background-image: none \9 ;
  background-size: 8px 10px;
  border: 0px solid rgba(0, 0, 0, 0.15);
  -moz-appearance: none;
  -webkit-appearance: none;
}
.fs-select-native:disabled {
  color: var(--color-text);
  cursor: not-allowed;
  background-color: var(--color-line-strong);
}
.fs-select-native::-ms-expand {
  opacity: 0;
}
/* (all .fs-card rules consolidated into kit-misc.css — the kit owns the
   card system; this extraction file carries none. 2026-07-27) */
.fs-alert {
  padding: 15px;
  margin-bottom: 1rem;
  border: 0px solid transparent;
}
.fs-alert--success {
  background-color: #dff0d8;
  border-color: #d6e9c6;
  color: #3c763d;
}
.fs-alert--danger {
  background-color: #f2dede;
  border-color: #ebccd1;
  color: #a94442;
}
.fs-alert--warning {
  background-color: #fcf8e3;
  border-color: rgb(249.5322580645, 242.2419354839, 203.9677419355);
  color: #8a6d3b;
}
.fs-alert--warning hr {
  border-top-color: rgb(247.064516129, 236.4838709677, 180.935483871);
}
.fs-select-native {
  display: inline-block;
  max-width: 100%;
  /* KIT variant: pre-consolidation geometry restored (verdict);
     left inset = THE token */
  padding: var(--fs-native-pad-y) var(--fs-native-clearance) var(--fs-native-pad-y) var(--fs-control-inset);
  color: #474747;
  vertical-align: middle;
  background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
  background-image: none \9 ;
  background-size: 8px 10px;
  border: 0px solid rgba(0, 0, 0, 0.15);
  -moz-appearance: none;
  -webkit-appearance: none;
}
.fs-select-native:disabled {
  color: var(--color-text);
  cursor: not-allowed;
  background-color: var(--color-line-strong);
}
.fs-select-native::-ms-expand {
  opacity: 0;
}
.fs-select-classic {
  display: inline-block;
  /* KIT variant: pre-consolidation geometry restored (verdict) */
  padding: var(--fs-classic-pad-y) var(--fs-classic-clearance) var(--fs-classic-pad-y) var(--fs-control-inset);
  line-height: 1.25;
  border: none;
  border-radius: 0;
  background-color: var(--color-surface-muted);
  font-size: 0.875rem;
  color: var(--color-text);
}
/* KIT variant: the small select, restored (verdict) */
.fs-select--sm {
  padding-top: var(--fs-select-sm-pad-y);
  padding-bottom: var(--fs-select-sm-pad-y);
  font-size: 75%;
}
@media (max-width: 543px) {
  .fs-select-classic {
    width: 100%;
  }
}
.fs-select-classic.fs-select--light {
  background-color: var(--color-surface);
}
.app-pane--login {
  position: absolute;
  overflow: hidden;
  display: table;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
}
.login-info {
  background: rgba(51, 51, 51, 0.8);
  padding: 2rem 0;
  color: var(--color-surface);
}
/* ONE cell-width definition (--cell-w): consumed by the cell width
   AND by the carousel's JS-free calc() positioning (LoginFooter). */
.flickity-enabled {
  --cell-w: 50%;
}
@media (min-width: 544px) {
  .flickity-enabled { --cell-w: 33.3333333333%; }
}
@media (min-width: 927px) {
  .flickity-enabled { --cell-w: 25%; }
}
@media (min-width: 992px) {
  .flickity-enabled { --cell-w: 16.6666666667%; }
}
@media (min-width: 1200px) {
  .flickity-enabled { --cell-w: 12.5%; }
}
@media (min-width: 1600px) {
  .flickity-enabled { --cell-w: 10%; }
}
.carousel-cell {
  width: var(--cell-w);
  height: 5rem;
  padding: 0 2rem;
  float: left;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.carousel-cell img {
  max-width: 100%;
  max-height: 5rem;
  margin: 0 auto;
}
/*! Flickity v2.0.2
http://flickity.metafizzy.co
---------------------------------------------- */
.flickity-enabled {
  position: relative;
}
.flickity-enabled:focus {
  outline: none;
}
.flickity-viewport {
  overflow: hidden;
  position: relative;
  height: 100%;
}
.flickity-slider {
  position: absolute;
  width: 100%;
  height: 100%;
}
/* draggable */
.flickity-enabled.is-draggable {
  -webkit-tap-highlight-color: transparent;
  tap-highlight-color: transparent;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.flickity-enabled.is-draggable .flickity-viewport {
  cursor: move;
  cursor: -webkit-grab;
  cursor: grab;
}
.table .ft-body--asset-details td {
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
.table .ft-body--asset-details {
  display: table-row-group !important;
}
.table .ft-body--asset-details.in {
  display: table-row-group !important;
}
.table .ft-body--asset-details .ft-row--asset-detail:last-child td {
  padding-bottom: 0.75rem;
}
.table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-date {
  display: inline-block;
  width: 8rem;
  border-right: 1px solid var(--color-line-strong);
  padding-right: 0.5rem;
  white-space: nowrap;
}
@media (max-width: 991px) {
  .table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-date {
    border-right: 0;
  }
}
.table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-name {
  display: inline;
  width: auto;
  padding-right: 0.5rem;
  padding-left: 0.5rem;
}
@media (max-width: 991px) {
  .table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-name {
    padding-left: 0;
    padding-right: 0;
    display: inline-block;
  }
}
/* (round 25: CPL toggle moved to the runtime .ft-stack--cpl-column model in kit-tables) */
.app-pane--full {
  padding: 0;
}
.ft-heading {
  margin: 0 0 0.5rem 0;
  display: inline-block;
  font-size: 1rem;
  font-weight: 300;
  color: var(--color-text);
  min-width: 6rem;
}
.ft-status-item {
  display: inline-block;
  width: 40%;
  font-size: 1rem;
}
/* (dead legacy rotation rules removed — chevron rotation is the ONE
   .mk-chevron definition in kit-forms.css; ft-status-item today hosts
   only the PlaylistForm status dot, no chevron) */
.film-edit .playlist a {
  word-wrap: break-word;
  text-overflow: ellipsis;
}
/* THE GRANT FORM'S VERTICAL RHYTHM, ONE VALUE, ONE PLACE (D-141).
 *
 * MEASURED BEFORE: 16, 0, 16, 0, 16 down the form. Two mechanisms were
 * fighting — every .fs-form-group carries margin-bottom: 1rem, and the
 * two preview slots wore a hand-added Tailwind mt-4 — and ADJACENT
 * MARGINS COLLAPSE, so the mt-4 never added anything at all. The empty
 * line D-132 ruled above the start line, and the one D-138 ruled above
 * the salutation, were both swallowed the moment they were written; and
 * where a preview slot came FIRST the next block started at zero,
 * because .fs-row carries no bottom margin of its own.
 *
 * So the blocks stop carrying their own spacing here and the FORM owns
 * it: one gap between blocks, set once. Nothing collapses against
 * anything, and a slot spaces the same whichever side of a field it is
 * on. */
.screener-grant-form > * + * {
  margin-top: var(--fs-screener-block-gap);
}
.screener-grant-form .fs-form-group {
  margin-bottom: 0;
}
/* TIGHT UNDER THE LINE THEY BELONG TO — the remark box under the
   salutation, and the validity pair under the line that starts the
   screener. Each is the field that sentence is asking for, not a new
   section, so neither takes the block rhythm. ONE value, both seams. */
.screener-grant-form > .screener-grant-remark,
.screener-grant-form > .screener-grant-dates {
  margin-top: var(--fs-screener-tight-gap);
}
/* THE CLOSING IS PROSE, and prose does not butt against a control: it
   keeps its own air below the dates, less than the block rhythm because
   it still belongs to them. */
.screener-grant-form > .screener-grant-closing {
  margin-top: var(--fs-screener-closing-gap);
}
/* THE VALIDITY PAIR IS ONE CONTROL, not two blocks: FROM and TO are read
   together and the form's block gap between them read as a separation
   they do not have. Its own, tighter value — the one deliberate
   exception, stated rather than hand-set at the call site. */
.screener-grant-dates > * + * {
  margin-top: var(--fs-screener-pair-gap);
}
.screener-recipients {
  position: relative;
  /* THE FIELD GROWS WITH ITS RECIPIENTS (D-131, owner's ruling).
     This was a fixed `height` with the control absolutely positioned
     over it: the control wrapped, but the box beneath it did not grow,
     so a second line of recipients hung over whatever followed. It is a
     MIN-height now and the control sits in the flow, so the field is as
     tall as its content — one line at rest, as many as it takes when
     many people are added. Nothing scrolls and nothing is clipped.
     `relative` stays: the suggestion panel hangs off this box. */
  min-height: var(--fs-field-height);
}
.screener-recipients-control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* TWO REGISTERS, ONE FIELD (reviewer 2026-07-27): TEXT gets the
     standard field text inset (12 pad -> visual 16 with the border,
     like the textarea below); CHIPS get the 4.5 centering gap. The
     state is pure CSS (:has), both insets derive from the existing
     kit constants — no third value, no JS layout. Vertical stays the
     4.5 gap in both states, so the 44 height and the placeholder
     baseline never jump. */
  gap: var(--fs-chipfield-gap);
  min-height: var(--fs-field-height);
  padding: var(--fs-chipfield-gap) calc(var(--fs-control-inset) - var(--fs-field-border-width));
  background: var(--color-surface);
  border: var(--fs-field-border);
  cursor: text;
}
.screener-recipients-control:has(.fs-chip) {
  /* G2.3: chips present -> the SAME register as the bar's chip fields:
     THE inset minus the chip's own lead minus the border this box draws,
     so the chip's content edge lands on the field's text inset (16). The
     4.5 chip gap stays what it always was — the vertical rhythm and the
     inter-chip gap — but it is no longer a second left-inset value. */
  padding-left: calc(
    var(--fs-control-inset) - var(--fs-chip-lead) - var(--fs-field-border-width)
  );
  padding-right: var(--fs-chipfield-gap);
}
/* (local chip rules deleted — recipient chips are the sealed D-033
   .fs-chip family, app.css, one definition) */
.screener-recipients-search {
  flex: 1;
  min-width: 80px;
  border: none;
  outline: none;
  /* 1.5px: the input is the flex-line driver (24px caret line) — at
     27px outer it matches the chip exactly, so the UNIFORM 4.5 gap
     holds and the box stays at THE field height (8 border + 2x4.5 gap
     + 27 line = 44). */
  padding: 1.5px 0;
  background: transparent;
  font-size: inherit;
  line-height: 1.5;
}
/* THE "+ REGISTER NEW RECIPIENT" LINK (D-132, owner's ruling): its +
   lines up with the OUTER edge of the field above it. It carried an
   inline margin-left of 8px and read as belonging to something else.
   .fs-btn--link is already padding:0, so alignment is the absence of
   that indent; the top margin moves here with it, because layout in a
   style attribute is layout nobody can find. */
.screener-recipients-register {
  display: inline-block;
  margin-top: 14px;
}
.screener-recipients-search::placeholder {
  color: var(--color-text);
  opacity: 1;
}
.screener-recipients-dropdown {
  position: absolute;
  /* THE PANEL IS THE FIELD'S OWN WIDTH (D-132, owner's ruling). It hung
     4px OUTSIDE the field on each side — the field's border width — so
     both top corners showed a step. Flush now: same left edge, same
     width. The panel draws the same 4px border, so an option's box
     begins on the field's INNER edge and a highlighted entry sits inside
     the frame rather than against it. Measured in
     recipientPanel.browser.test. */
  left: 0;
  right: 0;
  top: 100%;
  background: var(--color-surface-muted);
  border: var(--fs-field-border);
  border-top: none;
  z-index: 9999;
  max-height: 300px;
  overflow-y: auto;
}
.screener-recipients-option {
  padding: 0.625rem 1rem;
  font-size: 0.875rem;
  color: var(--color-ink);
  cursor: pointer;
}
.screener-recipients-option:hover {
  background: var(--color-accent);
  color: var(--color-surface);
}
.app-pane--login small a:not(.fs-btn) {
  text-decoration: none;
}
.app-pane--login small a:not(.fs-btn):hover {
  text-decoration: underline;
}
body.light.body--login, .content.app-pane--login {
  background: black;
  overflow: auto;
}
/* (round 9) the completion cell obeys the global no-wrap hard rule */
@media (max-width: 926px) {
  .ft-cell--transfer {
    display: block;
    width: 100% !important;
    max-width: 100% !important;
    padding-bottom: 0 !important;
  }
}
/* reference cell bottom padding is the plain 5.6px — the ported legacy
   0.75rem override left too much air under the CPL text (round 2) */
.table .ft-body--asset-details.in.hidden {
  display: none !important;
}
.ft-cell--transfer-cpl--sm {
  /* M4g/O5: flush left edge with the progress percentage above (round 7,
     legacyref: both at one x). It said "the same 4px lead-in as the
     progress cell" and then hard-set the 4 — so when M4e/O8a gave that
     column the chain's box->text gap above 927, the filename stayed
     behind and the pair the rule exists to keep together drifted 6px
     apart. It reads the lead now instead of restating it; the tail row
     only renders between 927 and 1546, where that is the value. */
  padding-left: var(--fs-checkrow-gap) !important;
}
.ft-cell--transfer-playlists {
  /* the reference's exact paint (round 6 rollback of rounds 2-5): text
     pulled up toward the main row, box kept — tail row 27.6px, text-to-
     divider 17.6px, both extracted from legacyref */
  position: relative;
  top: -8px;
}
/* (round 25: CPL toggle moved to the runtime .ft-stack--cpl-column model in kit-tables) */
/* (round 25: CPL toggle moved to the runtime .ft-stack--cpl-column model in kit-tables) */
/* (round 25: CPL toggle moved to the runtime .ft-stack--cpl-column model in kit-tables) */
@media (max-width: 926px) {
  .transfers--admin--list .ft-cell--transfer-cpl--sm {
    display: none !important;
  }
}
/* (round 25: CPL toggle moved to the runtime .ft-stack--cpl-column model in kit-tables) */
@media (max-width: 926px) {
  .transfers--admin--list .ft-row--transfer--sm {
    display: none;
  }
}
@media (max-width: 926px) {
  .transfers--admin--list [class^=table-cell--transfer] {
    display: block;
    width: 100% !important;
    max-width: 100% !important;
    padding-bottom: 0 !important;
  }
  .transfers--admin--list [class^=table-cell--transfer]:last-child {
    padding-bottom: 0.75rem !important;
  }
}
.tablesaw-stack tbody tr {
  border-bottom: 1px solid #dfdfdf;
}
.fs-select-classic.fs-select--light:disabled {
  background: #ddd;
}
a.fs-link-muted {
  color: inherit;
}
.transfers-search-form {
  padding-top: 4px;
}
/* THE /films BAR HAS NO GEOMETRY OF ITS OWN (D-121, owner's ruling).
   It carried `padding-top: 4px !important` and `margin-bottom: 18px`
   here while its form ALSO takes the shared bar form's 4px — so the
   filter row sat 4px lower than on /transfers and /screeners and the
   bar's bottom edge was a different number again. FilterBarFrame owns
   the whole box now: one padding, one margin, one overflow, for all
   three bars. */
.table .ft-body--asset-details .ft-cell--asset-detail {
  padding-top: 4px !important;
}
.film-spoken-language {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-subtitle-languages {
  width: calc(var(--fs-spec-col-2) + var(--fs-spec-gap));
}
.film-dimension {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-resolution {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-aspect-ratio {
  width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
}
.film-audio-type {
  width: calc(var(--fs-spec-col-audio) + var(--fs-spec-gap));
}
.film-fps {
  width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
}
.film-duration {
  width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
}
.film-end-credit {
  width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
}
/* the Distributor pulldowns' 220px is GONE (D-121): every bar pulldown
   wears --fs-chipfield-width from app.css, at one breakpoint (927), so
   this rule's own 543 breakpoint and its second number are both
   retired. */
.film-distributor-logo {
  float: right;
}
@media (max-width: 991px) {
  .table .ft-body--asset-details .ft-cell--asset-detail .ft-detail-name {
    padding-left: 8px;
  }
}
/* the transfers pulldowns' second width block is GONE too (D-121). It
   was dead either way — below 927 the stacked bar makes every select
   full width, above it the shared rule wins on specificity — and dead
   numbers are what let the bar drift into five sizing models. */
@media (min-width: 927px) {
  .film-info {
    min-height: 108px;
  }
}
@media (max-width: 926px) {
  .transfers--admin--list .ft-cell--transfer-cpl {
    display: block;
  }
}
.transfers-search-form {
  overflow: hidden;
}
@media (min-width: 927px) {
  .ft-cell--asset-detail {
    white-space: nowrap;
  }
}
.ft-heading {
  padding-left: 4px;
}
.film-playlist-transfer-icon {
  width: 40px;
}
.films-image {
  position: absolute;
  top: 0px;
}
.fs-select-native {
  max-width: 100%;
}
.form-file-container {
  padding: 0;
  margin: 0;
}
.storage-table-cpls {
  white-space: nowrap;
}
.storage-table-cpls p {
  height: 23px;
}
.storage-modal-footer {
  height: 45px;
}
.storage-modal-btn:disabled {
  opacity: 0.5;
}
.organizations-item {
  border-top: 4px solid var(--color-surface-muted);
}
.organizations-logo-container {
  background-color: var(--color-line-strong);
  padding: 1rem;
  text-align: center;
  height: 8rem;
  width: 8rem;
  max-height: none;
  max-width: none;
  margin-right: 0;
}
.organizations-logo-image {
  max-height: 6rem;
  max-width: 6rem;
}
.films-ingest-dcps {
  width: 927px;
}
.table .ft-body--asset-details .ft-cell--asset-detail {
  padding: 0px;
  padding-top: 8px;
}
.film-info {
  min-height: 38px;
}
/* film-edit version grid — production parity (design pass, extracted
   legacyref /films/4910/edit @1600): full content width, fs-table
   header register (700 14px uppercase var(--color-text)), production column
   widths (preload 126, DE/FR/IT 71, Hide 78, public 104, invoice 120;
   title takes the rest), 12px cell padding with the 29px production
   checkbox (row pitch 56.5), light row separators. NOTE: D-031's
   fixed-minima+weighted-surplus doctrine is Transfers-specific — this
   grid simply matches production. */
table.film-edit {
  width: 100%;
}
.film-edit th {
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--color-text);
  padding: 12px;
  text-align: left;
}
.film-edit td {
  padding: 12px;
  vertical-align: top;
  /* production row typography: 300 14px/21px (ours inherited the 16px
     document font — the round-23 property diff) */
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  color: var(--color-text);
}
.film-edit tbody tr + tr td,
.film-edit tbody + tbody tr:first-child td {
  /* production separator: var(--color-line-strong) hairline (its computed border reads
     0px yet the row pitch carries 0.5px — a subpixel border) */
  border-top: 0.5px solid var(--color-line-strong);
}
/* production's checkbox control box is 29x32 — the 32 drives the
   56.5px row pitch (12 + 32 + 12 + hairline) */
.film-edit .fs-check {
  min-height: 32px;
  align-items: center;
  display: inline-flex;
  margin: 0;
}
.film-edit th.fe-col--preload { width: 126px; }
.film-edit th.fe-col--lang { width: 71px; }
.film-edit th.fe-col--hide { width: 78px; }
.film-edit th.fe-col--public { width: 104px; }
.film-edit th.fe-col--invoice { width: 120px; }
.film-edit .fs-check-box {
  width: 29px;
  height: 29px;
}

/* M4R/O2: THE FLOOR IS A ONE-LINE-BAND CONSTRUCT. The label columns
   need a minimum so an auto table cannot borrow from them to pay for a
   longer button caption (M4Q/O3) — but only where those columns render.
   Below the master breakpoint the same cells are EMPTIED to nothing
   (kit-tables), and a floor there would hold a mobile row open to the
   width of a desktop label run. A value introduced for one band is
   declared inside that band. */
@media (min-width: 927px) {
  .film-spoken-language {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-subtitle-languages {
    min-width: calc(var(--fs-spec-col-2) + var(--fs-spec-gap));
  }
  .film-dimension {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-resolution {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-aspect-ratio {
    min-width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
  }
  .film-audio-type {
    min-width: calc(var(--fs-spec-col-audio) + var(--fs-spec-gap));
  }
  .film-fps {
    min-width: calc(var(--fs-spec-col-1) + var(--fs-spec-gap));
  }
  .film-duration {
    min-width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
  }
  .film-end-credit {
    min-width: calc(var(--fs-spec-col-3) + var(--fs-spec-gap));
  }
}
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties {
  @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
    *, :before, :after, ::backdrop {
      --tw-rotate-x: initial;
      --tw-rotate-y: initial;
      --tw-rotate-z: initial;
      --tw-skew-x: initial;
      --tw-skew-y: initial;
      --tw-space-y-reverse: 0;
      --tw-border-style: solid;
      --tw-font-weight: initial;
      --tw-ordinal: initial;
      --tw-slashed-zero: initial;
      --tw-numeric-figure: initial;
      --tw-numeric-spacing: initial;
      --tw-numeric-fraction: initial;
      --tw-shadow: 0 0 #0000;
      --tw-shadow-color: initial;
      --tw-shadow-alpha: 100%;
      --tw-inset-shadow: 0 0 #0000;
      --tw-inset-shadow-color: initial;
      --tw-inset-shadow-alpha: 100%;
      --tw-ring-color: initial;
      --tw-ring-shadow: 0 0 #0000;
      --tw-inset-ring-color: initial;
      --tw-inset-ring-shadow: 0 0 #0000;
      --tw-ring-inset: initial;
      --tw-ring-offset-width: 0px;
      --tw-ring-offset-color: #fff;
      --tw-ring-offset-shadow: 0 0 #0000;
      --tw-outline-style: solid;
      --tw-blur: initial;
      --tw-brightness: initial;
      --tw-contrast: initial;
      --tw-grayscale: initial;
      --tw-hue-rotate: initial;
      --tw-invert: initial;
      --tw-opacity: initial;
      --tw-saturate: initial;
      --tw-sepia: initial;
      --tw-drop-shadow: initial;
      --tw-drop-shadow-color: initial;
      --tw-drop-shadow-alpha: 100%;
      --tw-drop-shadow-size: initial;
      --tw-ease: initial;
      --tw-content: "";
    }
  }
}

@layer theme {
  :root, :host {
    --spacing: .25rem;
    --container-3xl: 48rem;
    --font-weight-light: 300;
    --font-weight-medium: 500;
    --font-weight-bold: 700;
    --ease-in-out: cubic-bezier(.4, 0, .2, 1);
    --default-transition-duration: .15s;
    --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);
    --breakpoint-md: 927px;
    --breakpoint-lg: 1586px;
    --color-text: #737373;
    --color-text-strong: #4d4d4d;
    --color-text-heading: #4a4a4a;
    --color-ink: #333;
    --color-surface: #fff;
    --color-surface-muted: #f2f2f2;
    --color-surface-soft: #f5f5f5;
    --color-line: #f2f2f2;
    --color-line-strong: #d9d9d9;
    --color-accent: #1183cf;
    --color-success: #7ed321;
    --color-danger: #d0021b;
    --color-action-success: #5cb85c;
    --color-kdm-valid: #76c100;
    --color-kdm-future: #f7cb00;
    --color-kdm-expired: #e00054;
    --color-status-muted: #b2b3b9;
    --color-status-waiting: #d9d9d9;
    --font-sans: Gotham, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
    --text-sm: 14px;
    --text-sm--line-height: 21px;
    --text-base: 16px;
    --text-base--line-height: 24px;
    --text-display: 40px;
    --text-display--line-height: 44px;
    --spacing-control: 34px;
  }
}

.pointer-events-none {
  pointer-events: none;
}

.collapse {
  visibility: collapse;
}

.invisible {
  visibility: hidden;
}

.visible {
  visibility: visible;
}

.absolute {
  position: absolute;
}

.fixed {
  position: fixed;
}

.relative {
  position: relative;
}

.static {
  position: static;
}

.inset-0 {
  inset: 0;
}

.top-0 {
  top: 0;
}

.top-2026 {
  top: calc(var(--spacing) * 2026);
}

.bottom-control {
  bottom: var(--spacing-control);
}

.left-0 {
  left: 0;
}

.isolate {
  isolation: isolate;
}

.z-0 {
  z-index: 0;
}

.z-10 {
  z-index: 10;
}

.z-50 {
  z-index: 50;
}

.float-left {
  float: left;
}

.float-right {
  float: right;
}

.\!container {
  width: 100% !important;
}

@media (min-width: 927px) {
  .\!container {
    max-width: 927px !important;
  }
}

@media (min-width: 1586px) {
  .\!container {
    max-width: 1586px !important;
  }
}

.container {
  width: 100%;
}

@media (min-width: 927px) {
  .container {
    max-width: 927px;
  }
}

@media (min-width: 1586px) {
  .container {
    max-width: 1586px;
  }
}

.m-0 {
  margin: 0;
}

.mt-2 {
  margin-top: calc(var(--spacing) * 2);
}

.mt-4 {
  margin-top: calc(var(--spacing) * 4);
}

.mt-5 {
  margin-top: calc(var(--spacing) * 5);
}

.mt-6 {
  margin-top: calc(var(--spacing) * 6);
}

.mb-2 {
  margin-bottom: calc(var(--spacing) * 2);
}

.mb-3 {
  margin-bottom: calc(var(--spacing) * 3);
}

.mb-4 {
  margin-bottom: calc(var(--spacing) * 4);
}

.mb-6 {
  margin-bottom: calc(var(--spacing) * 6);
}

.mb-8 {
  margin-bottom: calc(var(--spacing) * 8);
}

.mb-10 {
  margin-bottom: calc(var(--spacing) * 10);
}

.mb-11 {
  margin-bottom: calc(var(--spacing) * 11);
}

.mb-12 {
  margin-bottom: calc(var(--spacing) * 12);
}

.ml-2 {
  margin-left: calc(var(--spacing) * 2);
}

.ml-auto {
  margin-left: auto;
}

.block {
  display: block;
}

.contents {
  display: contents;
}

.flex {
  display: flex;
}

.grid {
  display: grid;
}

.hidden {
  display: none;
}

.inline {
  display: inline;
}

.inline-block {
  display: inline-block;
}

.inline-flex {
  display: inline-flex;
}

.table {
  display: table;
}

.size-20 {
  width: calc(var(--spacing) * 20);
  height: calc(var(--spacing) * 20);
}

.h-\[37px\] {
  height: 37px;
}

.h-control {
  height: var(--spacing-control);
}

.w-1\/3 {
  width: 33.3333%;
}

.w-60 {
  width: calc(var(--spacing) * 60);
}

.w-\[673px\] {
  width: 673px;
}

.w-auto {
  width: auto;
}

.w-full {
  width: 100%;
}

.max-w-3xl {
  max-width: var(--container-3xl);
}

.max-w-full {
  max-width: 100%;
}

.min-w-0 {
  min-width: 0;
}

.flex-1 {
  flex: 1;
}

.flex-shrink, .shrink {
  flex-shrink: 1;
}

.grow {
  flex-grow: 1;
}

.table-fixed {
  table-layout: fixed;
}

.border-collapse {
  border-collapse: collapse;
}

.transform {
  transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, );
}

.zoom-8 {
  zoom: 8%;
}

.cursor-pointer {
  cursor: pointer;
}

.resize {
  resize: both;
}

.list-none {
  list-style-type: none;
}

.flex-wrap {
  flex-wrap: wrap;
}

.items-center {
  align-items: center;
}

.items-start {
  align-items: flex-start;
}

.justify-between {
  justify-content: space-between;
}

.gap-4 {
  gap: calc(var(--spacing) * 4);
}

.gap-6 {
  gap: calc(var(--spacing) * 6);
}

:where(.space-y-1 > :not(:last-child)) {
  --tw-space-y-reverse: 0;
  margin-block-start: calc(var(--spacing) * var(--tw-space-y-reverse));
  margin-block-end: calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)));
}

.truncate {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

.overflow-x-auto {
  overflow-x: auto;
}

.border {
  border-style: var(--tw-border-style);
  border-width: 1px;
}

.border-none {
  --tw-border-style: none;
  border-style: none;
}

.bg-accent {
  background-color: var(--color-accent);
}

.bg-ink {
  background-color: var(--color-ink);
}

.bg-surface-muted {
  background-color: var(--color-surface-muted);
}

.bg-transparent {
  background-color: #0000;
}

.p-0 {
  padding: 0;
}

.p-4 {
  padding: calc(var(--spacing) * 4);
}

.p-6 {
  padding: calc(var(--spacing) * 6);
}

.px-4 {
  padding-inline: calc(var(--spacing) * 4);
}

.px-8 {
  padding-inline: calc(var(--spacing) * 8);
}

.py-2\.5 {
  padding-block: calc(var(--spacing) * 2.5);
}

.py-3 {
  padding-block: calc(var(--spacing) * 3);
}

.py-16 {
  padding-block: calc(var(--spacing) * 16);
}

.pt-1 {
  padding-top: var(--spacing);
}

.pb-0 {
  padding-bottom: 0;
}

.pl-0 {
  padding-left: 0;
}

.pl-2 {
  padding-left: calc(var(--spacing) * 2);
}

.pl-3 {
  padding-left: calc(var(--spacing) * 3);
}

.text-left {
  text-align: left;
}

.text-right {
  text-align: right;
}

.font-sans {
  font-family: var(--font-sans);
}

.text-base {
  font-size: var(--text-base);
  line-height: var(--tw-leading, var(--text-base--line-height));
}

.text-display {
  font-size: var(--text-display);
  line-height: var(--tw-leading, var(--text-display--line-height));
}

.text-sm {
  font-size: var(--text-sm);
  line-height: var(--tw-leading, var(--text-sm--line-height));
}

.font-bold {
  --tw-font-weight: var(--font-weight-bold);
  font-weight: var(--font-weight-bold);
}

.font-light {
  --tw-font-weight: var(--font-weight-light);
  font-weight: var(--font-weight-light);
}

.font-medium {
  --tw-font-weight: var(--font-weight-medium);
  font-weight: var(--font-weight-medium);
}

.text-accent {
  color: var(--color-accent);
}

.text-danger {
  color: var(--color-danger);
}

.text-kdm-expired {
  color: var(--color-kdm-expired);
}

.text-kdm-future {
  color: var(--color-kdm-future);
}

.text-kdm-valid {
  color: var(--color-kdm-valid);
}

.text-line {
  color: var(--color-line);
}

.text-line-strong {
  color: var(--color-line-strong);
}

.text-status-muted {
  color: var(--color-status-muted);
}

.text-status-waiting {
  color: var(--color-status-waiting);
}

.text-success {
  color: var(--color-success);
}

.text-surface {
  color: var(--color-surface);
}

.text-surface-muted {
  color: var(--color-surface-muted);
}

.text-text {
  color: var(--color-text);
}

.text-text-heading {
  color: var(--color-text-heading);
}

.text-transparent {
  color: #0000;
}

.lowercase {
  text-transform: lowercase;
}

.uppercase {
  text-transform: uppercase;
}

.italic {
  font-style: italic;
}

.ordinal {
  --tw-ordinal: ordinal;
  font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, );
}

.tabular-nums {
  --tw-numeric-spacing: tabular-nums;
  font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, );
}

.opacity-40 {
  opacity: .4;
}

.opacity-60 {
  opacity: .6;
}

.opacity-65 {
  opacity: .65;
}

.ring {
  --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}

.outline {
  outline-style: var(--tw-outline-style);
  outline-width: 1px;
}

.blur {
  --tw-blur: blur(8px);
  filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
}

.filter {
  filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
}

.transition {
  transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
  transition-duration: var(--tw-duration, var(--default-transition-duration));
}

.ease-in-out {
  --tw-ease: var(--ease-in-out);
  transition-timing-function: var(--ease-in-out);
}

.select-all {
  -webkit-user-select: all;
  user-select: all;
}

.after\:clear-both:after {
  content: var(--tw-content);
  clear: both;
}

.after\:block:after {
  content: var(--tw-content);
  display: block;
}

.after\:content-\[\'\'\]:after {
  --tw-content: "";
  content: var(--tw-content);
}

@media (hover: hover) {
  .hover\:bg-\[\#0e6cab\]:hover {
    background-color: #0e6cab;
  }
}

@media (min-width: 927px) {
  .md\:ml-\[33\.3333\%\] {
    margin-left: 33.3333%;
  }

  .md\:hidden {
    display: none;
  }

  .md\:w-1\/2 {
    width: 50%;
  }

  .md\:w-1\/3 {
    width: 33.3333%;
  }

  .md\:w-1\/4 {
    width: 25%;
  }

  .md\:w-1\/6 {
    width: 16.6667%;
  }

  .md\:w-2\/3 {
    width: 66.6667%;
  }

  .md\:w-3\/4 {
    width: 75%;
  }

  .md\:w-7\/12 {
    width: 58.3333%;
  }
}

@media (min-width: 1586px) {
  .lg\:w-1\/4 {
    width: 25%;
  }
}

@property --tw-rotate-x {
  syntax: "*";
  inherits: false
}

@property --tw-rotate-y {
  syntax: "*";
  inherits: false
}

@property --tw-rotate-z {
  syntax: "*";
  inherits: false
}

@property --tw-skew-x {
  syntax: "*";
  inherits: false
}

@property --tw-skew-y {
  syntax: "*";
  inherits: false
}

@property --tw-space-y-reverse {
  syntax: "*";
  inherits: false;
  initial-value: 0;
}

@property --tw-border-style {
  syntax: "*";
  inherits: false;
  initial-value: solid;
}

@property --tw-font-weight {
  syntax: "*";
  inherits: false
}

@property --tw-ordinal {
  syntax: "*";
  inherits: false
}

@property --tw-slashed-zero {
  syntax: "*";
  inherits: false
}

@property --tw-numeric-figure {
  syntax: "*";
  inherits: false
}

@property --tw-numeric-spacing {
  syntax: "*";
  inherits: false
}

@property --tw-numeric-fraction {
  syntax: "*";
  inherits: false
}

@property --tw-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-shadow-color {
  syntax: "*";
  inherits: false
}

@property --tw-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}

@property --tw-inset-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-inset-shadow-color {
  syntax: "*";
  inherits: false
}

@property --tw-inset-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}

@property --tw-ring-color {
  syntax: "*";
  inherits: false
}

@property --tw-ring-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-inset-ring-color {
  syntax: "*";
  inherits: false
}

@property --tw-inset-ring-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-ring-inset {
  syntax: "*";
  inherits: false
}

@property --tw-ring-offset-width {
  syntax: "<length>";
  inherits: false;
  initial-value: 0;
}

@property --tw-ring-offset-color {
  syntax: "*";
  inherits: false;
  initial-value: #fff;
}

@property --tw-ring-offset-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-outline-style {
  syntax: "*";
  inherits: false;
  initial-value: solid;
}

@property --tw-blur {
  syntax: "*";
  inherits: false
}

@property --tw-brightness {
  syntax: "*";
  inherits: false
}

@property --tw-contrast {
  syntax: "*";
  inherits: false
}

@property --tw-grayscale {
  syntax: "*";
  inherits: false
}

@property --tw-hue-rotate {
  syntax: "*";
  inherits: false
}

@property --tw-invert {
  syntax: "*";
  inherits: false
}

@property --tw-opacity {
  syntax: "*";
  inherits: false
}

@property --tw-saturate {
  syntax: "*";
  inherits: false
}

@property --tw-sepia {
  syntax: "*";
  inherits: false
}

@property --tw-drop-shadow {
  syntax: "*";
  inherits: false
}

@property --tw-drop-shadow-color {
  syntax: "*";
  inherits: false
}

@property --tw-drop-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}

@property --tw-drop-shadow-size {
  syntax: "*";
  inherits: false
}

@property --tw-ease {
  syntax: "*";
  inherits: false
}

@property --tw-content {
  syntax: "*";
  inherits: false;
  initial-value: "";
}
/* ==================== THE CONTROL KIT ====================
   Design-system contract (consolidation + reviewer verdict
   2026-07-26): every form-control property is defined ONCE — here as
   tokens/component variants; icon/tree geometry in
   src/features/deliver/treeIconRegistry.ts (sealed D-037). PAGES
   CONSUME, NEVER DEFINE: no padding/height/focus literal on a form
   control outside this contract.
   Verdict state: the kit ARCHITECTURE stands, the consolidation's
   visual deltas are reverted to the pre-consolidation look via the
   named component variants below — with ONE exception: the control
   inset is 16 globally. Out of scope: buttons' inner padding, the
   34px toggle controls. */
:root {
  /* THE inset: inner text inset of every field (reviewer: 16
     everywhere — supersedes the 12px token and the date-field 12) */
  --fs-control-inset: 16px;
  /* TWO AXES, TWO CONSTANTS, TWO HOMES (G2b v2). Both measured off
     Tom's mock (parity/references/homevideo/referenz-richtig.png, a 2x
     capture: rows 80 image px apart, label ink 28 image px past the
     box's paint edge).

     HORIZONTAL — the icon/box -> text distance is GLOBAL: every surface
     that pairs a mark or a box with a label rides it (conversion lists,
     the cinema tab, the deliver tree's name cell, /transfers, the
     menus, every toggle label seat). Its home is the registry
     (GAP_ICON_TEXT), bridged onto :root at boot; the value below is the
     stylesheet's readable fallback.

     VERTICAL — the pitch is NOT global: it follows the row's CONTENT.
     Only a row with an interactive checkbox takes it (see the consumer
     block below); icon rows keep their own tight rhythm.

     ONE CHECKBOX, APP-WIDE (M4b/O6, corrected by M4c/P1+P2). There were
     two painted sizes in the same family — the base 34 and a compact 29
     — plus a third and fourth in the admin family and a fifth drawn by
     the deliver tree. They are one token.

     M4c REVERSES M4b's choice of value: 34 is the standard, not 29.
     /transfers is the surface that settles it — its rows are built
     around the larger box and shrinking it caused more trouble there
     than the drift it removed.

       --fs-checkbox-size   29 (M4b)  ->  34   (M4c/P1)
       --fs-checkrow-pitch  42 (M4b)  ->  46   (M4c/P2, derived below)

     THE PITCH IS DERIVED, not hand-set: the visual gap between two
     adjacent checkbox BOXES is 12px everywhere, so a row of boxes is
     one box plus one gap tall. Change the box and the rhythm follows.

     Rows where expanded content or a wrapped second line sits between
     two boxes are the explicit exception (Tom): box-to-box cannot mean
     anything there, and nothing asserts it. */
  --fs-checkbox-size: 34px;
  --fs-checkbox-gap: 12px;
  --fs-checkrow-pitch: calc(var(--fs-checkbox-size) + var(--fs-checkbox-gap));
  /* M4d/P1 — THE CHAIN GAP. One value on both sides of the box:
     chevron -> box and box -> content. It was 14 (the homevideo mock's
     icon->text distance); the chain ruling supersedes it with 10.
     Bridged from the registry (GAP_ICON_TEXT) at boot — the literal
     below is the stylesheet's readable fallback. Two adjacent status
     MARKS keep GAP_ICON (7.75, sealed): Tom's exception. */
  --fs-checkrow-gap: 10px;
  /* the chevron column = the painted width of the EXPANDED chevron
     (registry CHEVRON_COL, measured 12.59 on screen). Bridged at boot. */
  --fs-chain-chevron: 12.56px;
  /* M4d/P6: THE SPEC COLUMNS. The playlist's specification line is the
     same two columns whether it is rendered one-line (desktop/tablet) or
     stacked (mobile), so both read the width from here. THEATRICAL is
     the reference: these are the widths its one-line cells have always
     had, and its stacked box already rendered at 48.75/97.52 — the
     stacked box now lands on them exactly instead of near them. */
  /* THE SPEC SLOTS (M4g/O3): each column is as wide as its own widest
     value, measured across the catalogue — 20 for a language code, 61
     for a subtitle list, 80 for an aspect, 89 for a runtime — rounded
     up. The GAP between columns is not part of a slot; it is its own
     token below, so widening the air never silently widens a column.
     Column 1 carries language and dimension, column 2 subtitles and
     sound, column 3 aspect and duration. */
  --fs-spec-col-1: 22px;
  --fs-spec-col-2: 52px;
  --fs-spec-col-3: 86px;
  /* AUDIO gets its own slot: today's catalogue holds "5.1" and "7.1",
     but the format names that belong in this column — Atmos, D-Box —
     are three times as wide, and a slot sized on the short case would
     let one of them push its neighbours or wrap. */
  /* THE WIDTH THE /transfers USER AND SITE COLUMNS SHARE (D-121,
     owner's third correction: "they cannot have separate widths in the
     CSS at all"). One definition, read by one rule that carries both
     selectors — see kit-tables, which also carries the arithmetic and
     what the number cost. At :root because every --fs-* token has to
     resolve there (e2e/smoke sweeps them). */
  --fs-transfer-people-col: 119px;

  --fs-spec-col-audio: 56px;
  /* THE GAP BETWEEN SPEC COLUMNS. Two named values because the two
     bands are not equally free: on the one-line band there is room to
     spend, on the stacked band the whole row — lead, chevron, box, the
     three slots and the action controls — has to fit 345px at a 390
     window, which leaves 14 and not a pixel more. */
  /* THE GAP BETWEEN SPEC COLUMNS. M4i widened it (32 tablet / 64
     desktop) to spend the width the run was leaving at its right;
     M4L reverses that on Tom's look at the corrected build — the wider
     spacing does not read well and the run goes back to the value it
     had. One number, both bands. */
  --fs-spec-gap: 20px;
  /* M4h/O4: 16, not 7. The stacked cell is wider than the grid inside
     it — measured 192.59 against 174 at a 390 window — so there were
     18.59 unused pixels sitting to the right of the duration column
     that the gaps can have. */
  --fs-spec-gap-mobile: 16px;
  /* THE GAP BETWEEN TWO ADJACENT BUTTONS (M4c/P11), one value app-wide.
     Measured off the reference Tom named — the Order popup's
     DELIVER TO CINEMA / CLOSE pair, which is two inline-block buttons
     with an ordinary word-space between them: 5px at the control font.
     The film edit form's Save/Cancel and Create-playlist/Ingest pairs
     already render the same 5. The only surface that had invented its
     own was the homevideo ORDER CONVERSION / RESTART pair at 16. */
  --fs-button-gap: 5px;
  /* M4T/O1: the distance between the target line's DIVIDER and whatever
     stands next to it — the organisation on a cinema delivery, the
     address itself on a web download. One value, both sides of the rule,
     both cases. It used to live on the organisation, so a row without
     one had no gap at all. */
  --fs-detail-divider-gap: 8px;
  /* M4T/O8: the film grid's tile gutter. The grid hangs one gutter
     outside the page content box on each side so the CARDS land on it
     (M4M/O2); anything that spans the grid full-width — the release-date
     heading and its rule — has to put the gutter back or it renders into
     the page margin. Stated once so the three rules cannot drift. */
  --fs-grid-gutter: 8px;
  /* THE CHIP's own lead (G2.3): the sealed D-033 chip draws a 3px
     self-coloured border and 5px of padding before its content. A chip
     field pulls its chip block back by this much, so the chip's content
     edge lands on --fs-control-inset — the same x as the empty state's
     placeholder text. Derived from .fs-chip, not a new hand-set value. */
  --fs-chip-lead: 8px;
  /* THE GRANT FORM'S BLOCK RHYTHM (D-141). One gap between the form's
     blocks — field groups and preview slots alike — replacing a
     .fs-form-group margin and a Tailwind mt-4 that collapsed into each
     other. 24px: more air than the 16 that survived the collapse, which
     is what the salutation was short of. */
  --fs-screener-block-gap: 24px;
  /* …and the tighter one INSIDE the validity pair, which is one control
     read as a unit rather than two blocks. */
  --fs-screener-pair-gap: 8px;
  /* SEAMS THAT CARRY THEIR OWN (D-142/D-143, the owner's correction to
     D-141). A form is not an even stack: one gap as the DEFAULT was
     right and fixed two that had been silently collapsing, but a block
     that belongs to the line above it sits TIGHT against it, and a
     paragraph of prose needs air.
     
     ONE tight value, not one per seam: the remark box under the
     salutation and the validity pair under the line that starts the
     screener are the same relationship, so they read the same. */
  --fs-screener-tight-gap: 0px;
  --fs-screener-closing-gap: 16px;
  /* THE mobile page edge (promoted, deliver-mobile round 2026-07-26):
     the legacyref-extracted 15px side margin every page uses below
     the 927 master breakpoint. Consumers: .fs-container,
     .fs-container-fluid@mobile, .app-navbar-meta/-main@mobile,
     .app-nav--open, .dt-section@mobile. */
  --fs-page-inset-mobile: 15px;
  /* THE page edge above the master breakpoint (M4f/O2, promoted from
     .fs-container-fluid's literal): the large margin is the normal one
     — it applies at TABLET and above without exception, and the 15 is
     the mobile-only value. Consumers: .fs-container-fluid,
     .fs-container--wide@>=927, .fd-hero-width@>=927. */
  --fs-page-inset: 32px;
  /* THE ROW INSET (M4h/O3): the air a row keeps INSIDE the page's own
     margin — 10px before the first mark on the left, 10px after the
     last one on the right, on every band. It is one value serving both
     sides, so a row can never be tight on one and loose on the other.
     Not the chain's gaps (those are mark-to-mark and mark-to-text
     distances between the row's parts); this is the row's distance from
     the container it sits in. */
  --fs-row-inset: 10px;
  /* THE COVER'S TWO FRAME WIDTHS (M4P). The grey ring a cover always
     wears, and the blue band it wears when selected — the second is
     drawn INWARD from the same outer edge, so selecting one changes
     colours and nothing else. Sampled off the pre-M4O build: the blue
     band was 4px there, and it is 4px here. */
  --fs-cover-frame: 2px;
  --fs-cover-select: 4px;
  /* The map's chrome clears the navigation by this much (M4h/O5). It
     lives here because its NAME says page-level, and a --fs-… declared
     on a surface is a token the app cannot check: the boot-time
     resolver reads them off :root. Hand-set; the value is Tom's call. */
  --fs-map-control-drop: 18px;
  /* THE PANE's top padding: the fixed header's band plus the standard page
     air below it (extracted; the header itself measures 105.5). One home,
     because a full-bleed page has to be able to cancel it — the map does
     (kit-misc #map), and a stale second copy of this number was the white
     strip under the bar. */
  --fs-pane-pad-top: 136px;
  /* K0: the closing band's height, hand-set (measured 220px on the
     rendered footer). The page area is a screenful minus the pane's top
     padding minus THIS, so a short page shows the band at the bottom of
     the first viewport instead of one scroll below it. */
  --fs-footer-band: 220px;
  /* THE FIXED HEADER's own height (extracted: meta bar + nav bar measure
     105.5 at every width). The pane's padding above is that plus the
     standard page air; a full-bleed page cancels only the AIR, so it starts
     at the header's edge — flush, with nothing of its own hidden behind the
     bar. The map's zoom control sat half under the bar because it cancelled
     the whole padding instead. */
  --fs-header-height: 105.5px;
  /* THE LOGIN GROUND (G4.2): the sign-in pages are dark from the first
     frame, before any photo has arrived. Black is production's own body
     colour and the measured dominant tone of the rendered page (the mask
     over the photos reads rgb(1,1,1) across 30% of the pixels), so there is
     nothing to see when a photo fades in over it. */
  --fs-login-ground: #000000;
  /* THE HEADER SEARCH FIELD (G3.3). One width for both layouts: the
     desktop width is also the mobile width, because a bigger field is
     better on a phone and the space is there. It gives way only when the
     air left next to the hamburger would fall below the minimum gap —
     declaratively, through max-width, so nothing is measured at runtime
     and nothing jumps on load.
       width 479  the field (rounds 15/16, production-extracted)
       toggler 52.6  the hamburger's box (D-020)
       gap-min 16    the air between field and hamburger — the HARD
                  constraint at every width; there is deliberately no
                  width floor beside it, because a floor wins over the cap
                  in the cascade and would eat the gap at the narrow end */
  --fs-search-width: 479px;
  --fs-search-toggler: 52.6px;
  --fs-search-gap-min: 16px;
  /* deliver CPL grouping (mobile round 2026-07-26): tight INSIDE a
     group (checkbox pair <-> its own CPL name when the name wraps),
     clearly larger BETWEEN groups — proximity carries the grouping. */
  --dt-cpl-gap-in: 4px;
  --dt-cpl-gap-between: 16px;
  /* THE field box = production's (reviewer verdict 2026-07-27 with
     DevTools measurements, supersedes the v6/D-038 37.5): outer 44,
     padding 8x12 — with the 4px border the VISUAL text inset stays 16
     (4 border + 12 pad). Selects keep their own sealed 37.5 line
     (--fs-select-height below). */
  --fs-field-height: 44px;
  --fs-field-pad-x: 12px;
  --fs-select-height: 37.5px;
  /* the deliver date fields: 162 (the reviewer's FINAL call
     2026-07-27; supersedes 160/175/148). Content box = 162 − 8 border
     − 24 padding = 130px — the pathological zero-heavy "30.12.2026
     20:00" (130px @16/300) fits exactly, the realistic widest
     "28.12.2026 23:59" (125px) with 5px air. */
  --fs-date-field-width: 162px;
  /* INPUT-FIELD text (reviewer round 2026-07-27, supersedes the D-038
     14: production renders form inputs/textareas/date fields at
     16px/300/20px in BOTH contexts — screener form on white AND the
     deliver grey panel; extracted element-level 2026-07-27). */
  --fs-control-font-size: 16px;
  --fs-control-font-weight: 300;
  --fs-field-line-height: 20px;
  /* SELECTS + BAR CONTROLS stay at production's own values (extracted
     2026-07-27: select 14px/300/17.5, 34px line — production keeps
     selects smaller than inputs; NOT superseded). Own token so the
     16px input bump can never drag them along silently. */
  --fs-select-font-size: 14px;
  /* THE field edge (production, both contexts): the field owns its
     border as part of its ONE definition — reads as a box on white
     (screener) and matches production on the grey panel (deliver).
     The width is its own token: label offsets, the chipfield inset
     math and the deliver select alignment all derive from it. */
  --fs-field-border-width: 4px;
  --fs-field-border: var(--fs-field-border-width) solid var(--color-surface-muted);
  /* THE focus frame (date fields only — see below) */
  --fs-focus-color: rgb(102, 175, 233);
  --fs-focus-width: 4px;

  /* ---- component variants (pre-consolidation look, restored) ---- */
  /* filter-bar controls: production 34px line (round 4) */
  --fs-bar-control-height: 34px;
  /* --fs-bar-control-pad-top (2px) RETIRED by D-184: a bar control has no
     vertical padding any more. It was the 2/0 asymmetry that put the
     pulldown's text a pixel off the bar's own line. */
  --fs-bar-select-clearance: 30px; /* text-to-arrow zone */
  --fs-bar-arrow-offset: 12px;     /* arrow inset from the right */
  /* header search (production nav geometry, D-020 context) */
  --fs-search-height: 48px;
  --fs-search-pad-y: 14px;
  /* generic white input (production .form-control impression) */
  --fs-input-pad-y: 8px;
  --fs-input-font-size: 16px;
  /* admin fs-field family (production register) */
  --fs-field-pad-y: 0.5rem;
  --fs-field-font-size: 1rem;
  /* ported native selects */
  --fs-native-pad-y: 0.375rem;
  --fs-native-clearance: 1.75rem;
  --fs-classic-pad-y: 0.625rem;
  --fs-classic-clearance: 2rem;
  --fs-select-sm-pad-y: 0.375rem;
  /* The DISTRIBUTOR filter pulldown carries NO width definition —
     intrinsic native-select width, sized by its widest option
     ("wichtiges Feld und darf etwas Platz haben", reviewer verdict
     2026-07-26). Deliberate: intrinsic by design, no constant. The
     other bar selects keep their fixed widths. */
  /* --fs-chipbox-pad-y (3px) RETIRED by D-184 with the same rule: the
     chip box's text sits on the bar's line, so the box has no vertical
     padding to centre a shorter line inside. The chip itself is
     unmoved — 27 in 34 still centres at 3.5, which is what
     --fs-chipfield-inset already says. */
  /* chipfield height = THE field height (44) since 2026-07-27.
     THE uniform chip gap (reviewer crop 2026-07-27): one value all
     around the chip block — left inset before the first chip, the
     top/bottom air and the inter-chip gap. 4.5 = (44 field − 8 border
     − 27 chip) / 2, i.e. exactly the centering air of the sealed
     D-033 chip in THE field box; the caret follows the same inset. */
  --fs-chipfield-gap: 4.5px;
  /* THE bar chip/filter field's DEFAULT width (D-111 part 4, third
     review): THE standard is the films Distributor pulldown as it
     renders (measured 220) — one shared token for every bar chip field
     on films, transfers and screeners, so nothing jumps between the
     pages. The floor rule stays: never narrower whatever the content;
     content may widen the field up to its row's space, on ONE line
     forever. Geometry pins the token against the live Distributor. */
  /* D-121: 200, not 220 — the owner's ruling on weight. It is the
     field's RESTING width wherever the element appears, and one chip
     must fit inside it (see --fs-chip-max below). */
  --fs-chipfield-width: 200px;

  /* THE FIELD'S INSET AROUND A CHIP — the same on all four sides
     (D-121, owner's ruling). MEASURED: the field is 34 high and a chip
     is 27, so the air above and below it is (34 - 27) / 2 = 3.5. The
     horizontal inset is now that same number, because the gap left of
     the chip read as far bigger than the gap above it — it was 8px,
     from `--fs-control-inset (16) - --fs-chip-lead (8)`, a rule that
     put the chip's TEXT on the placeholder's 16px inset. That rule is
     superseded: an equal optical inset around the chip wins over
     aligning its text with the placeholder's. */
  --fs-chipfield-inset: 3.5px;

  /* THE FIELD KEEPS A CLICKABLE STRIP BESIDE THE CHIP (D-122, owner's
     correction of D-121). A chip filling the field to its inner edge
     was too aggressive: a person must be able to click into the field
     next to a chip, and the field's end wants a little more grey than
     one pixel of caret.

     THE RESERVE IS 24px, and it is not a new number — it is the
     clearance the field already carried on its right before D-121 spent
     it, and the width of an ordinary click target. It holds the gap
     after the chip and the caret itself, both clickable:

       field                                    200
       - the inset, both sides   2 x 3.5 =       -7
       - the reserve (gap 4.5 + caret 19.5)     -24
                                               ----
       chip                                     169

     Inside the chip the label takes what is left after the chip's own
     furniture — frame 3+3 border and 5+5 padding = 16, the × 8.19, and
     the word-space before it 3.89 — so the label is cut at 140.92. It
     is the CHIP that carries the cap and the label that ellipsizes
     inside it, so the chip's right edge lands exactly on the field's
     inner right edge rather than near it.

     ONLY SHORTEN, NEVER LENGTHEN: this is a max-width, so a short value
     leaves a narrow chip and nothing is padded out. */
  --fs-chipfield-reserve: 24px;

  /* THE SUGGESTION PANEL'S WIDTH — one number, whatever it holds
     (D-123). It used to be `width: max-content` between a 160px floor
     and a 420px cap, so it resized itself as results arrived: the
     opening set, then a typed page, then the next page, each a
     different width under the pointer.

     350 (D-127, owner's ruling). 420 was never a decision: it was the
     max-width the panel carried while it sized itself to content, and
     fixing the width promoted that ceiling into the number.

     NOTHING IS TRUNCATED. A long entry WRAPS onto a second line, which
     is fully readable where a cut title is not — so there is no
     ellipsis in this panel and the entry's own height varies. It is
     still wider than the 200px field beneath it: a suggestion is a
     whole title or address, while the field only has to hold a chip. */
  --fs-suggest-panel-width: 350px;
  --fs-chip-max: calc(
    var(--fs-chipfield-width) - 2 * var(--fs-chipfield-inset) - var(--fs-chipfield-reserve)
  );

  /* THE GAP BEFORE A REMOVE × — one word-space, because that is the
     relationship the reference has (D-121, owner's ruling). The film
     conversions row writes "name@example.com ×" as ONE line of running
     text with a literal space between them; a chip is a flex box and
     has no word-spaces, so the same relationship has to be spelled as a
     gap. Measured in the chip's register (Gotham 300 14/21): a space
     advances 3.89px, i.e. 0.278em — em, so it stays one space at any
     size the surrounding text takes. */
  --fs-remove-x-gap: 0.278em;
}


/* ---- FOCUS (the one scoped definition — no per-page rules) ----
   The blue INSET frame applies EXCLUSIVELY to the date fields: the
   picker opens there, and the frame marks the active popup surface
   (reviewer verdict). Everything else keeps its pre-consolidation
   behavior, restored below. */
.fs-dtp-field:focus,
.fs-dtp-field:focus-visible,
.fs-dtp-field--open {
  outline: none;
  /* the field now owns a real 4px border (2026-07-27) — the frame is
     that border turning blue (production's focus mechanism), not a
     shadow stacked inside the grey border. Same law, same visual:
     a 4px blue frame at the box edge, on date fields ONLY. */
  border-color: var(--fs-focus-color);
}
/* native selects: menu shows focus; UA ring suppressed */
select:focus,
select:focus-visible {
  outline: none;
  box-shadow: none;
}
/* icon-anchor family (collapse chevrons, transfer status/type links):
   the UA :focus-visible ring drew a blue rounded frame around the
   version collapse chevron (reviewer defect, Icons_falsch.png rollout
   2) — focus frames exist ONLY on the date fields. */
.ft-toggle:focus,
.ft-toggle:focus-visible,
.ft-arrow:focus,
.ft-arrow:focus-visible,
.ft-arrow-targets:focus,
.ft-arrow-targets:focus-visible,
.transfer-icon:focus,
.transfer-icon:focus-visible,
.transfer-type-icon:focus,
.transfer-type-icon:focus-visible {
  outline: none;
}
/* restored pre-consolidation focus styling (border-color impressions;
   on borderless variants they are inert by design, as before) */
.fs-field:focus {
  color: #474747;
  background-color: #fff;
  border-color: #66afe9;
  outline: none;
}
.fs-input:focus {
  border-color: rgb(102, 175, 233);
}
.fs-dtp-time-input:focus {
  border-color: rgb(102, 175, 233);
}
.fs-select-native:focus {
  border-color: #51a7e8;
  outline: none;
}
/* ============ THE INNER-CHECK POSITION — ONE DEFINITION ============
   Reviewer verdict 2026-07-27: the /deliver (fs-toggle) check position
   is the reference. Every checkbox centres its check glyph in the box.
   The sealed .fs-toggle paints a centered 16px background (app.css,
   pixel-parity 0-diff — left untouched, it already sits at this same
   centred position). The .fs-check-box family (film-edit, admin/login
   forms, CheckboxRow) centres the SAME 16px <Icon name="check"> HERE,
   so its ink-vs-box centre matches deliver instead of riding ~1px high
   on the inline line-box. ONE place, no per-page nudge, no second
   position value. These boxes are the "control anatomy" census
   exclusion (kept OUT of MarkIcon) — that exclusion does NOT exempt
   them from this no-duplication rule. Loaded last, so this centring
   wins over the block-flow default without touching the variant rules. */
.fs-check-box {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* THE CHECKBOX ROW (G2.1): the paint is .fs-toggle's (sealed, scoped);
   this is the row rhythm and nothing else. A row is at least one pitch
   tall, so a list of them breathes evenly whatever the surface. */
/* :not(--inline) and not a bare .fs-checkrow: the sealed paint rules name
   two classes, so the row's own geometry has to match that weight to say
   "a row is BLOCK-level" over the bar toggle's inline-flex. */
.fs-checkrow:not(.fs-checkrow--inline) {
  min-height: var(--fs-checkrow-pitch);
  /* a row is a row: the box and its label sit on one centred line, and
     the pitch is the row's own height — no stacking margins on top of it
     (the .fs-check--compact nudge is a form-row nudge, not a list one) */
  display: flex;
  align-items: center;
  margin-top: 0;
}
/* THE PITCH FOLLOWS THE ROW'S CONTENT (G2b v2, reviewer rule).
   A row with an interactive CHECKBOX in it gets this airy pitch — the
   box needs the room. A row WITHOUT one keeps its own tight rhythm:
   the cinema tab's delivery entries carry status ICONS, not checkboxes,
   and neither does a /transfers row. v1 handed the pitch to a shared row
   base and it leaked onto both; the pitch reaches a surface through the
   checkbox ROW alone now.
   Two consumers, and they are the only legal ones (asserted by the
   checkboxPitchOnlyOnCheckboxRows source gate):
     .fs-checkrow          — the row element itself, wherever it renders
     .fd-conversion-row td — the HOMEVIDEO conversion list, whose cell
                             hosts an inline checkbox row and therefore
                             owns its height; conversion checkboxes exist
                             only under HOMEVIDEO.
   O6: the deliver page's 42 IS this token now — it was the living
   reference and the films value moved onto it, so there is one pitch and
   not two. */
/* the selector carries the weight it needs to beat the asset-details
   table's own 4px cell padding — and it still names nothing but the
   conversion row, so the pitch cannot reach a neighbouring icon row */
.fs-table .ft-body--asset-details tr.fd-conversion-row td {
  height: var(--fs-checkrow-pitch);
  padding-top: calc((var(--fs-checkrow-pitch) - var(--fs-checkbox-size)) / 2);
  padding-bottom: calc((var(--fs-checkrow-pitch) - var(--fs-checkbox-size)) / 2);
}
.fs-checkrow input {
  /* the box is the box: a row is a flex container now, and a flex item
     may shrink — the conversion list's 72px name edge squeezed the 34px
     box to 32 before this line. */
  flex: none;
}
.fs-checkrow--inline {
  /* NOT a row in a list: a bar toggle, a table cell, a form row. It takes
     its height from what it sits in and keeps that surface's own paint
     geometry — only list rows carry the pitch. */
  min-height: 0;
  display: inline-flex;
}
