{"version":3,"file":"NavMenuInk.BBr9RT9V.mjs","names":["React.useRef"],"sources":["https:/framerusercontent.com/modules/i55QtKwYGeuZQFiIWUpb/iGrJMKthS0y32VLhrxV6/NavMenuInk.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import*as React from\"react\";// Menu ink: every entry sits at full ink, and hovering one entry is what\n// pushes its siblings back.\n//\n// The old scheme was the Conduct one — items muted at rest, the hovered\n// item restored to full ink. It reads as \"the menu is disabled until you\n// touch it\": opening Product showed four grey rows. Leo asked for the\n// inverse, which is also the stronger contrast: black at rest, and on\n// hover the pointed-at entry *stays* black while the rest step back.\n//\n// That is sibling state, and a Framer variant cannot express it — a\n// component knows it is hovered, never that a neighbour is. Doing it on\n// the canvas would need one variant per hovered item (10 on desktop, 13\n// more in the drawer). So it is CSS: `:has()` on the group, and the two\n// overrides below exist only to mark which element is the group and\n// which are its items. Nothing here reads or writes layout.\n//\n// withNavInkGroup -> a list that owns a set of entries (each dropdown\n//                    panel, each drawer level).\n// withNavInkBar   -> the bar's own link row. Same marking job, opposite\n//                    rule: siblings never step back, the hovered link\n//                    lifts. See \"The bar reads the other way\" below.\n// withNavInkItem  -> one entry inside such a list. On the Nav Menu Item\n//                    component root it covers every instance at once.\n//\n// All three stamp their own rendered element and assume nothing about the\n// structure in between, so columns, wrappers and future re-nesting are\n// all fine.\n//\n// A second scheme lives at the bottom of the file for the CMS row lists —\n// \"Other industries\" and anything built like it. Same idea, three more\n// marks, and one rule the nav has no use for: the row's line-and-dot mark\n// lengthens the way the menu's does.\n//\n// withInkList -> a list of rows.\n// withInkRow  -> one row inside it.\n// withInkMark -> the line-and-dot at the end of such a row.\n//\n// None of it runs on a phone. Every rule that reads `:hover` sits behind\n// `(hover: hover) and (pointer: fine)`, because a finger has no hover to\n// express: iOS fires the hover state on tap and then leaves it there, so\n// tapping Industries in the drawer greyed out every row beside it and the\n// grey stayed until something else was tapped. See \"No hover on a finger\"\n// below.\nconst STYLE_ID=\"lupitor-nav-menu-ink\";const GROUP_ATTR=\"data-nav-ink-group\";const BAR_ATTR=\"data-nav-ink-bar\";const ITEM_ATTR=\"data-nav-ink-item\";const LIST_ATTR=\"data-ink-list\";const ROW_ATTR=\"data-ink-row\";const MARK_ATTR=\"data-ink-mark\";// 0.34 lands black on white at roughly Text/Tertiary, which is the grey\n// the menu used to rest at — the same step, now only while hovering.\nconst DIM=.34;// The bar reads the other way (2026-08-16, Leo: hovering Product should\n// not grey out Industries and Company). Three top-level tabs are the\n// page's own signposts and they all stay at full ink; the one under the\n// cursor is the one that changes, lifting a step off black. On the frost\n// bar that reads as \"brighter\", which is what was asked for; on the\n// transparent-over-hero bar the same step softens the white instead.\n// One number cannot do both, and the light bar is the one being pointed\n// at in every review.\nconst LIFT=.58;const EASE=\"0.44,0,0.56,1\";const DURATION=\"0.22s\";// The row mark grows by the same +6 the menu's own marks use — the Circle\n// goes 15 → 21, the overview arrow 27 → 33, the industry row 29 → 35. The\n// tail is pinned left and right inside that box and the dot rides the\n// right edge, so widening the box is the whole animation.\nconst GROW=6;// …and the row takes that 6px out of its own right margin. Two things\n// decide which side:\n//\n// It has to come out of a margin at all because the mark ends a stack\n// whose name and description are `fr` — a wider mark would squeeze them,\n// and a description one word from wrapping would reflow under the\n// cursor. A negative margin keeps the row's outer footprint at exactly\n// what it was.\n//\n// And it has to be the *right* margin so the mark grows rightward: the\n// left edge stays put, the tail lengthens and the dot travels out into\n// the row's padding (Leo, 2026-08-21 — off the left it read as the line\n// \"growing back\"). Off the left margin the arithmetic is identical and\n// the animation is backwards, which is how it shipped for an hour.\n// No hover on a finger, and no grey box under it either.\n//\n// `HOVER` is the whole hover scheme's gate and `TOUCH` is its exact\n// complement, so a device gets one of the two and never both. Everything\n// that reads `:hover` — the menu dim, the bar lift, the mark growth —\n// lives inside `HOVER`. `TOUCH` pins the nav's ink at full instead, which\n// is the value every entry rests at anyway.\n//\n// A finger does not hover: iOS resolves `:hover` on tap and holds it\n// until you tap elsewhere, so the dim was arriving on the tap that opened\n// a page and staying behind (Leo, 2026-08-21 — the drawer, the industry\n// rows and the company hero links all did it). Tapping is still allowed\n// to do things; it is only the pointing-at that has no meaning here.\n//\n// `TOUCH` deliberately says nothing about `[ROW_ATTR]`: a CMS row list\n// carries a staggered appear effect and pinning its opacity would eat the\n// fade, exactly as the note under the row rules explains.\nconst HOVER=\"(hover: hover) and (pointer: fine)\";const TOUCH=\"(hover: none), (pointer: coarse)\";// And the grey box: iOS and Android paint `-webkit-tap-highlight-color`\n// over any anchor a finger lands on, sized to the whole cell — a chunky\n// grey slab over a drawer row, which is what a tap on Banking looked\n// like. The property inherits, so setting it on the three container\n// marks covers every link inside them, `Drawer L1`'s two buttons\n// included. `user-select` is held to the **entries** rather than the\n// containers, because a press held a moment longer selected a menu label\n// instead of following the link — and a group can have a contact card\n// somewhere beneath it, whose form must stay selectable. The row lists\n// are content and keep their text either way. `/product`'s chapter tabs\n// solved the same thing node-by-node before this file existed; if the\n// box turns up somewhere neither covers, it is this one line.\nconst CSS=`\n[${ITEM_ATTR}] {\n    transition: opacity ${DURATION} cubic-bezier(${EASE});\n}\n[${ROW_ATTR}] {\n    transition: opacity ${DURATION} cubic-bezier(${EASE});\n}\n[${MARK_ATTR}] {\n    transition:\n        width ${DURATION} cubic-bezier(${EASE}),\n        margin-right ${DURATION} cubic-bezier(${EASE});\n}\n[${GROUP_ATTR}],\n[${BAR_ATTR}],\n[${LIST_ATTR}] {\n    -webkit-tap-highlight-color: transparent;\n}\n[${GROUP_ATTR}] [${ITEM_ATTR}],\n[${BAR_ATTR}] [${ITEM_ATTR}] {\n    -webkit-user-select: none;\n    user-select: none;\n}\n@media ${HOVER} {\n    [${GROUP_ATTR}]:has([${ITEM_ATTR}]:hover) [${ITEM_ATTR}]:not(:hover) {\n        opacity: ${DIM} !important;\n    }\n    [${GROUP_ATTR}] [${ITEM_ATTR}]:hover,\n    [${GROUP_ATTR}]:not(:has([${ITEM_ATTR}]:hover)) [${ITEM_ATTR}] {\n        opacity: 1 !important;\n    }\n    [${BAR_ATTR}] [${ITEM_ATTR}] {\n        opacity: 1 !important;\n    }\n    [${BAR_ATTR}] [${ITEM_ATTR}]:hover {\n        opacity: ${LIFT} !important;\n    }\n    [${LIST_ATTR}]:has([${ROW_ATTR}]:hover) [${ROW_ATTR}]:not(:hover) {\n        opacity: ${DIM} !important;\n    }\n    [${ROW_ATTR}]:hover [${MARK_ATTR}] {\n        width: calc(var(--ink-mark-w, 29px) + ${GROW}px) !important;\n        margin-right: -${GROW}px !important;\n    }\n}\n@media ${TOUCH} {\n    [${GROUP_ATTR}] [${ITEM_ATTR}],\n    [${BAR_ATTR}] [${ITEM_ATTR}] {\n        opacity: 1 !important;\n    }\n}\n`;// !important: Framer writes hover effects as inline styles via motion,\n// and an inline opacity would otherwise win over this rule.\n//\n// The second rule pins the other two states — hovered, and at rest with\n// no hover anywhere in the group — to full ink. Without it, only the\n// dimmed state was CSS-owned, and a variant switch interrupting a hover\n// cycle could strand a motion-written inline opacity on an entry: after\n// opening a menu and leaving the nav, a bar link sat at the dim grey\n// until the next hover (Leo: Industries \"stays grayed out\" on scroll).\n// With every state pinned, no stray inline opacity can ever show.\n//\n// The row rules deliberately do NOT pin the other two states, and that is\n// the one place the two schemes differ. A CMS row list carries a\n// staggered appear effect, so motion writes an inline opacity 0 → 1 on\n// every row as it enters; `opacity: 1 !important` at rest would win over\n// that and the rows would arrive with the rise but no fade. Dimming is\n// the only state that needs to beat an inline value — un-hovering falls\n// back to motion's own settled `opacity: 1`, which is exactly the value\n// wanted. Nothing here switches variants, so there is no hover cycle for\n// a variant change to interrupt and no stuck ink to guard against.\nfunction useInkStyles(){React.useEffect(()=>{if(typeof document===\"undefined\")return;if(document.getElementById(STYLE_ID))return;const style=document.createElement(\"style\");style.id=STYLE_ID;style.textContent=CSS;document.head.appendChild(style);},[]);}// The wrapper is display:contents, so it has no box and no layout effect;\n// the element we want is its first child, the node's own rendered root.\nfunction useStamp(attribute){const ref=React.useRef(null);React.useEffect(()=>{const el=ref.current?.firstElementChild;if(el&&!el.hasAttribute(attribute))el.setAttribute(attribute,\"\");});return ref;}// The mark stamps its own width alongside the attribute, so the hover\n// rule can say \"+6\" rather than naming a number that only fits one mark.\n// Measured once and never again: hovering does not re-render, but an\n// appear effect can, and re-measuring mid-transition would feed the\n// growing width back into the calc that is growing it.\nfunction useMarkStamp(){const ref=React.useRef(null);React.useEffect(()=>{const el=ref.current?.firstElementChild;if(!el)return;if(!el.hasAttribute(MARK_ATTR))el.setAttribute(MARK_ATTR,\"\");if(el.style.getPropertyValue(\"--ink-mark-w\"))return;const width=el.getBoundingClientRect().width;if(width>0)el.style.setProperty(\"--ink-mark-w\",`${width}px`);});return ref;}// Every export has to be written out as a `(Component) => Component`\n// function: Framer decides what is an override by reading that\n// signature, and a const assigned from a factory is not recognised.\nfunction marked(Component,attribute){return /*#__PURE__*/React.forwardRef((props,ref)=>{useInkStyles();const wrapperRef=useStamp(attribute);return /*#__PURE__*/_jsx(\"div\",{ref:wrapperRef,style:{display:\"contents\"},children:/*#__PURE__*/_jsx(Component,{ref:ref,...props})});});}export function withNavInkGroup(Component){return marked(Component,GROUP_ATTR);}export function withNavInkBar(Component){return marked(Component,BAR_ATTR);}export function withNavInkItem(Component){return marked(Component,ITEM_ATTR);}export function withInkList(Component){return marked(Component,LIST_ATTR);}export function withInkRow(Component){return marked(Component,ROW_ATTR);}export function withInkMark(Component){return /*#__PURE__*/React.forwardRef((props,ref)=>{useInkStyles();const wrapperRef=useMarkStamp();return /*#__PURE__*/_jsx(\"div\",{ref:wrapperRef,style:{display:\"contents\"},children:/*#__PURE__*/_jsx(Component,{ref:ref,...props})});});}\nexport const __FramerMetadata__ = {\"exports\":{\"withInkRow\":{\"type\":\"reactHoc\",\"name\":\"withInkRow\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withInkMark\":{\"type\":\"reactHoc\",\"name\":\"withInkMark\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withNavInkBar\":{\"type\":\"reactHoc\",\"name\":\"withNavInkBar\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withNavInkGroup\":{\"type\":\"reactHoc\",\"name\":\"withNavInkGroup\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withNavInkItem\":{\"type\":\"reactHoc\",\"name\":\"withNavInkItem\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withInkList\":{\"type\":\"reactHoc\",\"name\":\"withInkList\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./NavMenuInk.map"],"mappings":"gIA0KA,SAAS,GAAc,CAAC,MAAoB,CAAyC,GAArC,OAAO,SAAW,KAAsB,SAAS,eAAe,CAAQ,EAAE,OAAO,IAAM,EAAM,SAAS,cAAc,OAAO,EAAE,EAAM,GAAG,EAAS,EAAM,YAAY,EAAI,SAAS,KAAK,YAAY,CAAK,CAAE,EAAE,CAAC,CAAC,CAAE,CAE5P,SAAS,EAAS,EAAU,CAAC,IAAM,EAAIA,EAAa,IAAI,EAAmI,OAAjI,MAAoB,CAAC,IAAM,EAAG,EAAI,SAAS,kBAAqB,GAAI,CAAC,EAAG,aAAa,CAAS,GAAE,EAAG,aAAa,EAAU,EAAE,CAAE,CAAC,EAAS,CAAI,CAKtM,SAAS,GAAc,CAAC,IAAM,EAAIA,EAAa,IAAI,EAA2S,OAAzS,MAAoB,CAAC,IAAM,EAAG,EAAI,SAAS,kBAA6F,GAAxE,CAAC,IAAc,EAAG,aAAa,CAAS,GAAE,EAAG,aAAa,EAAU,EAAE,EAAK,EAAG,MAAM,iBAAiB,cAAc,GAAE,OAAO,IAAM,EAAM,EAAG,sBAAsB,CAAC,CAAC,MAAS,EAAM,GAAE,EAAG,MAAM,YAAY,eAAe,GAAG,EAAM,GAAG,CAAE,CAAC,EAAS,CAAI,CAGzW,SAAS,EAAO,EAAU,EAAU,CAAC,OAAoB,GAAkB,EAAM,KAAO,EAAa,EAA2D,EAAK,MAAM,CAAC,IAApD,EAAS,CAAwD,EAAE,MAAM,CAAC,QAAQ,UAAU,EAAE,SAAsB,EAAK,EAAU,CAAK,MAAI,GAAG,CAAK,CAAC,CAAC,CAAC,EAAG,CAAE,CAAC,SAAgB,EAAgB,EAAU,CAAC,OAAO,EAAO,EAAU,CAAU,CAAE,CAAC,SAAgB,EAAc,EAAU,CAAC,OAAO,EAAO,EAAU,CAAQ,CAAE,CAAC,SAAgB,EAAe,EAAU,CAAC,OAAO,EAAO,EAAU,CAAS,CAAE,CAAC,SAAgB,EAAY,EAAU,CAAC,OAAO,EAAO,EAAU,CAAS,CAAE,CAAC,SAAgB,EAAW,EAAU,CAAC,OAAO,EAAO,EAAU,CAAQ,CAAE,CAAC,SAAgB,EAAY,EAAU,CAAC,OAAoB,GAAkB,EAAM,KAAO,EAAa,EAAsD,EAAK,MAAM,CAAC,IAA/C,EAA4D,EAAE,MAAM,CAAC,QAAQ,UAAU,EAAE,SAAsB,EAAK,EAAU,CAAK,MAAI,GAAG,CAAK,CAAC,CAAC,CAAC,EAAG,CAAE,2CApL13B,IAA4B,EA2ChE,EAAS,uBAA6B,EAAW,qBAA2B,EAAS,mBAAyB,EAAU,oBAA0B,EAAU,gBAAsB,EAAS,eAAqB,EAAU,gBAE1N,EAAI,IAQJ,EAAK,IAAU,EAAK,gBAAsB,EAAS,QAInD,EAAK,EA2CL,EAAI;GACP,EAAU;0BACa,EAAS,gBAAgB,EAAK;;GAErD,EAAS;0BACc,EAAS,gBAAgB,EAAK;;GAErD,EAAU;;gBAEG,EAAS,gBAAgB,EAAK;uBACvB,EAAS,gBAAgB,EAAK;;GAElD,EAAW;GACX,EAAS;GACT,EAAU;;;GAGV,EAAW,KAAK,EAAU;GAC1B,EAAS,KAAK,EAAU;;;;;OAKpB,EAAW,SAAS,EAAU,YAAY,EAAU;mBACxC,EAAI;;OAEhB,EAAW,KAAK,EAAU;OAC1B,EAAW,cAAc,EAAU,aAAa,EAAU;;;OAG1D,EAAS,KAAK,EAAU;;;OAGxB,EAAS,KAAK,EAAU;mBACZ,EAAK;;OAEjB,EAAU,SAAS,EAAS,YAAY,EAAS;mBACrC,EAAI;;OAEhB,EAAS,WAAW,EAAU;gDACW,EAAK;yBAC5B,EAAK;;;;OAIvB,EAAW,KAAK,EAAU;OAC1B,EAAS,KAAK,EAAU"}