/* hudr.net — THE "BUILT IN <COUNTRY>" BADGE. One stylesheet, every surface.
 *
 * Loaded by the ux shell, by the logged-out auth layout, and by the admin panel's preview — so the
 * thing an owner picks an option from in the admin is styled by the exact rules that will run on the
 * site. It lived in devsocial.css before, which only the signed-in ux pages load; the moment the
 * badge was wanted on login/signup too, keeping it there would have meant a second copy of a
 * five-beat animation with a settings contract. One file instead.
 *
 * THE CONTRACT WITH THE SERVER. FlagBadgeService validates the owner's choice against a fixed
 * catalogue and sends KEYS; flag-badge.js turns each into a class:
 *     fw-<flag_style>   on .brand-flag-wrap   — five of them
 *     tw-<text_style>   on .brand-flag-word   — ten
 *     tc-<text_color>   on .brand-flag-word   — colour treatment
 *     tf-<text_font>    on .brand-flag-word   — font family
 *     fl-<layout>       on .brand-flag        — one line or two
 * A key with no rule here paints nothing, which is why the server falls back to a default rather
 * than passing through whatever is in the settings row. ADD TO ALL THREE — catalogue, CSS, admin
 * dropdown — or the option does not exist.
 *
 * THE ASSET, MEASURED, because most numbers below derive from it: /assets/emoji/img-apple-64/*.png
 * is 64x64 RGBA and the opaque flag occupies about x3-60, y11-52 — ROUGHLY A THIRD IS TRANSPARENT
 * MARGIN. The hoist (the flag's left edge, where a real flag is pinned) is 3/64 = 4.7%. Two rules
 * follow and they are not negotiable: anchor transforms at the hoist, and mask anything painted over
 * the flag to the flag's own alpha.
 */

/* =========================================================================================
   THE SLOT
   ========================================================================================= */

/* THE WORDMARK STAYS PUT. This used to share a slot with it and swap visibility, so for five seconds
   a minute the header said "built" where the product name should be. It now sits AFTER the wordmark
   and the wordmark is never touched.

   WIDTH IS TRANSITIONED, NOT JUMPED. The badge is empty, then a flag, then a word or two, then empty
   again — four widths in five seconds, in a flex row whose other children would snap sideways each
   time. flag-badge.js measures each beat on a hidden clone and sets an exact pixel width; this
   transition carries it. overflow:hidden makes a mid-transition frame show a clipped word rather
   than an overflowing one.

   `width` IS a layout property and this animates it deliberately: absolute positioning would take
   the badge out of flow and let it collide with the header's search box, and a fixed reserved width
   would leave a permanent gap beside the wordmark on every page. */
.brand-flag{
  display:inline-flex;align-items:center;line-height:1;
  width:0;overflow:hidden;white-space:nowrap;
  opacity:0;transform:translateY(3px);
  /* NEGATIVE MARGIN EATS THE PARENT'S FLEX GAP. `.logo` is `display:flex; gap:9px`, and a zero-WIDTH
     flex item is still a flex item — so a collapsed badge left a permanent 9px hole after the
     wordmark on every page, all day, for something that shows five seconds a minute. width:0 alone
     does not close it. It animates back to 0 as the slot opens, which is also what gives the badge
     its breathing room while it is out. */
  margin-left:-9px;
  transition:width .34s cubic-bezier(.22,.61,.36,1),margin-left .34s cubic-bezier(.22,.61,.36,1),
             opacity .22s ease,transform .22s ease;
}
.brand-flag.is-in{opacity:1;transform:none;margin-left:0}

/* THE WORDS SIT ON THE WORDMARK'S LINE; THE FLAG STAYS CENTRED.
   The parent centres its children, which is right for the flag — a picture wants its middle on the
   wordmark's middle. It is wrong for text: this slot sets line-height:1, so a word's box is tight
   (~14px) while "hudr" carries the header's full line box (~30px). Centring a short box against a
   tall one puts the short one's BASELINE 3px higher, and 3px is plenty to read as "the small text is
   floating above the name" — which is exactly what it looked like.

   TWO THINGS WERE TRIED FIRST AND BOTH FAILED, so do not "simplify" this back into either of them:
     · `align-self:baseline` on the slot — a flex item whose `overflow` is not visible has no baseline
       to share, so the algorithm synthesises one from the box's bottom edge. Measured: the word went
       28px HIGH instead of 3. The slot is overflow:hidden by necessity (it is what makes the width
       animation read as a wipe), so baseline alignment is simply not available to it.
     · giving the slot the wordmark's own line-height — this made the two boxes identical (both 30px,
       same top) and moved the baseline by exactly nothing, because the residual is a font-metric
       difference inside the box, not a box-height difference.
   So the offset is corrected where it actually is: on the text, in `em`, so it stays proportional at
   any `text_size` the owner sets. `top` rather than `transform` because all ten word animations own
   the transform property. */
