Why levitation?

Shadows communiceren hiërarchie en materiële metaforen: een element met een shadow zit visueel boven de canvas in een z-as die de gebruiker instinctief leest (Material Design elevation as z-axis; Apple HIG depth conveys hierarchy). De schaal hier gebruikt een verdubbelings-progressie (2×) voor y-offset en blur — dit matcht hoe licht in de fysieke wereld afvalt en zorgt dat elke stap perceptueel duidelijk groter is dan z'n voorganger zonder dat tussenstappen nodig zijn.

Elke shadow is opgebouwd uit twee lagen: een key shadow (scherp, directioneel, simuleert een primary light source) en een ambient shadow (zacht, diffuus, simuleert reflected light). De combinatie geeft realisme zonder de "stamp"-look van een enkele drop-shadow met grote blur.

Gebruik

example.scss
@use "@ftp/style-library/scss/mixins/levitation" as *;

.my-card {
  @include levitate("s");
}

.my-modal {
  @include levitate("l");
}

Shadow levels — preview + rationale

  1. Hover states, subtle depth

    Extra Small xs

    example.scss
    @include levitate("xs");
    Use for
    Hover-states op resting cards/chips; subtle affordance dat een element interactief is zonder de visuele hiërarchie te verstoren.
    Avoid
    Niet op resting cards — xs is een hover-signaal; gebruik s als default-elevatie.
    Z-index pairing
    z-index: 1 — same plane as the resting card it elevates.
  2. Cards, buttons

    Small s

    example.scss
    @include levitate("s");
    Use for
    Resting elevation voor cards, raised buttons, en panels die zich onderscheiden van de canvas zonder te zweven.
    Avoid
    Niet op een full-bleed page-sectie (geen rechthoekige rand) — shadow op een onbegrensde achtergrond werkt niet.
    Z-index pairing
    z-index: 1 — resting layer above the canvas.
  3. Dropdowns, popovers

    Medium m

    example.scss
    @include levitate("m");
    Use for
    Floating UI dat boven page-content opent: dropdowns, popovers, comboboxes, tooltips met body-content.
    Avoid
    Niet op een resting card — m suggereert "ik zweef tijdelijk boven de pagina", wat verwarring geeft als de card daar permanent staat.
    Z-index pairing
    z-index: 1000 — popover layer.
  4. Modals, dialogs

    Large l

    example.scss
    @include levitate("l");
    Use for
    Modal dialogs, confirm popups, en drawers die de pagina-flow onderbreken en focus claimen.
    Avoid
    Niet op een button of card — l-elevatie zonder backdrop voelt los van de pagina en breekt de material-metafoor.
    Z-index pairing
    z-index: 9000 — modal layer (above page chrome).
  5. Toasts, high elevation

    Extra Large xl

    example.scss
    @include levitate("xl");
    Use for
    Toasts en notification banners die buiten de page-flow zweven; de hoogste visueel-prominente laag.
    Avoid
    Niet op iets dat onderdeel is van de page-flow — xl trekt focus weg van de hoofdcontent.
    Z-index pairing
    z-index: 9999 — top-most notification layer.

Accessibility

Shadow is decoratief. Visuele hiërarchie mag nooit afhankelijk zijn van shadow alleen — gebruikers met low-contrast displays, high-contrast OS-modes, of beperkt zicht missen subtiele drop-shadows. Analoog aan WCAG 1.4.1 Use of Color moet "iets staat bovenop iets anders" altijd door een tweede signaal versterkt worden: een border, een grotere afstand, een size-shift, of een expliciete state.

In high-contrast themes wordt de shadow-intensiteit gereduceerd of vervangen door een border — zie de HC Solar Light / HC Solar Dark themes voor de aanpassing.