/* ==========================================================================
   dns-tokens.css
   dubainotaryservices.ae, design 07: the Upload Desk

   THE ONLY FILE IN THIS THEME ALLOWED TO CONTAIN A HEX CODE.
   That is enforced by lint_dns_css.py and it is the reason a palette change
   is one file rather than a search and replace across fifty kilobytes.

   THE DIRECTION
   The page opens with a drop zone, not a photograph of a handshake. So the
   system is tool-like rather than ceremonial: white ground, near black ink,
   one green that means "this is the thing to press", and a deep green-black
   for the panels that carry the answer back. It reads as an instrument you
   operate, which is what the concept is.

   Nothing here is shared with the client's other two sites. Site 1 is navy
   and gold with a serif on a skyline photograph. notaryservicesdubai.com is
   navy and yellow. This is white, ink and green with a grotesque. The three
   sites cannot be mistaken for each other, which was the original brief.

   CONTRAST IS MEASURED, NOT ESTIMATED
   Every pairing below carries its computed WCAG 2.1 ratio, produced by
   05-Scripts/check_contrast.py against these exact values. Two rules fell out
   of that measurement and both are load bearing:

     1. --dns-action is NOT the bright green. The bright green reaches only
        2.35:1 on white, which fails AA for text and for a button label. The
        action token is the darker green at 5.14:1. The bright one is called
        --dns-action-bright and is legal ONLY on the dark surface, where it
        measures 7.77:1.
     2. --dns-border is a hairline for dividers and measures 1.21:1. It is
        illegal as the boundary of anything you click or type into, because
        SC 1.4.11 wants 3:1 for a control. --dns-border-strong exists for
        that job and measures 3.71:1.

   ========================================================================== */

