/* ============================================================
   Pärn & Partners — homepage design system

   Ported from example/parnpartners-avaleht-v2.html. Brand colours
   and Inter come from the previous site: green #66BE3D and
   navy #1D213E. Its slate #354B5C was the body-copy colour until
   this site replaced it with a neutral #3E3E3E — see --slate.

   Three deliberate deviations from the mockup, all contrast fixes
   (mockup ratios measured at 2.33:1 and 3.68:1 against a 4.5:1
   requirement):

   1. REVERSED, AT THE CLIENT'S DIRECTION, AND NOW A DEVIATION IN THE
      OTHER DIRECTION. Text on a green fill was navy for the contrast
      (2.33:1 -> 6.72:1); it is WHITE everywhere now, which puts every
      green button back at 2.33:1 against a 4.5:1 requirement. It was
      the two badges only; it is the buttons, the newsletter, the social
      hovers and the consent banner too. On --green-dark, the hover
      fill, white reaches 3.08:1 — still short.
      This is no longer an exception recorded per instance. It is the
      rule, and the instances point here.
   2. --green-text is a darkened green for green text and icons on
      LIGHT backgrounds (5.22:1). On dark backgrounds the bright
      --green already passes (6.72:1) and is used as-is.
      EYEBROWS ARE NO LONGER PART OF THIS. They were moved to the
      logo's --green-logo at the client's direction and read 2.69:1
      on white; the .eyebrow rule carries the full note.
   3. --muted darkened #858589 -> #6B6B70 (3.68:1 -> 5.30:1).

   Purely decorative green rules (the eyebrow dash, the card top
   bar) are exempt from the 3:1 boundary rule — they carry no
   information that is not also in text.
   ============================================================ */

:root{
  --green:#66BE3D;
  --green-dark:#55a531;
  --green-text:#3F7A25;
  --green-soft:rgba(102,190,61,.12);
  /* The exact green of the logo artwork, sampled from it rather than eyeballed:
     10800 pixels of #48B400 in the bar beside the name. It is NOT --green, which
     is the brand fill the mockup specified and is two steps softer. On white it
     measures 2.69:1, which is why it began as a colour for marks and ornament
     only. IT IS NOW THE COLOUR OF EVERY GREEN THING THAT IS NOT A FILL, at the
     client's direction and against that reasoning — the eyebrows first, then
     the links, the member roles, the "Loe edasi" cues and the service and
     feature icons. See the note on the .eyebrow rule for the measurement.

     WHAT STILL IS NOT THIS GREEN, and why:
       --green      the FILL. Buttons, hovers, bars and ticks are painted in
                    it and white text sits on top; it is a background, not a
                    mark, so it is not part of "the greens on the page".
       --green-text the functional green. The focus ring, the success status
                    line, the required-field asterisk, the language tick and
                    the consent panel's links. Each of these has to clear a
                    contrast bar to do its job at all, and #48B400 does not:
                    2.69:1 on white against a 4.5:1 (text) or 3:1 (focus ring,
                    WCAG 1.4.11) requirement. A brand colour may be quiet; an
                    indicator that cannot be seen is a defect. */
  --green-logo:#48B400;
  --navy:#1D213E;
  --navy-deep:#15182E;
  --navy-soft:#2A2F52;
  /* BODY COPY, and neutral rather than the previous site's blue-grey slate
     (#354B5C). Every run of body text on the site reads from this one token —
     body itself, the prose blocks, the dropdown and blockquote text, the
     contact details, the form fields and the accessibility panel's --textColor
     — so the colour of body copy is changed here and nowhere else.
     10.70:1 on white and 10.07:1 on --paper-soft, up from 9.08 and 8.55.
     THE NAME IS NOW A HISTORICAL ONE: this is not slate any more. It is kept
     because it is what all eleven call sites say; rename the token, not the
     value, if that ever grates. */
  --slate:#3E3E3E;
  /* SECONDARY TEXT ONLY, and a much shorter list than it used to be: the lead
     paragraphs, service and post copy, feature cards, the values list and the
     contact intro all read --slate now, because they are body copy and body
     copy is one colour. What is left here is the text that is deliberately
     quieter than the paragraph beside it — post and article meta, the
     testimonial attribution, share and side-card labels, the form note, the
     submenu links — plus one border on a hovered field, which is not text at
     all. Darkened from #858589 for contrast; see deviation 3 above. */
  --muted:#6B6B70;
  --line:#E7E9F0;
  --field-line:#8F93A3;
  --line-soft:#F1F2F6;
  --paper:#FFFFFF;
  --paper-soft:#F7F8FB;
  --max:87.5rem;
  --header-h:5.25rem;
  --r:0.875rem;
  /* Every image's corner radius, so the whole site turns on one value. */
  --r-img:var(--r);
  /* THE SECOND RADIUS, AND THE LAST ONE. --r is for panels — cards, images,
     bands, menus. This is for the small interactive chrome inside them: the
     burger, the language and accessibility buttons, the menu rows, the pager.
     They need their own value because --r is 14px and these are 36-44px boxes,
     where it would round a third of the control away.
     It exists because there was no token and the file had drifted to three
     numbers for one job — 8px on the accessibility toggle and the language
     rows, 10px on the burger sitting immediately beside them, 12px on the
     dropdowns above. Anything rectangular is now --r or --r-ui; the only other
     shapes left are the pills, the circles, and the 2-4px bars and ticks that
     are ornament rather than boxes. */
  --r-ui:0.625rem;
  --shadow:0 1.125rem 3.125rem -1.5rem rgba(29,33,62,.28);
  --shadow-lg:0 2.125rem 5rem -2.125rem rgba(29,33,62,.45);
  --t:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  color:var(--slate);
  background:var(--paper);
  font-size:1.03rem;
  line-height:1.7;
  -webkit-font-smoothing:antialiased;
}
/* Rounded corners are the DEFAULT for every image, set on the element rather
   than per section so a section added later inherits it without remembering
   to. The four kinds of image that opt out are listed together below, each
   because a radius would damage that image rather than because it was missed.
   Nothing else overrides it: every other image corner on the site — the post
   cards, the article cover, the team photos, the sidebar thumbnails, the
   focus-card thumbnails — reads --r-img, so the whole site turns on one
   value. */
img{max-width:100%;display:block;border-radius:var(--r-img)}

/* Opt-out 1 — logos and award marks. A logo is artwork with its own edges, not
   a photograph in a frame: the site logotype's green rule runs flush to the
   left of its canvas, and the award marks are drawn to their own boundary, so
   a radius crops the mark rather than styling it. */
.brand img,
.footer .flogo,
.about-awards img,
.logo-strip img{border-radius:0}

/* Opt-out 2 — full-bleed section backdrops. These are stretched edge to edge
   behind a whole section, so a radius does not round a picture: it notches the
   section's corners and shows the page through them. The sections they sit in
   are what the eye reads as the shape, and those stay square. */
.hero-media img,.page-title > img,.cta > img{border-radius:0}

/* Opt-out 3 — images that FILL a rounded frame. The frame is already rounded
   and clips its overflow, so it supplies the shape; a radius on the image as
   well rounds the corners a second time, one frame-width in, and leaves the
   card showing through the notches where the photo should meet its edge. The
   corner you see is the frame's, and it is rounded. */
.featured .fimg img,
.post-img img,
.member-photo img,
.cta-portrait img,
.focus-thumb img,
.art-cover img,
.quote-band-bg{border-radius:0}

/* Opt-out 4 — the language flags. A flag renders at 19x13, and a radius is
   clamped to half the shorter side, so --r-img's 14px comes out as 6.5px and
   turns the Estonian tricolour into an oval. 2px is the largest radius that
   still leaves a flag looking like a flag. Declared here rather than on each
   of .lang-toggle / .lang-menu / .mobile-lang so the exception is stated once,
   beside the rule it is an exception to. */
.lang-toggle img,
.lang-menu img,
.mobile-lang img{border-radius:2px}

a{color:inherit;text-decoration:none}
/* Estonian compounds run long ('Võltskaupadega', 'Privaatsustingimused')
   and a single word wider than a 320px column would otherwise push the
   page sideways. (Checklist 1.2, WCAG 1.4.10) */
h1,h2,h3,h4{color:var(--navy);margin:0;font-weight:700;letter-spacing:-.02em;line-height:1.15;overflow-wrap:break-word}
h1{font-size:clamp(2.3rem,4.6vw,3.9rem);font-weight:800;letter-spacing:-.035em}
h2{font-size:clamp(1.85rem,3.1vw,2.75rem)}
h3{font-size:1.22rem;letter-spacing:-.015em}
p{margin:0}
.wrap{max-width:var(--max);margin:0 auto;padding:0 1.75rem}

/* Screen-reader-only text that still has to be announced.
   Used for the per-service link names and new-window warnings. */
.visually-hidden{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* ---- Focus -------------------------------------------------
   The mockup ships no focus styles at all. Every interactive
   element gets a visible ring; scroll-margin keeps a focused
   target clear of any sticky chrome. (Checklist 8.2, 5.5) */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:3px solid var(--green-text);
  outline-offset:3px;
  border-radius:4px;
}
:where(a,button,input,[tabindex]){scroll-margin-top:7rem}
/* Dark surfaces need the bright green to stay visible. */
.hero :where(a,button):focus-visible,
.cta :where(a,button):focus-visible,
.footer :where(a,button,input):focus-visible{outline-color:var(--green)}