.brand-flag.bf-text .brand-flag-word{position:relative;top:.16em}

/* Off-screen measuring clone. It must lay out exactly like the real slot's content and never be seen
   or read: position:absolute keeps it out of flow, visibility:hidden keeps it out of the
   accessibility tree, and living inside the same parent is what makes an em-sized flag and an
   800-weight word measure as what they will actually paint as. */
.brand-flag-measure{
  position:absolute;left:-9999px;top:0;
  display:inline-flex;align-items:center;line-height:1;white-space:nowrap;visibility:hidden;
  pointer-events:none;
}

/* =========================================================================================
   LAYOUT  (fl-*)
   ========================================================================================= */

/* One line: the flag, then each word in turn, all on the header's baseline. */
.brand-flag.fl-inline,
.brand-flag-measure.fl-inline{align-items:center}

/* Two lines at once — "built" above, "in india" below, which is what the owner asked for.
   The header row has a fixed height and 19px type, so the two lines are scaled to .62em each with a
   1.05 line-height: 2 x .62 x 1.05 = 1.30em, which is SHORTER than the single 1em line it replaces,
   so the header cannot grow. align-items stays center so the block sits on the wordmark's optical
   centre rather than its baseline — a stacked block aligned to a baseline hangs low and looks
   dropped. */
.brand-flag.fl-stacked,
.brand-flag-measure.fl-stacked{align-items:center}
.brand-flag-stack{
  display:inline-flex;flex-direction:column;justify-content:center;
  line-height:1.05;text-align:left;
}
.brand-flag-stack .brand-flag-word{font-size:.62em;display:block}
/* The second line is the qualifier ("in india"), so it sits a touch quieter than the first. */
.brand-flag-stack .bfs-2{opacity:.85}

/* =========================================================================================
   THE WORDS — base
   ========================================================================================= */
.brand-flag-word{
  font-weight:800;letter-spacing:-.02em;color:inherit;white-space:nowrap;
  display:inline-block;   /* transforms need a block box; inline text ignores translate/scale */
}

/* Fonts (tf-*). ONLY Inter and JetBrains Mono are actually shipped by this site — every other option
   is a system stack, so it renders with whatever the visitor's device has and will differ between a
   Mac, a Windows PC and an Android phone. That is a real limitation and the admin form says so;
   downloading a webfont for a five-second-a-minute badge is not a trade worth making. */