:root {

  /* --- surfaces ---------------------------------------------------------
     A white page with a green-grey sunken band. The sunken band is only 3%
     off white, which is enough that a white card sitting on it reads as a
     raised object without needing a shadow. That was the fix for the site
     looking like a wireframe: it was not the hue, it was that nothing had a
     surface.                                                              */
  --dns-surface:         #FFFFFF;   /* page ground                          */
  --dns-surface-raised:  #FFFFFF;   /* cards, with a border                 */
  --dns-surface-sunken:  #F3F7F5;   /* alternating bands                    */
  --dns-surface-invert:  #101619;   /* dark panels, the answer surface      */
  --dns-surface-invert-2:#1A2228;   /* cards inside a dark panel            */

  /* Legacy names the existing stylesheet still consumes. Remapped rather
     than removed, so a page that has not been rebuilt yet still renders in
     the new palette instead of falling back to unstyled.                   */
  --dns-leaf:      #FFFFFF;
  --dns-ground:    #F3F7F5;
  --dns-band:      #E7F0EC;
  --dns-tint-lt:   #D4E5DE;
  --dns-plum:      #101619;
  --dns-plum-deep: #080D10;
  --dns-meta:      #55606A;
  --dns-edge:      #94A3A0;

  /* --- ink ---------------------------------------------------------------
     ink        on surface        18.25:1   AAA
     text       on surface        12.67:1   AAA
     text-muted on surface         6.43:1   AA  body, AAA large
     text-muted on surface-sunken  5.95:1   AA
     ink        on surface-sunken 16.89:1   AAA                            */
  --dns-ink:         #101619;
  --dns-text:        #2B343B;
  --dns-text-muted:  #55606A;

  /* text-invert        on surface-invert  16.75:1  AAA
     text-invert-muted  on surface-invert   7.58:1  AAA
     text-invert-muted  on surface-invert-2 6.69:1  AA                     */
  --dns-text-invert:       #F2F6F5;
  --dns-text-invert-muted: #9CA9B1;

  /* --- action ------------------------------------------------------------
     THE BRIGHT GREEN IS NOT A TEXT COLOUR ON WHITE. Measured 2.35:1, which
     fails AA at every size that matters. It is legal on the dark surface
     only.

     white         on action          5.14:1  AA
     white         on action-hover    7.71:1  AA
     action-bright on surface-invert  7.77:1  AA
     action        on surface         5.14:1  AA  so it may be a link colour
     action        on surface-sunken  4.76:1  AA                           */
  --dns-action:        #0A7D57;   /* fills and links on light              */
  --dns-action-hover:  #075F42;
  --dns-action-bright: #17C089;   /* on dark surfaces ONLY                 */
  --dns-action-soft:   #E6F5EF;   /* tinted panels behind action content   */


  /* WhatsApp green is fixed by the platform and is not ours to adjust.
     Measured: #0B2E18 on #25D366 is 7.47:1, so the label is dark, never
     white, which would have been 2.36:1 and illegal.                      */
  --dns-wa:            #25D366;
  --dns-wa-ink:        #0B2E18;

  /* --- status ------------------------------------------------------------
     Semantic colour, kept separate from the brand accent so "accepted" and
     "press this" are never the same green.
     white on ok 5.41:1, white on warn 5.42:1, white on stop 6.03:1        */
  --dns-ok:    #17794F;
  --dns-warn:  #9A5B0B;
  --dns-stop:  #B03A28;

  /* --- borders -----------------------------------------------------------
     border        on surface        1.21:1  dividers only, ILLEGAL on controls
     border-strong on surface        3.71:1  mandatory on inputs and buttons
     border-strong on surface-sunken 3.43:1

     The first value chosen here was #94A3A0, which looked right and measured
     2.62:1 on white and 2.43:1 on the band. Both fail SC 1.4.11. It was
     caught by check_contrast.py rather than by eye, which is the entire
     argument for measuring: a control boundary that is slightly too pale is
     invisible as a bug and illegal as a fact.                             */
  --dns-border:        #E4EBE8;
  --dns-border-strong: #798884;
  --dns-border-width:  1px;

  /* --- focus -------------------------------------------------------------
     A visible focus ring is not optional. focus on surface is 5.14:1 and on
     surface-invert 3.55:1, so the same ring is legible on both grounds.   */
  --dns-focus:        #0A7D57;
  --dns-focus-width:  3px;
  --dns-focus-offset: 2px;

  /* --- type --------------------------------------------------------------
     Familjen Grotesk was already self hosted and does the display work:
     crisp, slightly Swedish, and nothing like the serif on site 1.
     Public Sans carries body text because it was drawn for civic use and
     stays legible at 16px without personality fighting the headings.
     Both are variable 400 to 700, so weight costs no extra request.

     Arabic is Noto Sans Arabic, variable 100 to 900, so 600 and 700 are
     drawn weights. A synthesised bold on Arabic is visibly wrong, and
     font-synthesis is switched off in dns-fonts.css so a failed load breaks
     visibly rather than faking it.                                        */
  --dns-font-display:    "Familjen Grotesk", "Familjen Fallback", system-ui, sans-serif;
  --dns-font-text:       "Public Sans", "Public Fallback", system-ui, sans-serif;
  --dns-font-display-ar: "Noto Sans Arabic", "Noto Arabic Fallback", system-ui, sans-serif;
  --dns-font-text-ar:    "Noto Sans Arabic", "Noto Arabic Fallback", system-ui, sans-serif;

  /* Body is 16px. Both dated competitors in the survey shipped 13 to 14px
     and every premium one used 16.                                        */
  --dns-text-xs:   0.75rem;    /* 12 */
  --dns-text-sm:   0.875rem;   /* 14 */
  --dns-text-base: 1rem;       /* 16 */
  --dns-text-md:   1.125rem;   /* 18 */
  --dns-text-lg:   1.375rem;   /* 22 */
  --dns-text-xl:   1.75rem;    /* 28 */
  --dns-text-2xl:  2.25rem;    /* 36 */
  --dns-text-3xl:  2.875rem;   /* 46 */
  --dns-text-4xl:  clamp(2.25rem, 1.4rem + 3.4vw, 3.75rem);

  --dns-weight-normal: 400;
  --dns-weight-medium: 500;
  --dns-weight-bold:   600;
  --dns-weight-heavy:  700;

  --dns-leading-tight:  1.08;
  --dns-leading-snug:   1.28;
  --dns-leading-normal: 1.62;

  --dns-tracking-label: 0.11em;

  /* --- space -------------------------------------------------------------
     A 4px base. Named by step rather than by size so a rhythm change is one
     edit here.                                                            */
  --dns-s1:  0.25rem;
  --dns-s2:  0.5rem;
  --dns-s3:  0.75rem;
  --dns-s4:  1rem;
  --dns-s5:  1.5rem;
  --dns-s6:  2rem;
  --dns-s7:  2.5rem;
  --dns-s8:  3rem;
  --dns-s10: 4rem;
  --dns-s12: 5rem;
  --dns-s16: 7rem;

  --dns-section-y:     clamp(3rem, 1.6rem + 5.6vw, 6rem);
  --dns-section-y-act: clamp(2.25rem, 1.4rem + 3.4vw, 4rem);

  /* The stacking gap for bare content modules that carry no padding of
     their own (leafgrid, leafgrid--compact, parallel, docket, a plain
     prose paragraph or table). One token per module, same clamp as
     --dns-section-y-act to start, so each can be turned up or down on its
     own without moving the others. */
  --dns-gap-leafgrid:         clamp(2.25rem, 1.4rem + 3.4vw, 4rem);
  --dns-gap-leafgrid-compact: clamp(2.25rem, 1.4rem + 3.4vw, 4rem);
  --dns-gap-parallel:         clamp(2.25rem, 1.4rem + 3.4vw, 4rem);
  --dns-gap-docket:           clamp(2.25rem, 1.4rem + 3.4vw, 4rem);
  --dns-gap-prose:            clamp(2.25rem, 1.4rem + 3.4vw, 4rem);

  /* --- geometry ----------------------------------------------------------
     ONE radius, used everywhere. The single fastest way a site reads as
     cheap is mixed radii: the survey found one competitor running 2px, 5px
     and 30px on the same screen.                                          */
  /* Tightened 4 September 2026 on the client's instruction: no card may
     carry a radius above 8px. The pill stays, but only for things that are
     genuinely circular, the phone disc, the step numeral and the FAQ
     toggle. Chips moved off it, which also takes them further from site 1,
     whose chips are full pills. */
  --dns-radius:      4px;
  --dns-radius-lg:   6px;
  --dns-radius-pill: 999px;

  --dns-wrap:      75rem;    /* 1200 */
  --dns-wrap-pad:  clamp(1.25rem, 0.7rem + 2.2vw, 2.5rem);
  --dns-gutter-track: 8.5rem;

  /* 44px, the minimum tap target. */
  --dns-target-min: 2.75rem;

  /* --- elevation ---------------------------------------------------------
     Restrained. The sunken band does most of the separation work, so
     shadows only lift the things that genuinely float.                    */
  --dns-lift-1: 0 1px 2px rgba(16, 22, 25, 0.05);
  --dns-lift-2: 0 2px 4px rgba(16, 22, 25, 0.05), 0 10px 24px -14px rgba(16, 22, 25, 0.18);
  --dns-lift-3: 0 4px 8px rgba(16, 22, 25, 0.06), 0 24px 48px -22px rgba(16, 22, 25, 0.28);

  --dns-transition: 160ms cubic-bezier(0.2, 0, 0.2, 1);

  /* --- added 4 September 2026 for the business rendering --------------
     A larger radius for cards, and the two overlays a photograph wears.
     overlay-ink over a pure white pixel, the worst case a photograph can
     contain, composites to a ground on which text-invert measures better
     than 7:1. overlay-action alone composites to roughly 2:1 for white
     text, so it is never placed under text on its own: it sits beside the
     text column, or on top of the ink layer, where it can only darken.  */
  --dns-radius-xl:      8px;

  /* Reweighted 4 September 2026. The client's objection was that the
     photographs were drowned: the Dubai skyline read as one flat green on
     desktop and as nearly black on a phone. Both overlays came down, and
     every figure below is composited over a pure white pixel, the worst
     case any photograph can contain, and measured against text-invert.

       ink 0.78, the old value      9.08:1
       ink 0.72, the new value      7.28:1   still better than 7:1
       ink 0.78 under action 0.55   6.80:1   the old pair
       ink 0.72 under action 0.24   8.10:1 at 0.78, and better at 0.72

     Cutting the green raises the contrast rather than lowering it, because
     the green composites lighter than the ink beneath it. The photograph
     comes back and the text gets safer, which is not the trade off it
     looked like. Action alone is still never placed under text: at 0.24 it
     composites to 1.4:1, so it sits beside the text column or on top of
     the ink, where it can only darken. */
  --dns-overlay-ink:    rgba(16, 22, 25, 0.72);
  --dns-overlay-action: rgba(10, 125, 87, 0.24);
}

/* Motion is decoration here, so it goes away entirely when asked. */
@media (prefers-reduced-motion: reduce) {
  :root { --dns-transition: 0ms; }
}