/* ---- Buttons ---- */
.btn{
  display:inline-flex;align-items:center;gap:.625rem;
  padding:.9375rem 1.75rem;border-radius:6.25rem;font-weight:600;font-size:.95rem;
  letter-spacing:.01em;border:1.5px solid transparent;cursor:pointer;
  transition:all .35s var(--t);white-space:nowrap;
}
.btn svg{width:.9375rem;height:.9375rem;transition:transform .35s var(--t);flex:none}
.btn:hover svg{transform:translateX(4px)}
/* White on green, not navy — see deviation 1 in the header note. */
.btn-green{background:var(--green);color:#fff;box-shadow:0 .75rem 1.75rem -.75rem rgba(102,190,61,.7)}
.btn-green:hover{background:var(--green-dark);transform:translateY(-2px);box-shadow:0 1.125rem 2.125rem -.875rem rgba(102,190,61,.8)}
.btn-ghost{border-color:rgba(255,255,255,.55);color:#fff}
.btn-ghost:hover{border-color:#fff;background:rgba(255,255,255,.08)}
.btn-outline{border-color:var(--line);color:var(--navy);background:#fff}
.btn-outline:hover{border-color:var(--navy);transform:translateY(-2px)}

/* ---- Eyebrow / lead ---- */
/* THE LOGO'S OWN GREEN ON EVERY EYEBROW, AT THE CLIENT'S DIRECTION, AND IT DOES
   NOT MEET THE CONTRAST MINIMUM. --green-logo is #48B400 and measures 2.69:1 on
   white where an eyebrow needs 4.5:1 — .section-head sets these at 1rem/600, so
   they are ordinary text and the large-text 3:1 bar does not apply. --green-text
   gave them 5.22:1.

   THIS IS THE WORST TRADE ON THE SITE, and it is now the widest: it started on
   the testimonials band alone and has been extended to every eyebrow over a
   light background — about, services, team, blog. The hero, the CTA and the
   page-title banner are NOT affected; they override to --green below and sit on
   navy, where it measures 6.72:1 and passes.

   Reverting is one word: --green-logo back to --green-text here.
   (Checklist 8.4, WCAG 1.4.3) */
.eyebrow{
  display:inline-flex;align-items:center;gap:.625rem;
  font-size:.78rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  color:var(--green-logo);margin-bottom:1.125rem;
}
.eyebrow::before{content:"";width:1.625rem;height:2px;background:var(--green);border-radius:2px;flex:none}
/* On navy the bright brand green already clears 4.5:1. */
.hero .eyebrow,.cta .eyebrow{color:var(--green-logo)}
.lead{font-size:1.06rem;color:var(--slate);max-width:60ch}

/* ---- Language picker (in the header) ----
   Two states in one markup. Without JS the menu is a plain row of links and
   the toggle stays hidden, so the languages are never locked behind a control
   that cannot open; `.is-enhanced`, which the script adds, turns it into the
   dropdown. */
/* No rule down its left edge. The divider was there to separate the menu
   from the controls beside it; the padding still does that, and the line
   was reading as a border on the flag button rather than as a break in the
   row. */
.lang-picker{position:relative;padding-left:.875rem}
.lang-menu{display:flex;gap:.375rem;align-items:center;list-style:none;margin:0;padding:0}
/* Flags only, so the target has to be made rather than filled by text:
   2.25rem square clears the 24px minimum comfortably. (Checklist 14.2) */
.lang-menu a{
  display:flex;align-items:center;justify-content:center;gap:.375rem;
  min-width:2.25rem;min-height:2.25rem;padding:0 .5rem;border-radius:var(--r-ui);
  font-size:.82rem;font-weight:600;color:var(--navy);
}
.lang-menu img{width:1.1875rem;height:.8125rem;flex:none}
.lang-tick{width:.75rem;height:.75rem;color:var(--green-text);opacity:0;flex:none}
/* The current language is marked by a tick, not by colour alone. (8.1) */
.lang-menu a[aria-current="true"] .lang-tick{opacity:1}

/* NO BORDER. The flag and the chevron are what identify this control, so the
   box around them was decoration — and it was the only boxed thing in a row of
   plain words. Dropping it costs the hover cue the border colour used to carry,
   so hover becomes a surface instead, the same one the accessibility toggle
   beside it already uses. The padding stays: it is what holds the 2.25rem
   target and gives that surface something to fill. (Checklist 14.2)
   Focus is untouched — the ring comes from the global :focus-visible rule and
   never depended on this border. */
.lang-toggle{
  display:flex;align-items:center;gap:.5rem;
  min-height:2.25rem;padding:0 .625rem;
  border:0;border-radius:var(--r-ui);background:none;
  font-family:inherit;font-size:.86rem;font-weight:600;color:var(--navy);
  cursor:pointer;transition:background .25s;
}
.lang-toggle:hover{background:var(--paper-soft)}
.lang-toggle img{width:1.1875rem;height:.8125rem;flex:none}
.lang-chevron{width:.625rem;height:.375rem;flex:none;transition:transform .25s}
.lang-toggle[aria-expanded="true"] .lang-chevron{transform:rotate(180deg)}

/* Enhanced: the list becomes the dropped panel. */
.lang-picker.is-enhanced .lang-menu{
  position:absolute;top:calc(100% + .5rem);right:0;z-index:60;
  flex-direction:column;align-items:stretch;gap:.125rem;
  background:#fff;border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--shadow);padding:.375rem;
}
.lang-picker.is-enhanced .lang-menu[hidden]{display:none}
.lang-picker.is-enhanced .lang-menu a{justify-content:space-between;padding:.5rem .625rem}
.lang-picker.is-enhanced .lang-menu a:hover{background:var(--paper-soft)}

@media(max-width:1080px){.lang-picker{padding-left:.625rem}}

/* ============ HEADER ============ */
.header{
  position:sticky;top:0;z-index:60;background:rgba(255,255,255,.92);
  backdrop-filter:saturate(180%) blur(14px);
  border-bottom:1px solid var(--line-soft);transition:box-shadow .35s,background .35s;
}
.header.stuck{box-shadow:0 .625rem 1.875rem -1.25rem rgba(29,33,62,.4);background:rgba(255,255,255,.98)}
.nav{display:flex;align-items:center;justify-content:space-between;min-height:var(--header-h);gap:1.75rem}
/* flex:0 1 auto + min-width:0 so a wide logo can shrink instead of pushing
   the language switcher and burger off a 320px screen. */
.brand{display:flex;align-items:center;flex:0 1 auto;min-width:0}
/* 2.25rem, down from 2.625rem. The header keeps its own min-height, so this
   shrinks the mark and not the bar: at 42px it stood nearly three times the
   15.2px menu text beside it, and at 36px it is about two and a half. The
   narrow override below stays at 2rem — that one exists to stop the row
   scrolling sideways, not to set a look. */
.brand img{height:2.25rem;width:auto;max-width:100%}
.menu{display:flex;align-items:center;gap:2.125rem;margin:0 0 0 auto;padding:0;list-style:none}
.menu > li{position:relative}
.menu a.top{
  font-size:.95rem;font-weight:600;color:var(--navy);padding:1.875rem 0;display:inline-flex;
  align-items:center;gap:.375rem;position:relative;transition:color .25s;
}
.menu a.top::after{
  content:"";position:absolute;left:0;bottom:1.5rem;height:2px;width:0;background:var(--green);
  transition:width .35s var(--t);border-radius:2px;
}
.menu a.top:hover{color:var(--green-logo)}
.menu a.top:hover::after,.menu a.top[aria-current="page"]::after{width:100%}
/* Current page: colour AND a persistent underline. (Checklist 7.1, 8.1) */
.menu a.top[aria-current="page"]{color:var(--green-logo)}
.caret{width:.5625rem;height:.5625rem;fill:currentColor;opacity:.6;flex:none}
.dropdown{
  position:absolute;top:100%;left:-1.375rem;min-width:15.625rem;background:#fff;border:1px solid var(--line);
  border-radius:var(--r);box-shadow:var(--shadow);padding:.625rem;opacity:0;visibility:hidden;
  transform:translateY(10px);transition:all .3s var(--t);list-style:none;margin:0;
}
/* focus-within, not hover alone: a keyboard user must be able to reach the
   submenu, and it has to stay open while the pointer travels to it. (1.18, 3.11) */
.menu li:hover > .dropdown,
.menu li:focus-within > .dropdown{opacity:1;visibility:visible;transform:translateY(0)}
.dropdown a{display:block;padding:.5625rem .875rem;border-radius:var(--r-ui);font-size:.92rem;font-weight:500;color:var(--slate);transition:.22s}
.dropdown a:hover{background:var(--paper-soft);color:var(--navy);padding-left:1.25rem}
.nav-cta{display:flex;align-items:center;gap:.875rem;flex:none}
/* NO BUTTON IN HERE ANY MORE — .nav-cta holds the language picker alone. The
   contact call to action is gone from the header entirely: the row, the copy
   the burger panel carried, the two settings behind them and the admin section
   that edited them. The name stays because the class is load-bearing in the
   rules below and in the markup; what it wraps has narrowed.

   Two rules went with the button: a `left:max(0px, (100vw - var(--max)) / 2)`
   that pushed it out of the 87.5rem column to the screen edge, and a
   `color:#fff` that was, at the time, the file's ONE recorded contrast
   deviation. That colour is no longer exceptional — deviation 1 has since been
   reversed and white on green is what every green fill carries. */
/* The burger only appears once JS can drive it; until then the mobile menu
   stays expanded. Without this, a JS failure below 1080px would leave the site
   with no navigation at all, since .menu is display:none there. (5.1) */
/* flex:none because it is a child of .header-row now, not of .nav-cta: the row
   gives .nav flex:1 and would otherwise be free to squeeze this. */
.burger{
  display:none;width:2.75rem;height:2.75rem;border:1px solid var(--line);border-radius:var(--r-ui);background:#fff;
  align-items:center;justify-content:center;cursor:pointer;padding:0;color:var(--navy);flex:none;
}
.burger span{display:block;width:1.125rem;height:2px;background:currentColor;position:relative}
.burger span::before,.burger span::after{content:"";position:absolute;left:0;width:1.125rem;height:2px;background:currentColor}
.burger span::before{top:-6px}
.burger span::after{top:6px}
@media(max-width:1080px){
  /* The page links go; the accessibility toggle does not. It is an <li> in
     this same list now, so hiding .menu outright would take the panel off the
     phone — the devices that want it most — and it is the only item here that
     is a control rather than a destination. */
  .menu > li:not(.nav-item){display:none}
  .menu{gap:0}
  /* AND THE EMPTY WRAPPER GOES WITH IT, which is what fixes the gap beside the
     burger. .nav is space-between, so .nav-cta stayed a zero-width flex item
     pinned to the row's right edge and the accessibility toggle was separated
     from the burger by .nav's OWN gap on top of .header-row's — 32px under
     600px where that gap is .75rem, 48px above it where it is 1.75rem. The
     icon therefore sat in a different place either side of a breakpoint that
     has nothing to do with it.

     Safe to hide outright rather than shrink: .nav-cta holds only the language
     picker now, and that is already display:none under .has-mobile-nav at this
     width, so this element has nothing visible left in it. With it gone
     .menu is the last item in the row and ONE gap separates the toggle from
     the burger — declared once, below, identical at every width down to 320px.

     .5rem rather than the row's usual 1.25rem: with the empty wrapper gone the
     two are simply neighbours, and this gap is now the only thing setting how
     far apart they read. Both controls clear the 24x24 minimum on their own
     (40x36 and 44x44), so the checklist's spacing rule for undersized targets
     does not bind here and they may sit as close as the design wants. (7.8) */
  .has-mobile-nav .nav-cta{display:none}
  .has-mobile-nav .header-row{gap:.5rem}
  .js-nav .burger{display:flex}
}
/* At the narrow end the logo, the language links and the burger have to share
   one row; shrink the chrome rather than let the header scroll sideways. */
@media(max-width:600px){
  :root{--header-h:4.5rem}
  .nav{gap:.75rem;min-height:var(--header-h)}
  .brand img{height:2rem}
  .nav-cta{gap:.5rem}
  .lang-picker{padding-left:.5rem}
  .lang-toggle{padding:0 .5rem;gap:.375rem}
  .lang-menu{gap:.125rem}
}
/* The no-JS fallback: a plain expanded list under the header. It carries the
   gutter and max-width itself rather than the .wrap class it used to share,
   because as a drawer it is fixed-position and must not be centred in a
   87.5rem column — and a list running edge to edge is what dropping .wrap
   would otherwise have left behind for anyone whose JS never ran. */
.mobile{
  display:block;border-top:1px solid var(--line);background:#fff;
  max-width:var(--max);margin:0 auto;padding:1.125rem 1.75rem 1.625rem;
}
/* ---- Mobile menu: a right-hand drawer, but only once JS can close it ----
   Everything that makes it a drawer is scoped to .js-nav. Unscoped, a script
   failure would leave a fixed panel covering the page with no way out; the
   plain expanded list above is the fallback, and it stays exactly as it was. */
.mobile-scrim{display:none}
.js-nav .mobile-scrim{
  display:block;position:fixed;inset:0;z-index:70;
  background:rgba(21,24,46,.45);backdrop-filter:blur(2px);
  opacity:0;visibility:hidden;transition:opacity .3s var(--t),visibility 0s .3s;
}
.js-nav .mobile-scrim.open{opacity:1;visibility:visible;transition:opacity .3s var(--t),visibility 0s}

.js-nav .mobile{
  position:fixed;top:0;right:0;bottom:0;z-index:80;
  width:min(21rem,86vw);max-width:none;
  display:flex;flex-direction:column;
  padding:0 1.375rem 1.625rem;
  background:var(--paper);border-top:0;border-left:1px solid var(--line);
  box-shadow:var(--shadow-lg);
  overflow-y:auto;overscroll-behavior:contain;
  /* visibility, not display: display:none cannot transition, and it is
     visibility that takes the closed drawer out of the tab order and off the
     accessibility tree — a drawer parked off-screen with transform alone is
     still focusable, so Tab would wander into an invisible menu. (1.9) */
  transform:translateX(100%);visibility:hidden;
  transition:transform .32s var(--t),visibility 0s .32s;
}
.js-nav .mobile.open{transform:none;visibility:visible;transition:transform .32s var(--t),visibility 0s}

/* Sticky so the way out stays put while the list scrolls under it. */
.js-nav .mobile-head{
  position:sticky;top:0;z-index:1;display:flex;justify-content:flex-end;
  padding:.875rem 0;margin:0 0 .25rem;background:var(--paper);
}
.mobile-head{display:none}
.js-nav .mobile-head{display:flex}
.mobile-close{
  width:2.75rem;height:2.75rem;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:var(--r-ui);background:#fff;color:var(--navy);
  cursor:pointer;padding:0;transition:background .25s var(--t),border-color .25s var(--t);
}
.mobile-close:hover{background:var(--paper-soft);border-color:var(--field-line)}
.mobile-close svg{width:.875rem;height:.875rem}
/* The drawer is its own scrolling box (overflow-y above), so a menu taller than
   the phone scrolls rather than losing its last entries — which with the
   language links and the call-to-action at the bottom is exactly what got cut
   off. (Checklist 5.1, 1.2)

   Nothing closes the menu on resize, so both the drawer and its scrim have to
   be named with their open class here: a menu opened on a phone and then
   widened — a tablet turned landscape — would otherwise stay on screen over the
   desktop header, carrying a second copy of the language links and a second nav
   called "Peamenüü". (Checklist 3.8) */
@media(min-width:1081px){
  .mobile,.js-nav .mobile,.js-nav .mobile.open,
  .js-nav .mobile-scrim,.js-nav .mobile-scrim.open{display:none}
}
.mobile ul{list-style:none;margin:0;padding:0}
.mobile a{display:block;padding:.6875rem 0;font-weight:600;color:var(--navy);border-bottom:1px solid var(--line-soft)}
.mobile .sub a{font-weight:500;color:var(--muted);padding-left:1rem;font-size:.93rem}

/* ---- Drawer contents: rows that read as a menu rather than a bare list ----
   Rows lose their hairlines and gain a hit area with a hover/focus surface, a
   radius that matches the site's, and a bar on the current page — a shape, not
   just the accent colour, so the marker survives a greyscale display. (8.1) */
.js-nav .mobile-nav{flex:1 1 auto}
.js-nav .mobile a{
  border-bottom:0;border-radius:var(--r-ui);padding:.6875rem .75rem;
  transition:background .2s var(--t),color .2s var(--t);
}
.js-nav .mobile a:hover{background:var(--paper-soft)}
.js-nav .mobile-nav > ul > li > a{font-size:1.0625rem}
.js-nav .mobile-nav > ul > li + li{margin-top:.125rem}
.js-nav .mobile-nav a[aria-current="page"]{
  background:var(--paper-soft);position:relative;
}
.js-nav .mobile-nav a[aria-current="page"]::before{
  content:"";position:absolute;left:0;top:.5rem;bottom:.5rem;
  width:3px;border-radius:2px;background:var(--green);
}
/* Submenus sit under their parent as a quieter, indented group with a rule down
   the left, so the nesting is visible without relying on indent alone. */
.js-nav .mobile .sub{
  margin:.125rem 0 .5rem .75rem;padding-left:.625rem;
  border-left:1px solid var(--line);
}
.js-nav .mobile .sub a{padding-left:.5rem;font-size:.9375rem}
/* The parent row: the link takes the width, the disclosure sits at its end, and
   the submenu wraps onto a line of its own underneath both. */
.js-nav .mobile-nav > ul > li{display:flex;flex-wrap:wrap;align-items:center}
.js-nav .mobile-nav > ul > li > a{flex:1 1 auto}
.js-nav .mobile-nav > ul > li > .sub{flex:1 0 100%}
/* Does nothing without JS, so it is not shown without JS — a control that
   cannot act is a tab stop that wastes the visitor's time. The list itself
   ships expanded for exactly the same reason. */
.sub-toggle{display:none}
.js-nav .sub-toggle{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:2.75rem;height:2.75rem;margin-left:.25rem;padding:0;
  border:0;border-radius:var(--r-ui);background:none;color:var(--navy);cursor:pointer;
  transition:background .2s var(--t);
}
.js-nav .sub-toggle:hover{background:var(--paper-soft)}
.js-nav .sub-toggle svg{width:.75rem;height:.75rem;fill:currentColor;transition:transform .25s var(--t)}
.js-nav .sub-toggle[aria-expanded="true"] svg{transform:rotate(180deg)}
/* The two blocks below the links are separated from them and from each other,
   because they are a different kind of thing from a page you can go to. */
.js-nav .mobile-lang{
  margin-top:.5rem;padding-top:.75rem;border-top:1px solid var(--line);
}

/* The language picker moves into the burger panel below the breakpoint, so the
   header row is left with the logo, the accessibility icon and the burger.
   Scoped to .has-mobile-nav because that class is only set when a panel exists
   to move it into; with no menu items there is no burger, and hiding this would
   leave a phone unable to change language at all. (5.1) */
@media(max-width:1080px){
  .has-mobile-nav .header-row .lang-picker{display:none}
}
/* Full-width rows like the menu links above them, so the flag is not a 19px
   target floating in a wide panel. (7.8) */
.mobile-lang{margin-top:.875rem}
.mobile-lang ul{display:flex;flex-direction:column}
.mobile-lang a{display:flex;align-items:center;gap:.625rem;font-weight:600}
.mobile-lang img{width:1.1875rem;height:.8125rem;flex:none}
.mobile-lang .lang-tick{width:.75rem;height:.75rem;margin-left:auto;opacity:0;flex:none}
.mobile-lang a[aria-current="true"] .lang-tick{opacity:1}

/* ============ HERO ============ */
/* The photo is the background of the whole band, with the copy over it.
   min-height, never height: a short window or enlarged text has to be able to
   push the hero taller instead of clipping the heading. (Checklist 1.8, 6.13)
   svh rather than vh, because on a phone vh is the *largest* viewport, which
   would tuck the bottom of the hero under the browser's own chrome. The plain
   min-height above it is the fallback where svh is unsupported.
   --header-real is the measured header, published by js/main.js; --header-h is
   the static token it falls back to, which is right to within a few pixels. */
.hero{
  position:relative;isolation:isolate;display:flex;align-items:center;
  background:var(--navy);color:#fff;overflow:hidden;
  min-height:40rem;
  min-height:calc(100svh - var(--header-real, var(--header-h)));
}
/* Absolute, so the portrait mobile crop cannot drive the band's height with
   its own intrinsic aspect ratio. */
.hero-media{position:absolute;inset:0;z-index:-1}
/* CONTAIN, NOT COVER: the whole photograph, never a crop of it. cover was
   throwing away a fifth to a quarter of the height on every ordinary desktop
   — 13% at 1400x900, 25% at 1366x768 — and centred, so half of that came off
   the top, which is where both faces are. contain fits the picture inside the
   band instead, so every width shows all of it.
   Anchored right, because that is the half of the band the copy does not
   cover, and the band's own navy fills whatever is left beside it — the photo
   is a backdrop here, so unfilled space reads as the band, not as a gap. */
.hero-media img{width:100%;height:100%;object-fit:contain;object-position:right center}
/* NO SCRIM AT THIS WIDTH. There was a CSS one here at both widths, and it was
   what made white text safe over an arbitrary photograph — with it the heading
   measured 14.0:1 and the subtitle 10.0:1; stripped and left bare, the same
   photo gave 2.9:1 and 2.1:1.

   ON DESKTOP THE DARKENING IS PART OF THE UPLOADED IMAGE: that picture carries
   a solid #1D213E block down its left third, and the copy sits on it. Nothing
   here will catch a replacement supplied without one, so anyone changing the
   desktop hero image needs to know it.

   BELOW 980px THE BLOCK IS DRAWN HERE INSTEAD — see the media query below. */
.hero .wrap{width:100%}
/* No dash before this one, at either width — as .about already does further
   down. The rule that draws it is .eyebrow::before up in the shared block. */
.hero .eyebrow::before{display:none}
.hero-copy{padding:5.5rem 0;max-width:44rem}
.hero-copy h1{color:#fff}
.hero-copy h1 em{font-style:normal;color:var(--green-logo)}
.hero-sub{color:rgba(255,255,255,.82);font-size:1.1rem;max-width:48ch;margin-top:1.375rem}
.hero-actions{display:flex;gap:.875rem;margin-top:2.375rem;flex-wrap:wrap}
@media(max-width:980px){
  .hero{align-items:flex-end}
  .hero-copy{padding:4rem 0 3.5rem;max-width:none}
  /* COVER HERE, unlike the desktop rule above. The phone gets its own portrait
     upload, framed for a tall band, and containing it inside one leaves a hard
     navy edge across the picture instead of a photograph behind the copy. The
     overflow it crops is HORIZONTAL — 33% of the width at 390px — so 62% is
     the anchor that does the work, and it is where the subject sits. */
  .hero-media img{object-fit:cover;object-position:62% center}
  /* THE BLOCK, drawn rather than uploaded. The desktop image carries a solid
     #1D213E panel down its left third; this is the same panel at the bottom,
     which is the edge the copy sits against at this width
     (align-items:flex-end above).

     It is the band's own background, not an overlay: .hero-media stops at the
     top --hero-photo-h and the hero's var(--navy) fills the rest, so the photo
     ENDS at the edge rather than continuing behind it. No hidden quarter of a
     photograph under the block, and the crop the visitor sees is the whole of
     what was downloaded.

     It lives here rather than in the uploaded file so a replacement mobile crop
     cannot arrive without it — the one that did had no darkening at all.

     NOTE THE COPY OVERLAPS THE PHOTO. At 25% the block sits under the buttons
     only; the eyebrow, heading and subtitle are on photography, where that
     first upload measured 1.0:1 and 1.5:1. This split is a deliberate
     composition choice, so the legibility of the text is back to being a
     property of the picture — a light hero photo will make it unreadable and
     nothing here will catch that. Adjust --hero-photo-h alone to move the edge;
     75% clears only the buttons, 25% would put every line on solid navy. */
  .hero-media{bottom:auto;height:var(--hero-photo-h,75%)}
}

/* ============ SECTION SHELL ============ */
.section{padding:6.875rem 0}
.section.soft{background:var(--paper-soft)}
/* Section titles follow the old site's .section-title: a plain uppercase green
   line over a 40px/800 heading, 60px of air below. The green is --green-text,
   not the brand #66BE3D, which is 2.33:1 on white. */
.section-head{max-width:45rem;margin-bottom:3.75rem}
.section-head.center{margin-left:auto;margin-right:auto;text-align:center}
/* 2px, as on the old site: the eyebrow sits tight on top of the title. */
.section-head .eyebrow{font-size:1rem;font-weight:600;letter-spacing:normal;margin-bottom:.125rem}
.section-head .eyebrow::before{display:none}
.section-head h2{font-size:clamp(1.85rem,3.1vw,2.5rem);font-weight:800;line-height:1.3;letter-spacing:normal}
.section-head.center .eyebrow{justify-content:center}
.section-head h2 + p{margin-top:1.125rem}
.section-head.center .lead{margin:1.125rem auto 0}
.section-head.split{display:flex;align-items:flex-end;justify-content:space-between;gap:1.875rem;max-width:100%;flex-wrap:wrap}
@media(max-width:760px){.section{padding:4.625rem 0}}

/* ============ SERVICES ============ */
.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.375rem;list-style:none;margin:0;padding:0}
.svc{
  background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:2.125rem 1.875rem 1.875rem;
  transition:all .4s var(--t);position:relative;overflow:hidden;
  display:flex;flex-direction:column;height:100%;
}
.svc::before{content:"";position:absolute;left:0;top:0;height:3px;width:0;background:var(--green);transition:width .45s var(--t)}
.svc:hover{transform:translateY(-6px);box-shadow:var(--shadow);border-color:transparent}
.svc:hover::before{width:100%}
/* Icon beside the heading on one row, the body copy below it across the full
   card — the old card's arrangement. No disc behind the icon, and no number:
   the mockup's 01..09 goes with it. */
.svc-head{display:flex;align-items:center;gap:1.25rem;margin-bottom:.9375rem}
.svc-icon{flex:none;color:var(--green-logo)}
.svc-icon svg{width:2.5rem;height:2.5rem;display:block;fill:currentColor}
.svc h3{margin:0;min-width:0}
.svc p{font-size:.94rem;color:var(--slate);flex:1}
.svc a{display:inline-flex;align-self:flex-start;align-items:center;gap:.4375rem;margin-top:1.375rem;font-weight:600;font-size:.9rem;color:var(--navy);transition:gap .3s}
.svc a:hover{gap:.75rem;color:var(--green-logo)}
.svc a svg{width:.8125rem;height:.8125rem;flex:none}
@media(max-width:980px){.svc-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.svc-grid{grid-template-columns:1fr}}

/* ============ TEAM ============ */
/* Flex, not grid: a row that is not full centres its cards instead of leaving
   a hole on the right, so two members, three or five all sit square under the
   heading. The block itself is centred in the wrap as well. */
.team{
  display:flex;flex-wrap:wrap;justify-content:center;gap:1.625rem;
  max-width:55rem;margin:0 auto;padding:0;list-style:none;
}
.member{
  flex:0 1 calc(50% - .8125rem);min-width:0;
  background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;transition:all .4s var(--t);
}
.member:hover{transform:translateY(-6px);box-shadow:var(--shadow);border-color:transparent}
.member-photo{position:relative;overflow:hidden;background:var(--paper-soft)}
.member-photo img{width:100%;height:21.25rem;object-fit:cover;object-position:center 18%;transition:transform 1s var(--t)}
.member:hover .member-photo img{transform:scale(1.05)}
.member-body{padding:1.5rem 1.625rem 1.625rem}
.member-body h3{font-size:1.15rem}
.member-role{font-size:.87rem;color:var(--green-logo);font-weight:600;margin-top:.3125rem;letter-spacing:.02em}
.member-links{display:flex;gap:.625rem;margin-top:1rem}
.member-links a{
  width:2.25rem;height:2.25rem;border:1px solid var(--line);border-radius:50%;display:grid;place-items:center;
  transition:.28s;color:var(--slate);
}
/* White glyph on the green fill, per deviation 1. */
.member-links a:hover{background:var(--green);border-color:var(--green);color:#fff}
.member-links svg{width:.9375rem;height:.9375rem;fill:currentColor}
@media(max-width:640px){.member{flex-basis:100%}}

/* ============ TESTIMONIALS ============ */
.tst-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem;list-style:none;margin:0;padding:0}
.tst{
  background:#fff;border-radius:var(--r);padding:2.125rem 1.875rem;border:1px solid var(--line);
  display:flex;flex-direction:column;gap:1.25rem;position:relative;transition:.4s var(--t);height:100%;margin:0;
}
.tst:hover{transform:translateY(-5px);box-shadow:var(--shadow);border-color:transparent}
/* The logo's own green on the quotation marks, at full strength — they carried
   opacity:.55 until now, which painted them as a washed rgb(154,214,115) rather
   than the logo's #48B400. They are ornament, and the quote itself is --slate,
   so their colour carries no contrast requirement either way.
   The negative margin pulls them down onto the quote. .tst is a flex column
   with one 1.25rem gap between all three children, so closing the space above
   the text by changing that gap would close the one under it as well, between
   the quote and the attribution, where it is wanted. A margin on this child
   alone is what makes the two independent. The value overshoots the 1.25rem it
   is cancelling because line-height:.6 leaves whitespace under the ink inside
   the box, so the marks read as detached long after the boxes are touching:
   -1.25rem still looked separated, -1.375rem nearly so, and -1.625rem is where
   they sit on the quote. Measured edge to edge that is a 6px overlap.

   This band's EYEBROW used to be overridden here too; it no longer needs to be,
   because every eyebrow reads --green-logo now. That trade is recorded once, in
   the shared .eyebrow rule near the top of this file. */
.tst .qm{font-size:3.4rem;line-height:.6;color:var(--green-logo);font-weight:800;margin-bottom:-1.625rem}
.tst blockquote{margin:0;color:var(--slate);font-size:.98rem;flex:1}
.tst-person{display:flex;align-items:center;gap:.875rem;padding-top:1.125rem;border-top:1px solid var(--line)}
.tst-person img{width:3.125rem;height:3.125rem;border-radius:50%;object-fit:cover;flex:none}
.tst-person b{display:block;color:var(--navy);font-size:.96rem;font-weight:600}
.tst-person span{font-size:.83rem;color:var(--muted)}
@media(max-width:980px){.tst-grid{grid-template-columns:1fr;max-width:38.75rem;margin:0 auto}}

/* ============ CTA ============ */
.cta{position:relative;isolation:isolate;color:#fff;overflow:hidden;background:var(--navy)}
.cta > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2}
/* Scrim ends at .88, not the mockup's .7. Over a light photo, .7 leaves the
   green eyebrow at 2.50:1; .88 holds it at 4.62:1 and white text at 10.79:1
   no matter what image an editor uploads. Visually near-identical. */
.cta::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(100deg,rgba(29,33,62,.96) 30%,rgba(29,33,62,.88) 100%)}
.cta .wrap{padding-top:5.75rem;padding-bottom:5.75rem;display:flex;align-items:center;justify-content:space-between;gap:2.75rem;flex-wrap:wrap}
.cta h2{color:#fff;max-width:16ch}
.cta p{color:rgba(255,255,255,.75);margin-top:1rem;max-width:46ch}
/* No dash before this one, as on the hero, the section heads and the about
   band. The rule that draws it is .eyebrow::before in the shared block near the
   top of this file; only the mark goes, the wording stays. */
.cta .eyebrow::before{display:none}
.cta-left{display:flex;align-items:center;gap:2.125rem}
.cta-actions{margin:0}
.cta-portrait{flex:0 0 9.25rem;width:9.25rem;height:9.25rem;border-radius:50%;overflow:hidden;border:3px solid rgba(102,190,61,.55)}
.cta-portrait img{position:static;width:100%;height:100%;object-fit:cover}
@media(max-width:620px){.cta-portrait{display:none}}

/* ============ BLOG ============ */
/* The newest post leads the listing as one wide card. It is a single link, so
   the inner elements are spans, not headings — the h1 is the page banner's. */
.featured{
  display:grid;grid-template-columns:1.15fr .85fr;border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;margin-bottom:2.75rem;background:#fff;transition:.4s var(--t);color:inherit;
}
.featured:hover{box-shadow:var(--shadow);border-color:transparent;transform:translateY(-4px)}
.featured .fimg{overflow:hidden;min-height:20.625rem;background:var(--paper-soft);display:block}
.featured .fimg img{width:100%;height:100%;object-fit:cover;transition:transform 1s var(--t)}
.featured:hover .fimg img{transform:scale(1.05)}
.featured .fbody{padding:2.75rem 2.875rem;display:flex;flex-direction:column;justify-content:center;gap:.875rem}
.featured .featured-title{font-size:clamp(1.4rem,2.2vw,1.9rem);font-weight:800;line-height:1.2;color:var(--navy)}
.featured .featured-excerpt{color:var(--slate);font-size:.98rem}
.featured .post-meta{margin:0}
.featured .more{color:var(--green-logo);font-weight:600;display:inline-flex;gap:.5rem;align-items:center}
.featured .more svg{width:.875rem;height:.875rem;flex:none}
.badge{
  display:inline-flex;align-items:center;gap:.5rem;background:var(--green-soft);color:var(--green-logo);
  font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:.4375rem .875rem;border-radius:100px;align-self:flex-start;
}
@media(max-width:860px){
  .featured{grid-template-columns:1fr}
  .featured .fbody{padding:2rem 1.75rem}
  .featured .fimg{min-height:14rem}
}

.blog-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.75rem;list-style:none;margin:0;padding:0}
@media(max-width:980px){.blog-grid{grid-template-columns:repeat(2,1fr)}}
.post{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:#fff;transition:.4s var(--t);display:flex;flex-direction:column;position:relative;height:100%}
.post:hover{transform:translateY(-6px);box-shadow:var(--shadow);border-color:transparent}
/* The whole card is clickable, but only the title is a link, so the
   card exposes exactly one accessible name. (Checklist 7.6) */
.post h2 a::after,.post h3 a::after{content:"";position:absolute;inset:0;z-index:1}
.post:focus-within{box-shadow:var(--shadow)}
.post-img{overflow:hidden;height:13.125rem;background:var(--paper-soft)}
.post-img img{width:100%;height:100%;object-fit:cover;transition:transform 1s var(--t)}
.post:hover .post-img img{transform:scale(1.06)}
.post-body{padding:1.625rem 1.75rem 1.75rem;display:flex;flex-direction:column;flex:1}
.post-meta{font-size:.8rem;color:var(--muted);display:flex;gap:1rem;margin-bottom:.75rem;flex-wrap:wrap}
.post-meta span{display:inline-flex;align-items:center;gap:.375rem}
.post h2,.post h3{font-size:1.13rem;margin-bottom:.625rem}
.post p{font-size:.93rem;color:var(--slate);flex:1}
.post .more{margin-top:1.125rem;font-weight:600;font-size:.9rem;color:var(--green-logo);display:inline-flex;gap:.4375rem;align-items:center}
.post .more svg{width:.8125rem;height:.8125rem;flex:none}
@media(max-width:640px){.blog-grid{grid-template-columns:1fr}}

/* ============ FOOTER ============ */
.footer{background:var(--navy-deep);color:rgba(255,255,255,.75);padding-top:5.25rem}
.footer h2{color:#fff;font-size:.82rem;letter-spacing:.16em;text-transform:uppercase;margin-bottom:1.375rem;font-weight:700}
.foot-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.4fr;gap:3rem;padding-bottom:4rem}
.footer .flogo{height:2.875rem;width:auto;margin-bottom:1.5rem}
.footer a{transition:color .25s}
.footer a:hover{color:var(--green-logo)}
.foot-list{list-style:none;padding:0;margin:0;display:grid;gap:.6875rem;font-size:.94rem}
/* Grid and flex children default to min-width:auto, which refuses to shrink
   below their content and pushed the footer past 320px. */
.foot-grid > *{min-width:0}
/* font-style:normal because this is an <address>, and every browser's own
   stylesheet sets that element in italic — the whole block was leaning,
   the company name, the street, the phone, the registry numbers, all of
   it. The element stays: this IS the site owner's contact details, which
   is what <address> is for. Only the slant goes. */
.foot-contact{font-style:normal;font-size:.94rem;display:grid;gap:.5625rem;overflow-wrap:anywhere}
.foot-contact .row{display:flex;gap:.625rem;flex-wrap:wrap}
/* LABELS SET THEIR OWN WIDTH, so each row starts hard left and its value
   follows the label directly. The 4.625rem min-width here was trying to line
   the values up in a second column, and could not: it is 74px and "KMKR nr:"
   measures 68px of text before its gap, so three rows aligned at 74px and the
   fourth sat 6px past them — a column that was visibly not a column. Left
   alignment is the whole of the rule now; nothing is indented to meet a width
   that a longer label, or another language, would break again. */
.foot-contact .row b{color:rgba(255,255,255,.9);font-weight:500}
.foot-company{color:#fff;font-weight:600}
.social{display:flex;gap:.625rem;margin-top:1.5rem;list-style:none;padding:0}
.social a{width:2.375rem;height:2.375rem;border:1px solid rgba(255,255,255,.28);border-radius:50%;display:grid;place-items:center;color:rgba(255,255,255,.85);transition:.28s}
.social a:hover{background:var(--green);border-color:var(--green);color:#fff}
.social svg{width:.9375rem;height:.9375rem;fill:currentColor}
.news p{font-size:.93rem;margin-bottom:1rem}
.news label{display:block;font-size:.88rem;margin-bottom:.5rem;color:rgba(255,255,255,.85)}
.news form{display:flex;gap:.5rem;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.24);border-radius:6.25rem;padding:.375rem .375rem .375rem 1.25rem}
.news input{flex:1;background:transparent;border:0;color:#fff;font-family:inherit;font-size:.92rem;outline:none;min-width:0}
.news input::placeholder{color:rgba(255,255,255,.6)}
.news button{border:0;background:var(--green);color:#fff;border-radius:6.25rem;padding:.6875rem 1.375rem;font-weight:600;font-size:.88rem;cursor:pointer;transition:.25s;font-family:inherit}
.news button:hover{background:var(--green-dark)}
.news .news-status{font-size:.85rem;margin-top:.625rem;min-height:1.2em}
.foot-bottom{border-top:1px solid rgba(255,255,255,.18);padding:1.625rem 0;font-size:.85rem;display:flex;justify-content:space-between;gap:1.25rem;flex-wrap:wrap}
@media(max-width:980px){.foot-grid{grid-template-columns:1fr 1fr;gap:2.5rem}}
@media(max-width:620px){.foot-grid{grid-template-columns:1fr}}

/* ============ PAGE TITLE (subpage banner) ============ */
/* Follows the old site's .page-title, with one deliberate departure:
     overlay   --navy-deep at .9   (WAS rgba(17,17,17,.9), near-black)
     padding   100px top and bottom, as on /et/teenused — the old site's
               subpages disagreed with each other (meist used 50px), and the
               teenused height is the one every banner here follows
     title     #f5f5f5, 600, line-height 1.1, 3.5rem (2rem below 768px)
     crumbs    600, 1rem, #fff current / #ddd links, angle separator

   THE SCRIM IS THE SITE'S OWN DARK NOW, NOT A NEUTRAL BLACK. Every page
   uploads its own banner photo and they differ — five subpages carried four
   different pictures, one of them with a green cast baked into the file, and
   every article carries its own — so the band that repeats on every page was
   the one band that never looked the same twice. Tinting the scrim navy gives
   them all one colour without taking the photographs away, and it is the navy
   the header and footer are already built from, where a neutral #111 belonged
   to no palette here.

   THE OPACITY IS UNCHANGED AT .9, DELIBERATELY. Only the hue moved: at .94 the
   pictures went to a barely-there 6% and the band stopped being a photo band
   at all, which is more than was asked for. What varies between pages now is
   the brightness of the picture, not its colour.

   The cost, measured the same way as before against a worst-case white photo:
     title #f5f5f5   13.34:1 -> 12.08:1
     crumb link #ddd 10.71:1 ->  9.70:1
     eyebrow --green  6.23:1 ->  5.64:1
   Navy is a lighter dark than #111, so all three come down and all three still
   clear their bar with room — the crumb links want 4.5:1 and hold 9.70:1. */
.page-title{position:relative;isolation:isolate;background:var(--navy-deep);color:#fff;text-align:center}
.page-title > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;z-index:-2}
.page-title::after{content:"";position:absolute;inset:0;z-index:-1;background:rgba(21,24,46,.9)}
.page-title .wrap{padding-top:6.25rem;padding-bottom:6.25rem}
.page-title h1,.page-title-label{color:#f5f5f5;font-weight:600;line-height:1.1;font-size:3.5rem;letter-spacing:normal;margin:0}
.page-title .eyebrow{color:var(--green-logo);justify-content:center}
.crumbs{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  list-style:none;margin:.625rem 0 0;padding:0;font-size:1rem;font-weight:600;
}
.crumbs li{display:inline-flex;align-items:center;margin:0 .75rem .625rem 0;color:#fff}
.crumbs a{color:#ddd}
.crumbs a:hover{color:var(--green-logo)}
.crumbs svg{width:.5rem;height:.5rem;margin-left:.75rem;fill:currentColor;opacity:.7}
@media(max-width:768px){
  .page-title h1,.page-title-label{font-size:2rem;line-height:1.3}
  .page-title .wrap{padding-top:3.75rem;padding-bottom:3.75rem}
}

/* ============ RECOGNITION BAND (wtr) ============ */
/* Two equal columns and a plain photo, as on the old site. */
.wtr{display:grid;grid-template-columns:1fr 1fr;gap:4rem;align-items:center}
.wtr-single{grid-template-columns:1fr;max-width:52rem}
.wtr-img{position:relative;min-width:0}
.wtr-img img{border-radius:var(--r-img);width:100%;display:block}
.wtr-body{min-width:0}
.wtr-body h2{font-size:1.45rem;line-height:1.4}
.wtr-body .lead{margin-top:.5rem;color:var(--slate);font-weight:500;font-size:1rem;line-height:1.8}
/* Rich text: the editor's paragraph breaks have to read as paragraph breaks. */
.wtr-body .lead p{margin:0}
.wtr-body .lead p + p{margin-top:1.875rem}
.wtr-body strong{color:var(--navy)}
/* Photo on the right: a visual swap only, nothing focusable moves. */
.wtr-image-right .wtr-img{order:2}
/* Two bands back to back read as one block, as they did on the old site,
   where both rows lived inside a single section. */
.recognition-band + .recognition-band{padding-top:0}
.recognition-band:has(+ .recognition-band){padding-bottom:5.375rem}
@media(max-width:900px){
  .wtr{grid-template-columns:1fr;gap:2.125rem}
  .wtr-image-right .wtr-img{order:0}
}

/* ============ QUOTE BAND ============ */
/* WAS A GREEN DISC ON A PHOTO; IS NOW A SPLIT. The old site's .video-block put
   a 490px circle of --green over the right end of the strip with a hard grey
   disc offset behind it, and the quote set in caps inside the circle. Three
   things were wrong with it and only one was taste: the caps came from CSS so
   the lines broke ragged against the curve, the offset disc read as a render
   artifact rather than a shape, and white on --green is 2.33:1 — the quote
   band was the least readable text on the site.

   The photo and the quote are now two halves of one strip, neither on top of
   the other. The panel is --navy, which is the site's own dark and gives the
   quote 15.9:1 instead of 2.33:1, and the photo keeps its whole frame instead
   of being a backdrop with a hole punched in it.

   The GREEN SURVIVES AS ONE MARK: a rule down the left of the quote, which is
   the device .feature-banner and .focus-card already use for the same job.
   That is the whole of the ornament here. */
.quote-band{padding:1.875rem 0 6.875rem}
.quote-band-inner{
  position:relative;overflow:hidden;margin:0;
  border-radius:var(--r-img);background:var(--navy);
  display:grid;grid-template-columns:1.15fr 1fr;min-height:26rem;
}
/* A grid cell now, not an absolute backdrop behind the badge. */
.quote-band-bg{display:block;width:100%;height:100%;object-fit:cover}
.quote-badge{
  display:flex;flex-direction:column;justify-content:center;gap:2.25rem;
  padding:clamp(2.5rem,3.4vw,3.75rem);
  background:var(--navy);color:#fff;
}
/* LIGHT AND LARGE, IN SENTENCE CASE. Every other heading on this site is 700 or
   800; a quote set at 300 is the one place the type speaks instead of
   announcing, which is what a sentence from the founder should sound like.
   The caps that used to be applied here are gone — they were a CSS transform,
   so the accessible text never changed, but they made a 60-character sentence
   into five ragged lines. */
.quote-badge blockquote{
  position:relative;margin:0;padding-left:1.375rem;
  font-size:clamp(1.375rem,1.9vw,1.9rem);font-weight:300;line-height:1.35;
  letter-spacing:-.02em;text-wrap:balance;
}
/* The margin mark. Inset from the cap line rather than running the full height,
   so it reads as an annotation against the text and not as a border on a box. */
.quote-badge blockquote::before{
  content:"";position:absolute;left:0;top:.3em;bottom:.3em;
  width:3px;border-radius:2px;background:var(--green);
}
/* Aligned with the quote's text, not with its rule: the attribution is not part
   of the quotation, so it does not sit inside the mark. */
.quote-badge figcaption{padding-left:1.375rem;font-size:1rem;line-height:1.5}
.quote-badge cite{display:block;font-style:normal;font-weight:600}
.quote-badge figcaption span{
  display:block;font-style:normal;font-weight:400;margin-top:.125rem;
  color:rgba(255,255,255,.66);
}
@media(max-width:900px){
  /* Stacked, photo first — the strip is too narrow to hold two columns and
     still give the quote a readable measure. */
  .quote-band-inner{grid-template-columns:1fr;min-height:0}
  .quote-band-bg{height:16rem}
}

/* ============ FEATURES (old-site features band) ============ */
/* No padding exception here any more. The band used to drop its bottom padding
   because the banner photo hung out below the box and filled that space; the
   photo sits inside the box now, so the band spaces itself like every other
   section. */
.features-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.875rem;align-items:start}
/* --r like every other panel on the site, but on the RIGHT SIDE ONLY. This band
   came over from the old site carrying its own 5px, and the cards beside it
   their own 10px, so the features row was the one place where three different
   corners met: 5px on the banner, 10px on the cards, and 14px on the photo
   hanging off the banner's own bottom edge.
   The left corners are square because the green edge butts against them. A
   radius there curves the navy away from a strip that runs straight past it,
   and the page background shows through the joint at both ends — the opposite
   of the single block the edge and the banner are meant to read as. */
.feature-banner{
  position:relative;margin-left:1rem;padding:2.8125rem 3.75rem;
  background:var(--navy);border-radius:0 var(--r) var(--r) 0;
}
/* The green edge sits in the wrap's own gutter, so it never causes overflow.
   It keeps a small radius on its OUTER side only: it is a 1rem-wide strip, and
   --r would round 14 of those 16 pixels away and leave a lozenge rather than an
   edge. The inner side is square so it meets the banner flush. */
.feature-banner::before{
  content:"";position:absolute;left:-1rem;top:0;width:1rem;height:100%;
  border-radius:4px 0 0 4px;background:var(--green);
}
.feature-banner h2{color:#fff;font-size:clamp(1.75rem,3vw,2.5rem);line-height:1.3;margin:0 0 1rem}
.feature-banner p{color:#B4B6C5;line-height:1.8;margin:0 0 1.875rem}
/* INSIDE the box, not hanging below it. The old site let the photo overhang the
   bottom edge; that left the banner with a normal gap above its heading and no
   gap at all under the photo, which read as an unfinished box. No bottom margin
   means the banner's own 2.8125rem padding closes it, matching the top. */
.feature-banner-img{display:block;width:100%;border-radius:var(--r-img)}
/* ONE COLUMN, ALWAYS. These two cards used to sit side by side above 760px and
   stack below it; they stack at every width now. Beside the banner that gives
   them the full width of the right-hand column rather than half of it, which is
   what the copy in them wants — both cards carry a paragraph, not a label. */
.feature-cards{display:grid;grid-template-columns:1fr;gap:1.875rem;list-style:none;margin:0;padding:0}
/* No banner beside them? The cards are the whole band, not half of it. */
.feature-cards:only-child{grid-column:1 / -1}
/* THE ICON SITS BEFORE THE TITLE, NOT ABOVE IT. Stacking the cards gave each
   one the full width of the column, and a 110px disc over a centred column of
   copy then made them far taller than the banner beside them — 367px each. On
   one row with the title the same card is 195px, and the band reads as two
   entries rather than two towers.
   A grid rather than flex because the paragraph has to sit under the TITLE, in
   the second column, not under the icon: three children, two of them placed by
   hand, and the icon left to auto-place into row 1 column 1. */
.feature-card{
  /* Side padding is 10px tighter than the old site's, which landed the text
     measure on the old 195px back when the wrap was 1240px. The wrap is 1400px
     now, so the measure is wider than the old site's by design. The vertical
     padding came down from 3.75rem with the icon; there is no disc to clear. */
  min-width:0;padding:2.5rem;background:#fff;border-radius:var(--r);
  box-shadow:0 0 30px rgba(0,0,0,.06);
  display:grid;grid-template-columns:auto 1fr;column-gap:1.25rem;align-items:center;
}
/* NO DISC BEHIND IT. The #F6F6F6 circle was what made the icon a 110px block;
   inline with the title it is just the mark, at a size that sits against a
   1.45rem heading rather than dwarfing it. */
.feature-icon{
  display:flex;align-items:center;justify-content:center;color:var(--green-logo);
}
.feature-icon svg{width:2.75rem;height:2.75rem;fill:currentColor}
.feature-title{margin:0;grid-column:2;font-size:1.45rem;line-height:1.4;letter-spacing:normal}
.feature-card p{color:var(--slate);line-height:1.8;margin:.75rem 0 0;font-weight:500;grid-column:2}
.feature-card a{color:var(--green-logo);font-weight:600;text-decoration:underline}
.feature-card a:hover{text-decoration:none}
@media(max-width:1100px){
  .features-grid{grid-template-columns:1fr}
}
@media(max-width:760px){
  .feature-card{padding:1.875rem}
  /* The paragraph goes full width here. Beside the icon it is indented by the
     mark plus the 1.25rem column gap, which on a phone leaves it a 195px
     measure — the copy wrapped to nine short lines and the card came out taller
     than it was before the icon moved. Under the icon it gets 259px and the
     card 318px instead of 347px. The TITLE stays in column 2: it is the thing
     the icon is marking, and pulling it under would leave the mark labelling
     nothing. */
  .feature-card p{grid-column:1 / -1}
  .feature-banner{padding:1.875rem 2rem}
}

/* ============ FOCUS CARDS ============ */
.focus{display:grid;grid-template-columns:1fr 1fr;gap:1.625rem;margin-top:4.375rem;list-style:none;padding:0}
.focus-card{
  display:flex;gap:1.625rem;align-items:flex-start;padding:1.875rem;background:var(--navy);
  border-radius:var(--r);color:#fff;transition:.4s var(--t);position:relative;overflow:hidden;height:100%;
}
.focus-card::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--green)}
.focus-card:hover{transform:translateY(-5px);box-shadow:var(--shadow-lg)}
.focus-thumb{flex:0 0 7.25rem;width:7.25rem;height:7.25rem;border-radius:var(--r-img);overflow:hidden;background:var(--navy-soft)}
.focus-thumb img{width:100%;height:100%;object-fit:cover;transition:transform 1s var(--t)}
.focus-card:hover .focus-thumb img{transform:scale(1.07)}
.focus-body h3{color:#fff;font-size:1.24rem}
.focus-body p{color:rgba(255,255,255,.78);font-size:.95rem;margin-top:.625rem}
.focus-link{display:inline-flex;align-items:center;gap:.5rem;margin-top:1rem;color:var(--green-logo);font-weight:600;font-size:.92rem}
.focus-link svg{width:.875rem;height:.875rem;transition:transform .3s var(--t);flex:none}
.focus-card:hover .focus-link svg{transform:translateX(5px)}
@media(max-width:860px){.focus{grid-template-columns:1fr}}
@media(max-width:480px){.focus-card{flex-direction:column}}

/* ============ ABOUT ============ */
.about{display:grid;grid-template-columns:1fr 1fr;gap:4.5rem;align-items:center}
.about-single{grid-template-columns:1fr;max-width:52rem}
.values{list-style:none;padding:0;margin:2rem 0 0;display:grid;gap:2px}
.values li{
  display:flex;gap:.875rem;align-items:flex-start;padding:.875rem 0;border-bottom:1px solid var(--line);
  font-weight:500;color:var(--navy);
}
.values li:last-child{border-bottom:0}
.tick{
  flex:0 0 1.375rem;width:1.375rem;height:1.375rem;border-radius:50%;background:var(--green-soft);
  display:grid;place-items:center;margin-top:3px;
}
.tick svg{width:.6875rem;height:.6875rem;fill:var(--green-logo)}
.about-visual{position:relative}
.about-visual > img{border-radius:var(--r-img);box-shadow:var(--shadow-lg);width:100%;height:32.5rem;object-fit:cover}
/* THE SERVICE PAGES SHOW THE WHOLE PHOTO. The fixed 32.5rem above is right for
   About, where the picture is one of three layered pieces — the float photo and
   the stat badge hang off its corners and need a known height to hang from. A
   service page has none of that: it is one upload beside a list, and cropping
   18.5% off the width of a 3:2 photo to fill a 636x520 box is throwing away
   framing the editor chose.
   height:auto is the whole rule. object-fit stops applying once the box is the
   picture's own shape, so it is left where it is rather than reset here.
   Specificity 0-3-1 beats the 0-2-1 above AND the same selector inside the
   900px query below, so one declaration covers every width. */
.about-points .about-visual > img{height:auto}
/* TOP OF THE PHOTO LINES UP WITH THE HEADING. .about centres its two columns,
   which is right for About, where both sides are about the same height. Here
   the left column is a title, a lead and a ticked list that grows with the
   service: the longer that list, the further down the middle the photo floated,
   until it read as unanchored to the heading it belongs to. Aligned to the
   start, the photo meets the title on every service page and the list simply
   runs past it. */
.about-points{align-items:start}
/* WHITE ON THE GREEN BADGE, which is what every green fill carries now — see
   deviation 1 in the header note, where the decision is recorded once for the
   whole site. The measurement here: white on --green is 2.33:1; the number is
   large text at both layouts' sizes so its bar is 3:1 rather than 4.5:1, and it
   misses that too, while the label under it is ordinary text and wants 4.5:1.
   The badge's icon is an uploaded image and keeps whatever it was drawn in.
   (Checklist 8.4, WCAG 1.4.3) */
.stat{
  position:absolute;right:-1.375rem;bottom:-1.625rem;background:var(--green);color:#fff;
  border-radius:var(--r);padding:1.625rem 2rem;box-shadow:0 1.5rem 3.125rem -1.25rem rgba(102,190,61,.6);
}
/* No dash before this one, joining .section-head above — the centred eyebrows
   over the services, team, testimonials and blog bands already drop it, and
   the hero dropped it too. What is left carrying the rule is the contact band
   alone, which sets its eyebrow against a dark photograph rather than over a
   heading. */
.about .eyebrow::before{display:none}
.stat b{display:block;font-size:2.9rem;font-weight:800;line-height:1;letter-spacing:-.03em}
.stat span{font-size:.85rem;font-weight:600}
@media(max-width:940px){
  .about{grid-template-columns:1fr;gap:3.5rem}
  .about-visual > img{height:25rem}
  .stat{right:1rem;bottom:-1.25rem}
}

/* ---- About, classic layout (old site) ----
   A smaller photo layered over the main one on a green offset block, the stat
   badge at the top right, and the award row closing the copy. The old site
   squared these corners; they are rounded now like every other image, and the
   green block is rounded with them so the photo is not framed by a square. */
.about-classic{align-items:center}
.about-classic h2{font-size:clamp(1.85rem,3.1vw,2.5rem);line-height:1.3}
.about-classic .lead{margin-top:.5rem;color:var(--slate);font-weight:500;font-size:1rem;line-height:1.8}
.about-classic .values{margin-top:1.875rem;gap:.75rem}
.about-classic .values li{
  padding:0;border-bottom:0;gap:.625rem;align-items:flex-start;
  color:var(--slate);font-weight:500;line-height:1.8;
}
/* Filled square tick, matching the old list marker. */
.about-classic .tick{
  flex:0 0 1rem;width:1rem;height:1rem;border-radius:2px;background:var(--green);margin-top:.4375rem;
}
.about-classic .tick svg{width:.625rem;height:.625rem;fill:#fff}
.about-classic .about-visual{display:flex;justify-content:flex-end;padding-bottom:1.875rem}
.about-classic .about-visual > img{
  width:min(100%,30.9375rem);height:34.375rem;box-shadow:none;
}
/* NO GREEN BEHIND IT ANY MORE. This box was .9375rem larger than the picture
   in both directions and filled --green, so the photo sat bottom-right of a
   green rectangle and 15px of it showed along the top and left as an offset
   accent. The green is gone and the PICTURE takes the whole box instead — same
   footprint on the page, a photo 245x225 where it was 230x210, and nothing
   behind it to show through. The radius comes from the site's img rule, so it
   still matches the main photo above it. */
.about-float{
  position:absolute;left:0;bottom:0;width:15.3125rem;height:14.0625rem;
  border-radius:var(--r-img);
}
.about-float img{display:block;width:100%;height:100%;object-fit:cover}
/* Badge moves to the top right; white on green, as everywhere else on the site.
   Rounded to match: it overlaps the main photo, so a square badge on a rounded
   photo reads as a mistake rather than as a style.

   It HANGS OFF the photo's right edge, as on the old site — measured there at
   1440px, the badge overhangs the photo by 85px of its 230px width, so a third
   of it sits in the whitespace beside the picture rather than on it.

   How far it can hang depends on the room beside the container, so this is in
   two steps rather than one. The column ends 1.75rem inside the wrap (the
   wrap's own padding), and that much overhang is free at every width. The full
   85px needs 57px of gutter beyond the wrap as well, which only exists once
   the wrap has stopped growing and the viewport is still widening. */
.about-classic .stat{
  top:2.5rem;right:-1.75rem;bottom:auto;left:auto;width:14.375rem;
  padding:2.5rem;border-radius:var(--r);box-shadow:none;
}
/* The full overhang needs the wrap plus 2×57px of gutter: 1400 + 114 = 1514px
   of USABLE width. 96rem (1536px) rather than the 1514 the arithmetic gives,
   because a classic scrollbar takes ~15px that this query does not see — the
   same margin the 1240px wrap needed before --max moved to 87.5rem. */
@media(min-width:96rem){
  .about-classic .stat{right:-5.3125rem}
}
.about-classic .stat-icon{display:block;width:3.9375rem;height:auto;margin-bottom:1.25rem}
.about-classic .stat b{font-size:1.45rem;font-weight:700;letter-spacing:normal}
.about-classic .stat span{display:block;margin-top:.375rem;font-size:1rem;font-weight:500}
.about-awards{
  display:flex;align-items:center;flex-wrap:wrap;gap:2.5rem;
  list-style:none;margin:2.5rem 0 0;padding:0;
}
.about-awards img{display:block;height:2.375rem;width:auto}
.about-awards a{display:block}
@media(max-width:940px){
  .about-classic .about-visual{justify-content:flex-start}
  .about-classic .about-visual > img{height:25rem}
  .about-classic .stat{top:auto;bottom:-1.25rem;right:0}
}
@media(max-width:600px){
  /* Below this the layered photo would cover the main one, and the badge has
     no corner left to sit in — it becomes a block under the photo. The visual
     drops out of flex first, or the static badge would stay a flex item beside
     the photo and push the page wider than the viewport. */
  .about-float{display:none}
  .about-classic .about-visual{display:block}
  .about-classic .about-visual > img{width:100%}
  .about-classic .stat{position:static;width:auto;padding:1.625rem 2rem}
  .about-classic .stat-icon{margin-bottom:.75rem}
}

/* ============ BLOG ARTICLE + PAGER ============ */
/* Article layout from example/parnpartners-blogi-artikkel-v2.html, with the
   greens that touch text swapped to --green-text: the mockup's --green on
   white is 2.3:1, well under the 4.5:1 body-text minimum. (Checklist 8.4) */
.art-layout{display:grid;grid-template-columns:minmax(0,1fr) 20.625rem;gap:4.375rem;align-items:start}
.art-cover{border-radius:var(--r-img);overflow:hidden;box-shadow:var(--shadow);max-height:28.75rem}
.art-cover img{width:100%;height:100%;object-fit:cover}
.art-title{font-size:clamp(1.85rem,3.2vw,2.6rem);margin:2.375rem 0 0;letter-spacing:-.03em}
.art-meta{
  display:flex;align-items:center;gap:1.375rem;flex-wrap:wrap;font-size:.9rem;color:var(--muted);
  margin:1.375rem 0 2.375rem;padding-bottom:1.875rem;border-bottom:1px solid var(--line);
}
.art-meta b{color:var(--navy);font-weight:600}
.art-meta .who{display:flex;align-items:center;gap:.6875rem}
.art-meta .who span{line-height:1.4}
.art-meta .who img{width:2.5rem;height:2.5rem;border-radius:50%;object-fit:cover;object-position:center 18%}

.prose{font-size:1.08rem;line-height:1.85;color:var(--slate)}
.prose > * + *{margin-top:1.625rem}
.prose p{margin:0 0 1.625rem}
.prose p.lead-p{font-size:1.22rem;line-height:1.65;color:var(--navy);font-weight:500;margin-bottom:1.875rem}
.prose h2{font-size:1.5rem;margin:2.625rem 0 1rem}
.prose h3{font-size:1.2rem;margin:2rem 0 .75rem}
.prose ul,.prose ol{padding-left:1.5rem;display:grid;gap:.5rem}
.prose img{max-width:100%;height:auto;border-radius:var(--r-img);margin:1.5rem 0}
.prose blockquote{
  margin:2.125rem 0;padding:1.5rem 1.875rem;background:var(--paper-soft);
  border-left:3px solid var(--green);border-radius:0 var(--r) var(--r) 0;color:var(--navy);font-weight:500;
}
.prose a{color:var(--green-logo);text-decoration:underline;text-underline-offset:3px}

.share{display:flex;align-items:center;gap:.75rem;margin-top:1.625rem;flex-wrap:wrap}
.share span{font-size:.86rem;color:var(--muted);font-weight:500}
.share a{
  width:2.375rem;height:2.375rem;border:1px solid var(--field-line);border-radius:50%;
  display:grid;place-items:center;color:var(--slate);transition:.28s;
}
.share a:hover{background:var(--navy);border-color:var(--navy);color:#fff}
.share svg{width:.9375rem;height:.9375rem;fill:currentColor}

.prevnext{display:grid;grid-template-columns:1fr 1fr;gap:1.375rem;margin-top:3.75rem;padding-top:2.5rem;border-top:1px solid var(--line)}
.pn{border:1px solid var(--line);border-radius:var(--r);padding:1.5rem;transition:.35s var(--t);background:#fff}
.pn:hover{border-color:transparent;box-shadow:var(--shadow);transform:translateY(-.25rem)}
.pn small{font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--green-logo);font-weight:700}
.pn b{display:block;margin-top:.5625rem;color:var(--navy);font-size:1rem;font-weight:600;line-height:1.4}
.pn.next{text-align:right}

.sidebar{position:sticky;top:7rem;display:grid;gap:1.625rem}
.side-card{border:1px solid var(--line);border-radius:var(--r);padding:1.625rem;background:#fff}
.side-card h2{font-size:.75rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin:0 0 1.25rem}
.mini{display:flex;gap:.875rem;padding:.875rem 0;border-bottom:1px solid var(--line-soft)}
.mini:last-child{border-bottom:0;padding-bottom:0}
.mini:first-of-type{padding-top:0}
.mini img{width:4.125rem;height:3.5rem;border-radius:var(--r-img);object-fit:cover;flex:0 0 4.125rem;background:var(--paper-soft)}
.mini b{display:block;font-size:.92rem;color:var(--navy);font-weight:600;line-height:1.35;transition:color .25s}
.mini:hover b{color:var(--green-logo)}
.mini span{font-size:.79rem;color:var(--muted)}
.side-cta{background:var(--navy);color:#fff;border-radius:var(--r);padding:1.875rem}
.side-cta b{display:block;font-size:1.12rem;color:#fff;margin-bottom:.625rem}
.side-cta p{font-size:.9rem;color:rgba(255,255,255,.78);margin:0 0 1.25rem}

@media(max-width:1000px){
  .art-layout{grid-template-columns:1fr;gap:3.125rem}
  .sidebar{position:static}
}
@media(max-width:600px){
  .prevnext{grid-template-columns:1fr}
  .pn.next{text-align:left}
}

.pager{margin-top:3rem}
.pager ul{display:flex;gap:.5rem;justify-content:center;list-style:none;margin:0;padding:0;flex-wrap:wrap}
.pager a,.pager span{
  display:grid;place-items:center;min-width:2.75rem;min-height:2.75rem;padding:0 .75rem;
  border:1px solid var(--line);border-radius:var(--r-ui);font-weight:600;font-size:.95rem;color:var(--navy);
}
.pager a:hover{border-color:var(--navy)}
/* Current page: filled AND marked with aria-current, never colour alone. */
.pager span[aria-current]{background:var(--navy);border-color:var(--navy);color:#fff}

/* ============ 404 ============ */
/* The banner above it carries the heading, so this is the sentence and the way
   out, centred under it. Measure and padding follow .text-block — the other
   page here that is a banner and then nothing but words. */
.error-page{padding:5rem 0 6.5rem;text-align:center}
.error-page p{max-width:34rem;margin:0 auto;font-size:1.08rem;line-height:1.85;color:var(--slate)}
.error-page .btn{margin-top:2rem}
@media(max-width:768px){.error-page{padding:3.25rem 0 4rem}}

/* ============ TEXT BLOCK (a page that is only text) ============ */
/* The privacy policy is what uses this: a page-title banner and then nothing
   but running text. Typography is .prose, borrowed whole from the blog
   article rather than written twice, so a heading, a list and a link look the
   same wherever a page is read rather than skimmed.

   .prose sets no width — in the article the sidebar column supplies one — so
   the measure is set here. 46rem at 1.08rem is about 75 characters a line;
   .wrap's 87.5rem would be nearer 200, which is where the eye loses its place
   coming back to the left margin. (Checklist 8.5) */
.text-block{padding:5rem 0 6.5rem}
/* Centred, not left-hugging: the banner above it is centred, and a 46rem
   column pinned to the left of a 87.5rem wrap reads as a layout that broke
   rather than a measure that was chosen. */
.text-block .prose{max-width:46rem;margin-inline:auto}
@media(max-width:768px){.text-block{padding:3.25rem 0 4rem}}

/* ============ CLIENT LOGOS ============ */
/* A static, centred strip. It used to scroll; the motion was dropped because it
   carried no information the still row does not — and with it goes the pause
   control that continuous motion would have required (Checklist 1.24) and the
   prefers-reduced-motion special case (1.25). Wrapping rather than scrolling
   also means every logo is visible at once at 320px and at 200% zoom. */
.logo-strip{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:2.5rem 4.75rem;list-style:none;margin:0;padding:.875rem 0;
}
/* Greyscale keeps a wall of competing brand colours from pulling focus off the
   heading. It lifts to full colour on hover and on keyboard focus alike, so a
   keyboard user gets the same affordance as a mouse user (1.18). */
.logo-strip img{
  height:2.875rem;width:auto;object-fit:contain;
  mix-blend-mode:multiply;filter:grayscale(1);opacity:.72;transition:filter .35s,opacity .35s;
}
.logo-strip li:hover img,
.logo-strip li:focus-within img{filter:none;opacity:1}
@media(max-width:768px){
  .logo-strip{gap:2rem 2.75rem}
  .logo-strip img{height:2.25rem}
}

/* ============ CONTACT ============ */
/* Mirrors the old contact page: form on the left and wider, contact details
   on the right, full-bleed map underneath. */
.contact-grid{display:grid;grid-template-columns:1.4fr 1fr;gap:3.5rem;align-items:start}
.contact-form-col h2{font-size:2.5rem;font-weight:800;margin-bottom:.25rem}
.contact-form-col .lead{font-size:1.25rem}
.contact-details-col h3{font-size:1.75rem;font-weight:800;margin-bottom:.5rem}
.contact-details-col > p{color:var(--slate);margin-bottom:1.5rem}

.contact-boxes{display:grid;gap:1.75rem;font-style:normal;margin-top:1.75rem}
.contact-box{display:flex;gap:1.25rem;align-items:flex-start}
/* No disc behind the glyph: the old page drew these plain, and the shape
   reads better at this size without a tint competing with it. */
.contact-box-icon{flex:0 0 2.75rem;width:2.75rem;height:2.75rem;display:grid;place-items:center}
.contact-box-icon svg{width:2.75rem;height:2.75rem;fill:var(--green)}
.contact-box-text{display:grid;gap:.25rem}
.contact-box-title{font-size:1.15rem;font-weight:700;color:var(--navy)}
.contact-box a{color:var(--slate)}
.contact-box a:hover{color:var(--green-logo);text-decoration:underline}

/* Light-background variant of the footer's social row. */
.social-light{margin-top:1.75rem}
.social-light a{border-color:var(--line);color:var(--slate)}
.social-light a:hover{background:var(--green);border-color:var(--green);color:#fff}

.contact-form{display:grid;gap:1.25rem;margin-top:1.5rem}
.contact-form .field{display:grid;gap:.375rem}
.contact-form label{font-size:.9rem;font-weight:600;color:var(--navy)}
.contact-form .req{color:var(--green-text)}
/* --field-line, not --line: a form control's border is a meaningful UI
   boundary and needs 3:1 (WCAG 1.4.11). --line is 1.21:1 on white — fine for
   a decorative card edge, not for telling someone where the input is.

   ROUNDED ON --r, THE SITE'S OWN RADIUS, replacing a 2px that read as square
   beside the pill-shaped submit button sitting in the same form. Not the pill
   itself: at 6.25rem the textarea below — nine rems tall and resizable — would
   bow at both ends, and a control the user can drag taller cannot depend on
   its own height for its shape. --r is what the cards and images already use,
   so the form now agrees with the page around it as well as with itself. */
.contact-form input,.contact-form textarea{
  font:inherit;font-size:1rem;color:var(--slate);background:#fff;
  border:1px solid var(--field-line);border-radius:var(--r);padding:.875rem 1rem;width:100%;
}
.contact-form input:hover,.contact-form textarea:hover{border-color:var(--muted)}
.contact-form textarea{min-height:9rem;resize:vertical}
.contact-form .two{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem}
/* justify-self, not align-self: in a grid it is the inline axis that
   decides width, so align-self alone left the button full-bleed. */
.contact-form button{justify-self:start;padding:.8rem 2.5rem}
.form-status{font-size:.92rem;min-height:1.4em}
.form-status.is-error{color:#B3261E}
.form-status.is-success{color:var(--green-text)}
.form-note{font-size:.78rem;color:var(--muted);line-height:1.5}
.form-note a{text-decoration:underline}

/* Full-bleed, matching the old page's edge-to-edge map. */
.contact-map{border:0;display:block;width:100%;height:31.25rem}
@media(max-width:900px){
  .contact-grid{grid-template-columns:1fr;gap:2.5rem}
  .contact-form .two{grid-template-columns:1fr}
  .contact-map{height:20rem}
}

/* ---- Scroll reveal -----------------------------------------
   Opt-in: content is visible by default and only hidden once
   main.js sets .js-reveal on <html>. If JS never runs, nothing
   is invisible. */
.js-reveal .rv{opacity:0;transform:translateY(1.625rem);transition:opacity .8s var(--t),transform .8s var(--t)}
.js-reveal .rv.in{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js-reveal .rv{opacity:1;transform:none;transition:none}
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
}

/* ============ ACCESSIBILITY PANEL (pcadmin component) ============
   The component ships its own stylesheet, but its markup is Bootstrap-classed
   — container-fluid, row, col-lg-4, the spacing utilities — and this site does
   not load Bootstrap, so the three groups stacked full-width and the panel ran
   773px tall. These are exactly the classes its markup uses and nothing more,
   scoped to the panel and its toggle so no Bootstrap-shaped names leak into a
   stylesheet that deliberately has none. */
/* Full-bleed, as container-fluid means: the panel is a band across the top of
   the viewport, not part of the page's 77.5rem column, so it must not inherit
   the site's width. Only the padding utilities inset its contents. */
#accessibility-controls .container-fluid{width:100%;max-width:none;margin:0}
#accessibility-controls .row{display:flex;flex-wrap:wrap;align-items:flex-start}
#accessibility-controls .col{flex:1 0 0%}
#accessibility-controls .col-auto{flex:0 0 auto;width:auto}
#accessibility-controls .col-12{flex:0 0 auto;width:100%}
#accessibility-controls .align-items-center{align-items:center}
#accessibility-controls .border-bottom{border-bottom:1px solid rgba(255,255,255,.2)}
#accessibility-controls .text-white{color:#fff}
#accessibility-controls .fw-semibold{font-weight:600}
#accessibility-controls .px-3{padding-left:1rem;padding-right:1rem}
#accessibility-controls .py-2{padding-top:.5rem;padding-bottom:.5rem}
#accessibility-controls .py-3{padding-top:1rem;padding-bottom:1rem}
#accessibility-controls .mb-0{margin-bottom:0}
#accessibility-controls .mb-3{margin-bottom:1rem}
/* The close button is a bare icon here, not the site's green pill. */
/* font-family is stated because a <button> does NOT inherit it: without this
   the label reads in the browser's own UI font beside a page set in Inter. */
#accessibility-controls .btn,
#accessibility-toggle{
  display:inline-flex;align-items:center;gap:0;
  padding:0;border:0;border-radius:0;background:none;
  font-family:inherit;font-size:inherit;font-weight:inherit;
  letter-spacing:normal;white-space:normal;
}
/* The component sets these on the span with !important, so matching the site's
   nav links takes the same weapon. Same size and weight as .menu a.top. */
#accessibility-toggle span{
  font-family:inherit!important;font-size:.95rem!important;font-weight:600!important;
  color:var(--navy)!important;
}
#accessibility-controls .btn:hover{transform:none;box-shadow:none}

/* Bootstrap's lg breakpoint, which is what col-lg-4 and mb-lg-0 mean. */
@media(min-width:62rem){
  #accessibility-controls .col-lg-4{flex:0 0 auto;width:33.3333%}
  #accessibility-controls .mb-lg-0{margin-bottom:0}
  #accessibility-controls .px-lg-5{padding-left:3rem;padding-right:3rem}
}

/* The toggle sits inside <nav>, after the menu and before the language picker.
   It is NOT inside .nav-cta, and should stay out of it: the toggle carries the
   class `btn`, so it was in reach of the `.nav-cta .btn{display:none}` that hid
   the header's contact button under 1080px, and survived only because an ID
   selector happened to outrank it. That button and its rule are both gone now,
   but the collision would come straight back with the next `.nav-cta .btn`. */
.header-row{display:flex;align-items:center;gap:1.25rem}
.header-row .nav{flex:1 1 auto;min-width:0}
/* The toggle is an <li> in .menu now, so it takes the list's own 2.125rem
   rhythm and needs no spacing of its own. .nav-item is the class the component
   puts on it. */
.menu > li.nav-item{display:flex;align-items:center}
#accessibility-toggle{
  min-width:2.25rem;min-height:2.25rem;justify-content:center;gap:.375rem;
  padding:0 .5rem;border-radius:var(--r-ui);color:var(--navy);cursor:pointer;transition:background .25s;
}
#accessibility-toggle:hover{background:var(--paper-soft);opacity:1}
#accessibility-toggle i{color:var(--navy)}

/* THE TWO WIDTHS WANT OPPOSITE HALVES OF THIS BUTTON, and it has exactly two:
   an icon and a word.

   Wide, it stands in the menu row after the last page link, so it is a word
   like every other item in that row and the icon is the thing that would make
   it look bolted on. Narrow, the row is the logo, the burger and this, there
   is no room for a word, and the icon is the whole control.

   Either way the button keeps its name: it carries aria-label, so what is
   announced does not change with the viewport. (14.8) Hiding a part rather
   than shrinking it keeps the 36px target at both widths. (7.8) The control
   itself is never hidden — the panel behind it is most wanted on exactly the
   devices that get the narrow layout. (5.1) */
@media(min-width:1081px){
  #accessibility-toggle i{display:none}
}
@media(max-width:1080px){
  #accessibility-toggle span{display:none}
  #accessibility-toggle i{margin-right:0!important}
}

/* ============ COOKIE CONSENT (pcadmin component) ============
   The Silktide consent manager ships in its own purple (#533BE2), which
   appears nowhere else here. It is token-driven, so most of this is handing it
   the site's values rather than restyling it.

   EVERY RULE IS PREFIXED WITH `html` ON PURPOSE. consent.css is emitted at the
   end of <body>, after this file, so a plain `#silktide-wrapper` rule would
   lose on source order at equal specificity. `html #silktide-wrapper` is 1-0-1
   against its 1-0-0 and wins without !important.

   THE COMPONENT HAS ONE GREEN WHERE THIS SITE HAS TWO. Its --primaryColor is
   used as a fill AND as text, and the site's rule (see the header of this
   file) is that those are different values: --green is the fill, and text on
   it is white; --green-text is the darkened green for green TEXT on a light
   background, because --green on white is 2.33:1. So --primaryColor is set to
   the TEXT green — it reaches links, the "Eelistused" button and the modal
   heading rule — and every place the component uses it as a FILL is restated
   below in --green with white on top, per deviation 1. Handing it --green
   instead would paint the LINKS at 2.33:1 as well; leaving the fills alone
   would paint the panel in a dark green this site uses nowhere. */
html #silktide-wrapper{
  --primaryColor:var(--green-text);
  --textColor:var(--slate);
  --backgroundColor:var(--paper);
  --fontFamily:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  /* A fill, so brand green, with the icon drawn WHITE on top — the same trade
     as every other green fill, per deviation 1. It is a graphic, so its bar is
     3:1 rather than 4.5:1, and white on --green misses even that at 2.33:1;
     navy was 6.72:1. The component's two names are the wrong way round:
     --cookieIconColor is the disc and --cookieIconBackgroundColor is the glyph
     drawn on it. */
  --cookieIconColor:var(--green);
  --cookieIconBackgroundColor:#fff;
  --boxShadow:var(--shadow);
  /* The component draws focus as a box-shadow rather than an outline, so the
     site's 3px green ring is restated in that form. White first, so the ring
     reads against a green button as well as against the white panel. */
  --focus:0 0 0 3px var(--paper),0 0 0 6px var(--green-text);
}

/* The banner and the modal are cards, and this site's cards are --r. */
html #silktide-wrapper #silktide-banner,
html #silktide-wrapper #silktide-modal{border-radius:var(--r)}

/* consent.css sets no font-family on its buttons at all, so they rendered in
   the UA default beside a panel set in Inter. The rest matches .btn. */
html #silktide-wrapper .st-button{
  font-family:inherit;font-size:.95rem;font-weight:600;letter-spacing:.01em;
  padding:.9375rem 1.75rem;border-radius:6.25rem;border-width:1.5px;
  transition:all .35s var(--t);
}

/* BOTH ANSWERS KEEP THE SAME SIZE AND THE SAME SOLIDITY. The component ships
   accept and reject as one style — two identical filled buttons — and that
   parity is the point: making "accept" a filled pill and "reject" a faint
   outline is the nudge consent guidance calls a dark pattern, and it would be
   this file that introduced it. They are told apart by colour, and both
   colours are the site's. Matched on the component's own accept-all /
   reject-all classes, the only thing in its markup that separates them, in
   the banner and again in the modal where they repeat under longer names. */
html #silktide-wrapper .accept-all.st-button,
html #silktide-wrapper .preferences-accept-all.st-button{
  background-color:var(--green);border-color:var(--green);color:#fff;
  box-shadow:0 .75rem 1.75rem -.75rem rgba(102,190,61,.7);
}
html #silktide-wrapper .accept-all.st-button:hover,
html #silktide-wrapper .preferences-accept-all.st-button:hover{
  background-color:var(--green-dark);border-color:var(--green-dark);color:#fff;
}
html #silktide-wrapper .reject-all.st-button,
html #silktide-wrapper .preferences-reject-all.st-button{
  background-color:var(--navy);border-color:var(--navy);color:#fff;
}
html #silktide-wrapper .reject-all.st-button:hover,
html #silktide-wrapper .preferences-reject-all.st-button:hover{
  background-color:var(--navy-soft);border-color:var(--navy-soft);color:#fff;
}

/* An ON switch is a green fill, so it takes the pair the site's green fills
   always take — white on --green now, per deviation 1. The rule stays rather
   than being deleted: the component would otherwise draw "ON" in
   --backgroundColor, and that being white here is coincidence, not intent. */
html #silktide-wrapper #silktide-modal .switch input:checked + .switch__pill{background:var(--green)}
html #silktide-wrapper #silktide-modal .switch input:checked ~ .switch__on{color:#fff}

/* The component squares a button off to 5px WHILE FOCUSED — its focus rule
   sets border-radius beside the box-shadow — so a pill snapped to a rectangle
   the moment it was tabbed to. The ring is what should change on focus. */
html #silktide-wrapper #silktide-banner .st-button:focus,
html #silktide-wrapper #silktide-modal .st-button:focus{border-radius:6.25rem}

/* Headings are the site's, not body text in disguise. */
html #silktide-wrapper #silktide-modal h1{
  color:var(--navy);font-weight:700;letter-spacing:-.02em;
}

/* Icon-only controls are navy here, as the header's accessibility toggle is. */
html #silktide-wrapper #silktide-modal .modal-close{color:var(--navy)}

/* "Eelistused" is a <button> styled as a link, and a <button> inherits no
   font-family: it read in the UA default. Same underline as body copy links. */
html #silktide-wrapper #silktide-banner .preferences{font-family:inherit;font-size:.95rem;font-weight:600}
html #silktide-wrapper #silktide-banner .preferences span,
html #silktide-wrapper a{text-underline-offset:3px}
