* Align Oo avatar eye spacing with evoo-logo overlap ratio Derive small-eye placement from evoo-logo.svg center spacing (~0.94 of r_big + r_small) for the shared rig, EvooMascot brand lock, and face crops. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Format brand-lock spacing test for Biome Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Align mobile Expo packages for install --check in CI Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * ci: retrigger after flaky chart-links E2E Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
83 lines
3.3 KiB
TypeScript
83 lines
3.3 KiB
TypeScript
import {
|
|
OO_EYE_ASYMMETRY_MIN_RATIO,
|
|
OO_EYE_CENTER_SPACING_RATIO,
|
|
ooEyeCentersFromLogoRatio,
|
|
} from "@rakazo/core";
|
|
|
|
/**
|
|
* evOo brand lock — non-negotiable (Ingo).
|
|
*
|
|
* Oo trademark = asymmetric Kulleraugen + size difference.
|
|
*
|
|
* All mascot surfaces (EvooMascot, BotAvatar, Wordmark) MUST keep:
|
|
* 1. Consistent size asymmetry between the two eyes (big O vs small o).
|
|
* 2. Kulleraugen — big, round, glossy googly/cute sclera + pupils.
|
|
* 3. Eye center spacing matched to `evoo-logo.svg` (close / slight overlap).
|
|
*
|
|
* Personality (mouth, hands, accessories, poses) builds ON TOP of this signature.
|
|
* Never symmetrize the eyes. Never use Grok-style emoji faces. Never equal eye radii.
|
|
*/
|
|
|
|
/** Canonical trademark string — cite in reviews and design docs. */
|
|
export const EVOO_OO_TRADEMARK = "Oo trademark = asymmetric Kulleraugen + size difference" as const;
|
|
|
|
/** Big eye (capital O) — outer sclera radius in mascot viewBox units. */
|
|
export const EVOO_EYE_BIG_R = 30;
|
|
|
|
/** Small eye (lowercase o) — ~φ⁻¹ of big eye; trademark size gap. */
|
|
export const EVOO_EYE_SMALL_R = 18.54;
|
|
|
|
/** Big sclera anchor in the mascot viewBox (capital O). */
|
|
export const EVOO_EYE_BIG_CX = 44;
|
|
export const EVOO_EYE_BIG_CY = 54;
|
|
|
|
const _mascotSmallCenter = ooEyeCentersFromLogoRatio(
|
|
{ cx: EVOO_EYE_BIG_CX, cy: EVOO_EYE_BIG_CY, r: EVOO_EYE_BIG_R },
|
|
EVOO_EYE_SMALL_R,
|
|
);
|
|
|
|
/** Small sclera anchor derived from the logo spacing ratio. */
|
|
export const EVOO_EYE_SMALL_CX = _mascotSmallCenter.cx;
|
|
export const EVOO_EYE_SMALL_CY = _mascotSmallCenter.cy;
|
|
|
|
/** Logo-matched center distance ÷ sum of sclera radii (re-export for docs/tests). */
|
|
export const EVOO_EYE_CENTER_SPACING_RATIO = OO_EYE_CENTER_SPACING_RATIO;
|
|
|
|
/** Pupil radii scale with sclera; golden-ratio proportion preserved. */
|
|
export const EVOO_PUPIL_BIG_R = 14.2;
|
|
export const EVOO_PUPIL_SMALL_R = EVOO_PUPIL_BIG_R * 0.618034;
|
|
|
|
/** Pupil anchors track sclera; offsets unchanged from the original mascot art. */
|
|
export const EVOO_PUPIL_BIG_CX = EVOO_EYE_BIG_CX + 4;
|
|
export const EVOO_PUPIL_BIG_CY = EVOO_EYE_BIG_CY + 3;
|
|
export const EVOO_PUPIL_SMALL_CX = EVOO_EYE_SMALL_CX + 0.37;
|
|
export const EVOO_PUPIL_SMALL_CY = EVOO_EYE_SMALL_CY + 0.94;
|
|
|
|
/** Minimum big÷small ratio — catches accidental symmetrization in tests/CI. */
|
|
export const EVOO_EYE_ASYMMETRY_MIN_RATIO = OO_EYE_ASYMMETRY_MIN_RATIO;
|
|
|
|
export const EVOO_BRAND_LOCK_RULES = [
|
|
"Two eyes only: one big O, one small o — never equal radii.",
|
|
"Kulleraugen: round white sclera, dark glossy pupil, primary + secondary catchlights.",
|
|
"Eye spacing follows evoo-logo.svg — centers closer than r_big + r_small (slight overlap).",
|
|
"Poses may change gaze, blink, squint (eyeOpen), brows, mouth, hands, accessories — not eye size parity.",
|
|
"No Grok-bot emoji face replacement; no symmetric sticker eyes.",
|
|
] as const;
|
|
|
|
/** Dev/test guard — throws if constants violate the trademark asymmetry. */
|
|
export function assertEvooEyeBrandLock(bigR = EVOO_EYE_BIG_R, smallR = EVOO_EYE_SMALL_R): void {
|
|
if (!(bigR > smallR)) {
|
|
throw new Error(
|
|
`${EVOO_OO_TRADEMARK}: big eye radius must exceed small (${bigR} vs ${smallR})`,
|
|
);
|
|
}
|
|
const ratio = bigR / smallR;
|
|
if (ratio < EVOO_EYE_ASYMMETRY_MIN_RATIO) {
|
|
throw new Error(
|
|
`${EVOO_OO_TRADEMARK}: asymmetry ratio ${ratio.toFixed(3)} below minimum ${EVOO_EYE_ASYMMETRY_MIN_RATIO}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
assertEvooEyeBrandLock();
|