.brand-flag-word.tf-header{font-family:var(--ff-ui,'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif)}
.brand-flag-word.tf-system{font-family:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}
.brand-flag-word.tf-serif{font-family:Georgia,'Times New Roman',Times,serif;letter-spacing:0}
.brand-flag-word.tf-mono{font-family:var(--ff-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);letter-spacing:-.04em}
.brand-flag-word.tf-rounded{font-family:ui-rounded,'SF Pro Rounded','Segoe UI Variable Display','Nunito',system-ui,sans-serif}
.brand-flag-word.tf-condensed{font-family:'Arial Narrow','Roboto Condensed','Segoe UI Semibold',system-ui,sans-serif;letter-spacing:0}

/* =========================================================================================
   COLOUR TREATMENTS  (tc-*)
   ========================================================================================= */

.brand-flag-word.tc-inherit{color:inherit}
.brand-flag-word.tc-brand{color:var(--accent,#0A66C2)}
.brand-flag-word.tc-gold{
  background:linear-gradient(180deg,#F7D774 0%,#C9962B 55%,#8A6516 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* THE TRICOLOUR, AND THE HONEST PROBLEM WITH IT.
   India's flag is saffron / WHITE / green. Painting the middle third of the letters white makes that
   third INVISIBLE on hudr's light header — not subtle, gone. So the middle band is `currentColor`,
   the header's own ink: dark on light, light on dark, legible in both. The result reads as the
   tricolour because the eye takes the saffron and green bands as the signal; a literally white band
   would read as broken text. If you want the true white band, it only works on a dark header.

   background-clip:text is a paint-time effect and costs more than a flat colour. It runs on two short
   words for a second each, so that is fine here and would not be on body text. */
.brand-flag-word.tc-tricolour{
  background:linear-gradient(180deg,
    #FF9933 0%, #FF9933 34%,
    currentColor 34%, currentColor 66%,
    #128807 66%, #128807 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* The SELECTED country's colours, sent resolved by the server as --bfc1/--bfc2 (it keeps a small
   table of unambiguous palettes). Falls back to the header ink when we do not have that country, so
   an unlisted country looks deliberate rather than broken. */
.brand-flag-word.tc-country{
  background:linear-gradient(180deg,
    var(--bfc1,currentColor) 0%, var(--bfc1,currentColor) 48%,
    var(--bfc2,currentColor) 52%, var(--bfc2,currentColor) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* No background-clip:text support → transparent text would be an invisible badge. Take the flat
   colour instead; it is the same information without the flourish. */
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .brand-flag-word.tc-tricolour,
  .brand-flag-word.tc-country,
  .brand-flag-word.tc-gold{background:none;color:inherit}
}

/* =========================================================================================
   THE WORDS — the ten animations  (tw-*)
   -----------------------------------------------------------------------------------------
   Each word is on screen for about a second before it is replaced, so every one of these must READ
   COMPLETELY inside ~600ms and then REST. Anything still moving when the beat ends looks broken, so
   there are no infinite loops here except `shine`, whose loop is the effect and is slow enough to
   read as one pass.
   ========================================================================================= */

.brand-flag-word.tw-rise{animation:hbRise .42s cubic-bezier(.2,.75,.25,1) both}
@keyframes hbRise{from{opacity:0;transform:translateY(.42em)}to{opacity:1;transform:none}}

.brand-flag-word.tw-fade{animation:hbFade .34s ease both}
@keyframes hbFade{from{opacity:0}to{opacity:1}}

/* clip-path, not width: animating width would reflow the slot mid-beat and fight the slot's own
   width transition. */
.brand-flag-word.tw-wipe{animation:hbWipe .46s cubic-bezier(.22,.61,.36,1) both}
@keyframes hbWipe{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}

/* Typewriter WITHOUT per-letter markup: a stepped clip reveals the word a character-width at a time.
   12 steps is more than any of these words has letters, so it reads as typing on all of them. */
.brand-flag-word.tw-type{animation:hbWipe .5s steps(12,end) both}

.brand-flag-word.tw-blur{animation:hbBlur .44s ease-out both}
@keyframes hbBlur{from{opacity:0;filter:blur(6px)}to{opacity:1;filter:blur(0)}}

/* From the flag's side, so the word reads as arriving from where the flag just was. */
.brand-flag-word.tw-slide{animation:hbSlide .42s cubic-bezier(.2,.75,.25,1) both}
@keyframes hbSlide{from{opacity:0;transform:translateX(-.6em)}to{opacity:1;transform:none}}

.brand-flag-word.tw-spring{animation:hbSpring .52s cubic-bezier(.34,1.56,.64,1) both}
@keyframes hbSpring{from{opacity:0;transform:scale(.72)}to{opacity:1;transform:scale(1)}}

.brand-flag-word.tw-flip{animation:hbFlip .5s cubic-bezier(.2,.75,.25,1) both;transform-origin:50% 0}
@keyframes hbFlip{
  from{opacity:0;transform:perspective(240px) rotateX(-78deg)}
  to{opacity:1;transform:perspective(240px) rotateX(0)}
}

.brand-flag-word.tw-zoom{animation:hbZoom .4s cubic-bezier(.2,.75,.25,1) both}
@keyframes hbZoom{from{opacity:0;transform:scale(.82)}to{opacity:1;transform:scale(1)}}

/* A highlight sweeping through the letters. It needs background-clip:text, so it OVERRIDES any
   colour treatment for the duration — the two cannot share the background. Documented rather than
   prevented: picking both is a legitimate "I want the shine" choice. */
.brand-flag-word.tw-shine{
  background:linear-gradient(100deg,
    currentColor 0%, currentColor 40%,
    rgba(255,255,255,.95) 50%,
    currentColor 60%, currentColor 100%);
  background-size:250% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:hbFade .3s ease both,hbShine 2.2s ease-in-out .1s infinite;
}
@keyframes hbShine{0%{background-position:120% 0}60%,100%{background-position:-40% 0}}

/* =========================================================================================
   THE FLAG — base
   ========================================================================================= */
.brand-flag-wrap{
  position:relative;display:inline-block;line-height:0;
  /* The hoist: the flag's left edge inside the PNG (3/64). Every transform is anchored here, which
     is the single biggest reason it reads as cloth and not as a sticker — displacement is zero at
     the pin and grows toward the fly.

     THIS DECLARATION IS THE ONE THAT WAS MISSING. The variable was defined here and the comment
     claimed every transform used it, but only .brand-flag-img ever applied it — and the FUNDAMENTAL
     sway lives on this wrapper. So the largest part of the motion was pivoting about the wrapper's
     CENTRE, dragging the pole end back and forth: precisely the rigid-sticker tell the whole design
     exists to avoid. Caught by a review of the shipped CSS, not by looking at it. */
  transform-origin:var(--bf-hoist) 50%;
  --bf-hoist:4.7%;
  /* SWING ALLOWANCE. Anchoring at the hoist doubles the lever arm — the fly is now ~28px from the
     pivot instead of ~14 — so every amplitude displaces twice as far, and the slot is overflow:hidden
     at the UNtransformed width. Measured overshoot past the clip edge before this: snap 2.65px,
     unfurl 1.44px, cloth 0.40px — i.e. the fly edge was being sliced off at the peak of the swing.
     The wrapper's own box is what flag-badge.js measures, so a few px here buys room for the motion
     in every style at once, and keeps buying it if an amplitude is ever raised. Cheaper and far more
     durable than re-tuning five sets of keyframes against a clip edge. */
  padding-right:3px;
}
.brand-flag-img{
  display:block;height:1.65em;width:auto;
  /* max-width:none is load-bearing: the site's global img{max-width:100%} clamps this to its PARENT,
     and the parent is the slot whose width animates from 0 — so the flag rendered 1px wide and grew
     as the slot opened, squashed and stretched instead of revealed. */
  max-width:none;
  transform-origin:var(--bf-hoist) 50%;
  backface-visibility:hidden;
  user-select:none;-webkit-user-drag:none;pointer-events:none;
}
/* The emoji fallback for a country we ship no PNG for. Never waved — a text glyph skewed like cloth
   looks like a rendering bug, and on the platforms this path is reached the emoji is already a
   properly drawn flag. */
.brand-flag-glyph{font-size:1.15em;line-height:1;display:inline-block}

/* The travelling light, shared by the styles that use it. Masked to the flag's own alpha (`--bf`,
   set inline by flag-badge.js — the same PNG as the <img>). That is required, not polish: these
   sprites are only opaque around x3-60/y11-52, so an unmasked overlay paints a grey bar above and
   below the flag. The mask is static — one raster at mount, nothing per frame. */
.brand-flag-sheen{
  position:absolute;inset:0;overflow:hidden;pointer-events:none;
  -webkit-mask-image:var(--bf);mask-image:var(--bf);
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
}
.brand-flag-sheen::before{
  content:"";position:absolute;top:-.7em;bottom:-.7em;left:-1.6em;right:-1.6em;
  /* A REPEATING gradient panned by exactly one period is seamless — no reset frame, no dead time —
     which is why the easing can be `linear`, the honest description of a wave travelling at a
     constant speed down a flag. One period is 1.10em along a line 10deg off vertical, i.e.
     1.10 / sin(100deg) = 1.117em horizontally. */
  background:repeating-linear-gradient(100deg,
    rgba(0,0,0,.16)       0em,
    rgba(0,0,0,0)         .22em,
    rgba(255,255,255,.30) .50em,
    rgba(255,255,255,0)   .78em,
    rgba(0,0,0,.16)       1.10em);
}
@keyframes hbSheen{from{transform:translateX(0)}to{transform:translateX(1.117em)}}
/* Without mask support the sheen would paint across the transparent margin as a grey slab. */
@supports not ((-webkit-mask-image:none) or (mask-image:none)){
  .brand-flag-sheen{display:none}
}

/* =========================================================================================
   THE FLAG — the five styles  (fw-*)
   -----------------------------------------------------------------------------------------
   Five different CHARACTERS of motion, not five tunings of one. Where a style uses more than one
   animation they run on periods with no small common multiple, so the combination never visibly
   repeats — the thing that makes an animation read as a GIF rather than as weather.
   ========================================================================================= */

/* CLOTH — the default and what shipped before this was selectable. A soft, asymmetric sway on the
   wrapper, a faster smaller ripple on the image, and the travelling sheen: three periods
   (2.6 / 1.7 / 2.1s) that never line up. Asymmetric because wind is: the away-swing is deeper and
   slower (peak at 27%), the return shallower and quicker. */
.brand-flag-wrap.fw-cloth.wave{animation:hbSway 2.6s cubic-bezier(.42,0,.58,1) infinite}
.brand-flag-wrap.fw-cloth.wave .brand-flag-img{animation:hbRipple 1.7s cubic-bezier(.42,0,.58,1) infinite}
.brand-flag-wrap.fw-cloth.wave .brand-flag-sheen::before{animation:hbSheen 2.1s linear infinite}
/* THE DEEP SWING TURNS AWAY, not toward. In CSS a point's z after rotateY is -x*sin(angle), so with
   the pivot at the hoist a NEGATIVE rotateY brings the fly toward the viewer, where perspective()
   magnifies it — the direction that overflows the slot. Positive turns it away and shrinks it. The
   deep excursion therefore takes the safe sign and the shallow return takes the other. */
@keyframes hbSway{
  0%  {transform:perspective(60px) rotateY(0deg) rotateZ(0deg)}
  27% {transform:perspective(60px) rotateY(11deg) rotateZ(-1.4deg)}
  66% {transform:perspective(60px) rotateY(-7deg) rotateZ(.9deg)}
  100%{transform:perspective(60px) rotateY(0deg) rotateZ(0deg)}
}
@keyframes hbRipple{
  0%,100%{transform:skewY(0deg) scaleY(1)}
  35%    {transform:skewY(-1.6deg) scaleY(.985)}
  70%    {transform:skewY(1.6deg) scaleY(1.015)}
}

/* BREEZE — barely any swing; the cloth breathes. For an owner who wants the flag to be present
   without being a moving thing in the corner of the eye. Slow enough (4.1 / 2.9 / 3.3s) that it
   never catches attention, which is the entire point. */
.brand-flag-wrap.fw-breeze.wave{animation:hbBreeze 4.1s ease-in-out infinite}
.brand-flag-wrap.fw-breeze.wave .brand-flag-img{animation:hbBreatheImg 2.9s ease-in-out infinite}
.brand-flag-wrap.fw-breeze.wave .brand-flag-sheen::before{animation:hbSheen 3.3s linear infinite;opacity:.6}
@keyframes hbBreeze{
  0%,100%{transform:perspective(70px) rotateY(0deg)}
  50%    {transform:perspective(70px) rotateY(-5deg)}
}
@keyframes hbBreatheImg{
  0%,100%{transform:skewY(0deg) scaleY(1)}
  50%    {transform:skewY(-.9deg) scaleY(.99)}
}

/* SNAP — strong wind. A quick hard flick to the peak and a slower recovery, so the flag looks caught
   and released rather than swung. The stepped easing on the outward leg is what makes it crack; a
   symmetric ease-in-out here would just be a fast cloth. Deliberately the most attention-getting of
   the five. */
.brand-flag-wrap.fw-snap.wave{animation:hbSnap 1.5s cubic-bezier(.16,.9,.28,1) infinite}
.brand-flag-wrap.fw-snap.wave .brand-flag-img{animation:hbSnapImg 1.1s cubic-bezier(.3,0,.2,1) infinite}
.brand-flag-wrap.fw-snap.wave .brand-flag-sheen::before{animation:hbSheen 1.3s linear infinite}
/* Same sign reasoning as hbSway, and it matters most here: this is the largest amplitude in the set,
   and it was the worst offender at 2.65px outside the clip edge. */
@keyframes hbSnap{
  0%  {transform:perspective(52px) rotateY(0deg) rotateZ(0deg)}
  18% {transform:perspective(52px) rotateY(18deg) rotateZ(-2.4deg)}
  46% {transform:perspective(52px) rotateY(-11deg) rotateZ(1.6deg)}
  74% {transform:perspective(52px) rotateY(5deg) rotateZ(-.7deg)}
  100%{transform:perspective(52px) rotateY(0deg) rotateZ(0deg)}
}
@keyframes hbSnapImg{
  0%,100%{transform:skewY(0deg) scaleY(1)}
  30%    {transform:skewY(-3.4deg) scaleY(.97)}
  65%    {transform:skewY(2.6deg) scaleY(1.03)}
}

/* UNFURL — the flag opens from the pole, overshoots a little, then settles into a gentle sway. A
   one-shot entrance followed by an infinite rest state, which is why there are two animations with
   a delay rather than one long keyframe list: the entrance must not repeat on every cycle.
   scaleX from the hoist is the unfurl; the transform-origin is what makes it open outward from the
   pole rather than grow from its middle. */
.brand-flag-wrap.fw-unfurl.wave .brand-flag-img{
  transform-origin:var(--bf-hoist) 50%;
  animation:hbUnfurl .85s cubic-bezier(.22,1.2,.36,1) both,
            hbRipple 1.9s cubic-bezier(.42,0,.58,1) .85s infinite;
}
.brand-flag-wrap.fw-unfurl.wave{animation:hbSway 3.0s cubic-bezier(.42,0,.58,1) .85s infinite}
.brand-flag-wrap.fw-unfurl.wave .brand-flag-sheen::before{animation:hbSheen 2.4s linear .85s infinite}
@keyframes hbUnfurl{
  0%  {transform:scaleX(.04) skewY(6deg);opacity:.2}
  55% {transform:scaleX(1.06) skewY(-2deg);opacity:1}
  100%{transform:scaleX(1) skewY(0deg);opacity:1}
}

/* PROUD — the flag does not move at all; only the light travels across it. The most restrained of
   the five and the cheapest: one animation, on one absolutely-positioned masked layer, so the flag
   bitmap itself is never re-composited. Reads as a flag lit from a passing source rather than a flag
   in wind — which is what you want if the header is already busy. */
.brand-flag-wrap.fw-proud.wave .brand-flag-sheen::before{animation:hbSheen 2.6s linear infinite}

/* =========================================================================================
   REDUCED MOTION
   -----------------------------------------------------------------------------------------
   The SEQUENCE still runs — it is information the owner chose to show, not decoration — but nothing
   animates: no wave, no sheen, no word entrances, and the slot cuts between beats instead of
   gliding. flag-badge.js also drops the `wave` class entirely under this preference, so this block
   is the belt to that braces.
   ========================================================================================= */
/* THE BADGE GOES WHEREVER THE WORDMARK GOES.
   devsocial.css hides the ux header's wordmark below 680px (`.logo span.word{display:none}`) to make
   room on a phone. Nothing hid the badge, so on every phone the header would have been owl + waving
   flag + "built in india" WITH THE BRAND NAME MISSING — the exact inversion of the one rule this
   badge has ("hudr my orginal name i want constant, after that name show this"). A badge that
   replaces the wordmark is the thing we removed; a badge that outlives it on small screens is the
   same mistake wearing a media query.
   Scoped to `.logo` on purpose: the auth pages keep their wordmark at every width, so the badge
   stays with it there. If that 680px breakpoint ever moves, move this with it. */
@media(max-width:680px){
  .logo .brand-flag{display:none}
}

@media(prefers-reduced-motion:reduce){
  .brand-flag{transition:none}
  .brand-flag-wrap,
  .brand-flag-wrap .brand-flag-img,
  .brand-flag-sheen::before{animation:none !important}
  .brand-flag-sheen{display:none}
  .brand-flag-word{animation:none !important}
  /* tw-shine paints its text transparent to show a moving gradient; with the animation off that
     would be an invisible word. */
  .brand-flag-word.tw-shine{background:none;color:inherit}
}
