This is page 6 of 27. Use http://codebase.md/cloudflare/mcp-server-cloudflare?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .changeset │ ├── config.json │ └── README.md ├── .dockerignore ├── .editorconfig ├── .eslintrc.cjs ├── .github │ ├── actions │ │ └── setup │ │ └── action.yml │ ├── ISSUE_TEMPLATE │ │ └── bug_report.md │ └── workflows │ ├── branches.yml │ ├── main.yml │ └── release.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc.cjs ├── .syncpackrc.cjs ├── .vscode │ ├── extensions.json │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── apps │ ├── ai-gateway │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── ai-gateway.app.ts │ │ │ ├── ai-gateway.context.ts │ │ │ ├── tools │ │ │ │ └── ai-gateway.tools.ts │ │ │ └── types.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── auditlogs │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── auditlogs.app.ts │ │ │ ├── auditlogs.context.ts │ │ │ └── tools │ │ │ └── auditlogs.tools.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── autorag │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── autorag.app.ts │ │ │ ├── autorag.context.ts │ │ │ ├── tools │ │ │ │ └── autorag.tools.ts │ │ │ └── types.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── browser-rendering │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── browser.app.ts │ │ │ ├── browser.context.ts │ │ │ └── tools │ │ │ └── browser.tools.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── cloudflare-one-casb │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── cf1-casb.app.ts │ │ │ ├── cf1-casb.context.ts │ │ │ └── tools │ │ │ └── integrations.tools.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── demo-day │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── frontend │ │ │ ├── index.html │ │ │ ├── public │ │ │ │ ├── anthropic.svg │ │ │ │ ├── asana.svg │ │ │ │ ├── atlassian.svg │ │ │ │ ├── canva.svg │ │ │ │ ├── cloudflare_logo.svg │ │ │ │ ├── cloudflare.svg │ │ │ │ ├── dina.jpg │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── favicon.png │ │ │ │ ├── intercom.svg │ │ │ │ ├── linear.svg │ │ │ │ ├── matt.jpg │ │ │ │ ├── mcp_demo_day.svg │ │ │ │ ├── mcpog.png │ │ │ │ ├── more.svg │ │ │ │ ├── paypal.svg │ │ │ │ ├── pete.jpeg │ │ │ │ ├── sentry.svg │ │ │ │ ├── special_guest.png │ │ │ │ ├── square.svg │ │ │ │ ├── stripe.svg │ │ │ │ ├── sunil.jpg │ │ │ │ └── webflow.svg │ │ │ ├── script.js │ │ │ └── styles.css │ │ ├── package.json │ │ ├── src │ │ │ └── demo-day.app.ts │ │ ├── tsconfig.json │ │ ├── worker-configuration.d.ts │ │ └── wrangler.json │ ├── dex-analysis │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── dex-analysis.app.ts │ │ │ ├── dex-analysis.context.ts │ │ │ ├── tools │ │ │ │ └── dex-analysis.tools.ts │ │ │ └── warp_diag_reader.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── dns-analytics │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── dns-analytics.app.ts │ │ │ ├── dns-analytics.context.ts │ │ │ └── tools │ │ │ └── dex-analytics.tools.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── docs-autorag │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── docs-autorag.app.ts │ │ │ ├── docs-autorag.context.ts │ │ │ └── tools │ │ │ └── docs-autorag.tools.ts │ │ ├── tsconfig.json │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── docs-vectorize │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── docs-vectorize.app.ts │ │ │ └── docs-vectorize.context.ts │ │ ├── tsconfig.json │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── graphql │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── graphql.app.ts │ │ │ ├── graphql.context.ts │ │ │ └── tools │ │ │ └── graphql.tools.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── logpush │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── logpush.app.ts │ │ │ ├── logpush.context.ts │ │ │ └── tools │ │ │ └── logpush.tools.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── radar │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── radar.app.ts │ │ │ ├── radar.context.ts │ │ │ ├── tools │ │ │ │ ├── radar.tools.ts │ │ │ │ └── url-scanner.tools.ts │ │ │ ├── types │ │ │ │ ├── radar.ts │ │ │ │ └── url-scanner.ts │ │ │ └── utils.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── sandbox-container │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── container │ │ │ ├── fileUtils.spec.ts │ │ │ ├── fileUtils.ts │ │ │ ├── sandbox.container.app.ts │ │ │ └── tsconfig.json │ │ ├── CONTRIBUTING.md │ │ ├── Dockerfile │ │ ├── evals │ │ │ ├── exec.eval.ts │ │ │ ├── files.eval.ts │ │ │ ├── initialize.eval.ts │ │ │ └── utils.ts │ │ ├── package.json │ │ ├── README.md │ │ ├── server │ │ │ ├── containerHelpers.ts │ │ │ ├── containerManager.ts │ │ │ ├── containerMcp.ts │ │ │ ├── metrics.ts │ │ │ ├── prompts.ts │ │ │ ├── sandbox.server.app.ts │ │ │ ├── sandbox.server.context.ts │ │ │ ├── userContainer.ts │ │ │ ├── utils.spec.ts │ │ │ └── utils.ts │ │ ├── shared │ │ │ ├── consts.ts │ │ │ └── schema.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.evals.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── workers-bindings │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── evals │ │ │ ├── accounts.eval.ts │ │ │ ├── hyperdrive.eval.ts │ │ │ ├── kv_namespaces.eval.ts │ │ │ ├── types.d.ts │ │ │ └── utils.ts │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── bindings.app.ts │ │ │ └── bindings.context.ts │ │ ├── tsconfig.json │ │ ├── vitest.config.evals.ts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ ├── workers-builds │ │ ├── .dev.vars.example │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── tools │ │ │ │ └── workers-builds.tools.ts │ │ │ ├── workers-builds.app.ts │ │ │ └── workers-builds.context.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vite.config.mts │ │ ├── vitest.config.ts │ │ ├── worker-configuration.d.ts │ │ └── wrangler.jsonc │ └── workers-observability │ ├── .dev.vars.example │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── CONTRIBUTING.md │ ├── package.json │ ├── README.md │ ├── src │ │ ├── tools │ │ │ └── workers-observability.tools.ts │ │ ├── workers-observability.app.ts │ │ └── workers-observability.context.ts │ ├── tsconfig.json │ ├── types.d.ts │ ├── vitest.config.ts │ ├── worker-configuration.d.ts │ └── wrangler.jsonc ├── CONTRIBUTING.md ├── implementation-guides │ ├── evals.md │ ├── tools.md │ └── type-validators.md ├── LICENSE ├── package.json ├── packages │ ├── eslint-config │ │ ├── CHANGELOG.md │ │ ├── default.cjs │ │ ├── package.json │ │ └── README.md │ ├── eval-tools │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src │ │ │ ├── runTask.ts │ │ │ ├── scorers.ts │ │ │ └── test-models.ts │ │ ├── tsconfig.json │ │ ├── worker-configuration.d.ts │ │ └── wrangler.json │ ├── mcp-common │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── api │ │ │ │ ├── account.api.ts │ │ │ │ ├── cf1-integration.api.ts │ │ │ │ ├── workers-builds.api.ts │ │ │ │ ├── workers-observability.api.ts │ │ │ │ ├── workers.api.ts │ │ │ │ └── zone.api.ts │ │ │ ├── api-handler.ts │ │ │ ├── api-token-mode.ts │ │ │ ├── cloudflare-api.ts │ │ │ ├── cloudflare-auth.ts │ │ │ ├── cloudflare-oauth-handler.ts │ │ │ ├── config.ts │ │ │ ├── constants.ts │ │ │ ├── durable-kv-store.ts │ │ │ ├── durable-objects │ │ │ │ └── user_details.do.ts │ │ │ ├── env.ts │ │ │ ├── format.spec.ts │ │ │ ├── format.ts │ │ │ ├── get-props.ts │ │ │ ├── mcp-error.ts │ │ │ ├── poll.ts │ │ │ ├── prompts │ │ │ │ └── docs-vectorize.prompts.ts │ │ │ ├── scopes.ts │ │ │ ├── sentry.ts │ │ │ ├── server.ts │ │ │ ├── tools │ │ │ │ ├── account.tools.ts │ │ │ │ ├── d1.tools.ts │ │ │ │ ├── docs-vectorize.tools.ts │ │ │ │ ├── hyperdrive.tools.ts │ │ │ │ ├── kv_namespace.tools.ts │ │ │ │ ├── r2_bucket.tools.ts │ │ │ │ ├── worker.tools.ts │ │ │ │ └── zone.tools.ts │ │ │ ├── types │ │ │ │ ├── cf1-integrations.types.ts │ │ │ │ ├── cloudflare-mcp-agent.types.ts │ │ │ │ ├── d1.types.ts │ │ │ │ ├── hyperdrive.types.ts │ │ │ │ ├── kv_namespace.types.ts │ │ │ │ ├── r2_bucket.types.ts │ │ │ │ ├── shared.types.ts │ │ │ │ ├── tools.types.ts │ │ │ │ ├── workers-builds.types.ts │ │ │ │ ├── workers-logs.types.ts │ │ │ │ └── workers.types.ts │ │ │ ├── utils.spec.ts │ │ │ ├── utils.ts │ │ │ └── v4-api.ts │ │ ├── tests │ │ │ └── utils │ │ │ └── cloudflare-mock.ts │ │ ├── tsconfig.json │ │ ├── types.d.ts │ │ ├── vitest.config.ts │ │ └── worker-configuration.d.ts │ ├── mcp-observability │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src │ │ │ ├── analytics-engine.ts │ │ │ ├── index.ts │ │ │ └── metrics.ts │ │ ├── tsconfig.json │ │ └── worker-configuration.d.ts │ ├── tools │ │ ├── .eslintrc.cjs │ │ ├── bin │ │ │ ├── run-changeset-new │ │ │ ├── run-eslint-workers │ │ │ ├── run-fix-deps │ │ │ ├── run-tsc │ │ │ ├── run-turbo │ │ │ ├── run-vitest │ │ │ ├── run-vitest-ci │ │ │ ├── run-wrangler-deploy │ │ │ ├── run-wrangler-types │ │ │ └── runx │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── bin │ │ │ │ └── runx.ts │ │ │ ├── changesets.spec.ts │ │ │ ├── changesets.ts │ │ │ ├── cmd │ │ │ │ └── deploy-published-packages.ts │ │ │ ├── proc.ts │ │ │ ├── test │ │ │ │ ├── fixtures │ │ │ │ │ └── changesets │ │ │ │ │ ├── empty │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── invalid-json │ │ │ │ │ │ └── published-packages.json │ │ │ │ │ ├── invalid-schema │ │ │ │ │ │ └── published-packages.json │ │ │ │ │ └── valid │ │ │ │ │ └── published-packages.json │ │ │ │ └── setup.ts │ │ │ └── tsconfig.ts │ │ ├── tsconfig.json │ │ └── vitest.config.ts │ └── typescript-config │ ├── CHANGELOG.md │ ├── package.json │ ├── tools.json │ ├── workers-lib.json │ └── workers.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── README.md ├── server.json ├── tsconfig.json ├── turbo.json └── vitest.workspace.ts ``` # Files -------------------------------------------------------------------------------- /apps/demo-day/frontend/index.html: -------------------------------------------------------------------------------- ```html 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8" /> 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 | 7 | <!-- Primary Meta Tags --> 8 | <title>MCP Demo Day - Preview the Future of Agentic Software</title> 9 | <meta 10 | name="description" 11 | content="Join us on May 1st, 2025 to witness groundbreaking demos from companies like Atlassian, Linear, Stripe, and more. Experience the next evolution of AI-powered software." 12 | /> 13 | 14 | <!-- Open Graph / Facebook --> 15 | <meta property="og:type" content="website" /> 16 | <meta property="og:url" content="https://demo-day.mcp.cloudflare.com/" /> 17 | <meta property="og:title" content="MCP Demo Day - Preview the Future of Agentic Software" /> 18 | <meta 19 | property="og:description" 20 | content="Join us on May 1st, 2025 to witness groundbreaking demos from companies like Atlassian, Linear, Stripe, and more. Experience the next evolution of AI-powered software." 21 | /> 22 | <meta property="og:image" content="https://demo-day.mcp.cloudflare.com/public/mcpog.png" /> 23 | 24 | <!-- Twitter --> 25 | <meta name="twitter:card" content="summary_large_image" /> 26 | <meta name="twitter:title" content="MCP Demo Day - Preview the Future of Agentic Software" /> 27 | <meta 28 | name="twitter:description" 29 | content="Join us on May 1st, 2025 to witness groundbreaking demos from companies like Atlassian, Linear, Stripe, and more. Experience the next evolution of AI-powered software." 30 | /> 31 | <meta name="twitter:image" content="https://demo-day.mcp.cloudflare.com/public/mcpog.png" /> 32 | <link rel="icon" type="image/png" href="public/favicon.ico" /> 33 | <link rel="icon" type="image/png" sizes="32x32" href="public/favicon-32x32.png" /> 34 | <link rel="icon" type="image/png" sizes="16x16" href="public/favicon-16x16.png" /> 35 | 36 | <link rel="stylesheet" href="styles.css" /> 37 | <link rel="preconnect" href="https://fonts.googleapis.com" /> 38 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> 39 | <link 40 | href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" 41 | rel="stylesheet" 42 | /> 43 | </head> 44 | 45 | <body> 46 | <div class="page-wrapper"> 47 | <main class="container"> 48 | <section class="left-panel"> 49 | <div class="header"> 50 | <div class="logo"> 51 | <img src="public/mcp_demo_day.svg" alt="MCP Logo" class="cloud-logo" /> 52 | </div> 53 | <div class="date-time" onclick="document.getElementById('calendarDialog').showModal()"> 54 | <button class="calendar-trigger" aria-label="Add to calendar"> 55 | <svg width="20" height="20" viewBox="0 0 20 20" fill="none"> 56 | <path 57 | d="M6 5V3M14 5V3M5 9H15M5 7.5H15M4.2 17H15.8C16.4627 17 17 16.4627 17 15.8V5.2C17 4.53726 16.4627 4 15.8 4H4.2C3.53726 4 3 4.53726 3 5.2V15.8C3 16.4627 3.53726 17 4.2 17Z" 58 | stroke="currentColor" 59 | stroke-width="1.5" 60 | stroke-linecap="round" 61 | stroke-linejoin="round" 62 | /> 63 | </svg> 64 | </button> 65 | <div class="date-time-text"> 66 | <h2>MAY 1, 2025</h2> 67 | <h3>ONLINE 10:00 AM PT / 1 PM ET</h3> 68 | </div> 69 | </div> 70 | </div> 71 | 72 | <div class="content"> 73 | <h1>Preview the Future<br />of Agentic Software</h1> 74 | 75 | <p class="description"> 76 | Come see how the world's most innovative platforms have connected agents to their 77 | services with MCP to build a new class of product experiences. 78 | </p> 79 | 80 | <div class="input-group"> 81 | <a class="notify-btn" href="https://www.youtube.com/watch?v=njBGqr-BU54"> 82 | Watch the stream 83 | <svg width="16" height="16" viewBox="0 0 16 16" fill="none"> 84 | <path 85 | d="M2.5 8H13.5M13.5 8L9 3.5M13.5 8L9 12.5" 86 | stroke="currentColor" 87 | stroke-width="1.5" 88 | stroke-linecap="round" 89 | stroke-linejoin="round" 90 | /> 91 | </svg> 92 | </a> 93 | <div class="success-message"> 94 | <div class="success-text"> 95 | <svg width="18" height="18" viewBox="0 0 18 18" fill="none"> 96 | <path 97 | d="M15 5L7 13L3 9" 98 | stroke="currentColor" 99 | stroke-width="2" 100 | stroke-linecap="round" 101 | stroke-linejoin="round" 102 | /> 103 | </svg> 104 | You're in! See you on May 1st 105 | </div> 106 | <div class="calendar-actions"> 107 | <button class="calendar-action" data-calendar-type="google"> 108 | <svg 109 | xmlns="http://www.w3.org/2000/svg" 110 | x="0px" 111 | y="0px" 112 | width="100" 113 | height="100" 114 | viewBox="0,0,256,256" 115 | style="fill: #ffffff" 116 | > 117 | <g 118 | fill="#ffffff" 119 | fill-rule="nonzero" 120 | stroke="none" 121 | stroke-width="1" 122 | stroke-linecap="butt" 123 | stroke-linejoin="miter" 124 | stroke-miterlimit="10" 125 | stroke-dasharray="" 126 | stroke-dashoffset="0" 127 | font-family="none" 128 | font-weight="none" 129 | font-size="none" 130 | text-anchor="none" 131 | style="mix-blend-mode: normal" 132 | > 133 | <g transform="scale(5.12,5.12)"> 134 | <path 135 | d="M25.99609,48c-12.68359,0 -23.00391,-10.31641 -23.00391,-23c0,-12.68359 10.32031,-23 23.00391,-23c5.74609,0 11.24609,2.12891 15.49219,5.99609l0.77344,0.70703l-7.58594,7.58594l-0.70312,-0.60156c-2.22656,-1.90625 -5.05859,-2.95703 -7.97656,-2.95703c-6.76562,0 -12.27344,5.50391 -12.27344,12.26953c0,6.76563 5.50781,12.26953 12.27344,12.26953c4.87891,0 8.73438,-2.49219 10.55078,-6.73828h-11.55078v-10.35547l22.55078,0.03125l0.16797,0.79297c1.17578,5.58203 0.23438,13.79297 -4.53125,19.66797c-3.94531,4.86328 -9.72656,7.33203 -17.1875,7.33203z" 136 | ></path> 137 | </g> 138 | </g> 139 | </svg> 140 | Google Calendar 141 | </button> 142 | <button class="calendar-action" data-calendar-type="outlook"> 143 | <svg 144 | xmlns="http://www.w3.org/2000/svg" 145 | x="0px" 146 | y="0px" 147 | width="100" 148 | height="100" 149 | viewBox="0,0,256,256" 150 | style="fill: #ffffff" 151 | > 152 | <g 153 | fill="#ffffff" 154 | fill-rule="nonzero" 155 | stroke="none" 156 | stroke-width="1" 157 | stroke-linecap="butt" 158 | stroke-linejoin="miter" 159 | stroke-miterlimit="10" 160 | stroke-dasharray="" 161 | stroke-dashoffset="0" 162 | font-family="none" 163 | font-weight="none" 164 | font-size="none" 165 | text-anchor="none" 166 | style="mix-blend-mode: normal" 167 | > 168 | <g transform="scale(5.12,5.12)"> 169 | <path 170 | d="M5,4c-0.552,0 -1,0.447 -1,1v19h20v-20zM26,4v20h20v-19c0,-0.553 -0.448,-1 -1,-1zM4,26v19c0,0.553 0.448,1 1,1h19v-20zM26,26v20h19c0.552,0 1,-0.447 1,-1v-19z" 171 | ></path> 172 | </g> 173 | </g> 174 | </svg> 175 | Outlook 176 | </button> 177 | <button class="calendar-action" data-calendar-type="ics"> 178 | <svg 179 | width="20" 180 | height="20" 181 | viewBox="0 0 24 24" 182 | fill="none" 183 | stroke="currentColor" 184 | > 185 | <path 186 | d="M12 15V3m0 12l-4-4m4 4l4-4M3 17l.6 2.6c.2.8.8 1.4 1.6 1.4h13.6c.8 0 1.4-.6 1.6-1.4l.6-2.6" 187 | stroke-width="2" 188 | stroke-linecap="round" 189 | stroke-linejoin="round" 190 | /> 191 | </svg> 192 | Download .ics 193 | </button> 194 | </div> 195 | </div> 196 | </div> 197 | <div class="attendees"> 198 | <div class="attendee-avatars"> 199 | <div class="attendee-avatar" data-tooltip="Special Guest"> 200 | <img src="public/special_guest.png" alt="Special Guest" /> 201 | </div> 202 | <div class="attendee-avatar" data-tooltip="Sunil Pai"> 203 | <img src="public/sunil.jpg" alt="Sunil Pai" /> 204 | </div> 205 | <div class="attendee-avatar" data-tooltip="Dina Kozlov"> 206 | <img src="public/dina.jpg" alt="Dina Kozlov" /> 207 | </div> 208 | </div> 209 | <span class="attendee-count"><strong>+ all the other cool kids</strong> went</span> 210 | </div> 211 | </div> 212 | </section> 213 | 214 | <section class="right-panel"> 215 | <div class="demos-section"> 216 | <h4>DEMOS FROM</h4> 217 | <ul class="demo-companies"> 218 | <li>Asana</li> 219 | <li>Atlassian</li> 220 | <li>Cloudflare</li> 221 | <li>Intercom</li> 222 | <li>Linear</li> 223 | <li>Paypal</li> 224 | <li>Sentry</li> 225 | <li>Square</li> 226 | <li>Stripe</li> 227 | <li>Webflow</li> 228 | <li>+ More</li> 229 | </ul> 230 | </div> 231 | </section> 232 | </main> 233 | 234 | <footer> 235 | <div class="footer-left"> 236 | <img src="public/cloudflare_logo.svg" alt="Cloudflare" class="cloudflare-logo" /> 237 | <div class="footer-links"></div> 238 | </div> 239 | <a 240 | href="https://developers.cloudflare.com/agents/guides/remote-mcp-server/?utm_source=website&utm_medium=reg+page&utm_campaign=MCP+Demo+Day" 241 | target="_blank" 242 | class="build-btn" 243 | > 244 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="24" height="24"> 245 | <path d="M8.16 23h21.177v-5.86l-4.023-2.307-.694-.3-16.46.113z" fill="transparent" /> 246 | <path 247 | d="M22.012 22.222c.197-.675.122-1.294-.206-1.754-.3-.422-.807-.666-1.416-.694l-11.545-.15c-.075 0-.14-.038-.178-.094s-.047-.13-.028-.206c.038-.113.15-.197.272-.206l11.648-.15c1.38-.066 2.88-1.182 3.404-2.55l.666-1.735a.38.38 0 0 0 .02-.225c-.75-3.395-3.78-5.927-7.4-5.927-3.34 0-6.17 2.157-7.184 5.15-.657-.488-1.5-.75-2.392-.666-1.604.16-2.9 1.444-3.048 3.048a3.58 3.58 0 0 0 .084 1.191A4.84 4.84 0 0 0 0 22.1c0 .234.02.47.047.703.02.113.113.197.225.197H21.58a.29.29 0 0 0 .272-.206l.16-.572z" 248 | fill="currentColor" 249 | /> 250 | <path 251 | d="M25.688 14.803l-.32.01c-.075 0-.14.056-.17.13l-.45 1.566c-.197.675-.122 1.294.206 1.754.3.422.807.666 1.416.694l2.457.15c.075 0 .14.038.178.094s.047.14.028.206c-.038.113-.15.197-.272.206l-2.56.15c-1.388.066-2.88 1.182-3.404 2.55l-.188.478c-.038.094.028.188.13.188h8.797a.23.23 0 0 0 .225-.169A6.41 6.41 0 0 0 32 21.106a6.32 6.32 0 0 0-6.312-6.302" 252 | fill="currentColor" 253 | /> 254 | </svg> 255 | Build An MCP Server 256 | </a> 257 | </footer> 258 | </div> 259 | <dialog id="calendarDialog" class="calendar-popover"> 260 | <h4>Add to Calendar</h4> 261 | <button class="close-button" onclick="document.getElementById('calendarDialog').close()"> 262 | <svg 263 | width="16" 264 | height="16" 265 | viewBox="0 0 24 24" 266 | fill="none" 267 | stroke="currentColor" 268 | stroke-width="1" 269 | > 270 | <path d="M6 18L18 6M6 6l12 12" stroke-linecap="round" stroke-linejoin="round" /> 271 | </svg> 272 | </button> 273 | <div class="calendar-options"> 274 | <button class="calendar-option" data-calendar-type="google"> 275 | <svg 276 | xmlns="http://www.w3.org/2000/svg" 277 | x="0px" 278 | y="0px" 279 | width="100" 280 | height="100" 281 | viewBox="0,0,256,256" 282 | style="fill: #ffffff" 283 | > 284 | <g 285 | fill="#ffffff" 286 | fill-rule="nonzero" 287 | stroke="none" 288 | stroke-width="1" 289 | stroke-linecap="butt" 290 | stroke-linejoin="miter" 291 | stroke-miterlimit="10" 292 | stroke-dasharray="" 293 | stroke-dashoffset="0" 294 | font-family="none" 295 | font-weight="none" 296 | font-size="none" 297 | text-anchor="none" 298 | style="mix-blend-mode: normal" 299 | > 300 | <g transform="scale(5.12,5.12)"> 301 | <path 302 | d="M25.99609,48c-12.68359,0 -23.00391,-10.31641 -23.00391,-23c0,-12.68359 10.32031,-23 23.00391,-23c5.74609,0 11.24609,2.12891 15.49219,5.99609l0.77344,0.70703l-7.58594,7.58594l-0.70312,-0.60156c-2.22656,-1.90625 -5.05859,-2.95703 -7.97656,-2.95703c-6.76562,0 -12.27344,5.50391 -12.27344,12.26953c0,6.76563 5.50781,12.26953 12.27344,12.26953c4.87891,0 8.73438,-2.49219 10.55078,-6.73828h-11.55078v-10.35547l22.55078,0.03125l0.16797,0.79297c1.17578,5.58203 0.23438,13.79297 -4.53125,19.66797c-3.94531,4.86328 -9.72656,7.33203 -17.1875,7.33203z" 303 | ></path> 304 | </g> 305 | </g> 306 | </svg> 307 | <span>Google Calendar</span> 308 | </button> 309 | <button class="calendar-option" data-calendar-type="outlook"> 310 | <svg 311 | xmlns="http://www.w3.org/2000/svg" 312 | x="0px" 313 | y="0px" 314 | width="100" 315 | height="100" 316 | viewBox="0,0,256,256" 317 | style="fill: #ffffff" 318 | > 319 | <g 320 | fill="#ffffff" 321 | fill-rule="nonzero" 322 | stroke="none" 323 | stroke-width="1" 324 | stroke-linecap="butt" 325 | stroke-linejoin="miter" 326 | stroke-miterlimit="10" 327 | stroke-dasharray="" 328 | stroke-dashoffset="0" 329 | font-family="none" 330 | font-weight="none" 331 | font-size="none" 332 | text-anchor="none" 333 | style="mix-blend-mode: normal" 334 | > 335 | <g transform="scale(5.12,5.12)"> 336 | <path 337 | d="M5,4c-0.552,0 -1,0.447 -1,1v19h20v-20zM26,4v20h20v-19c0,-0.553 -0.448,-1 -1,-1zM4,26v19c0,0.553 0.448,1 1,1h19v-20zM26,26v20h19c0.552,0 1,-0.447 1,-1v-19z" 338 | ></path> 339 | </g> 340 | </g> 341 | </svg> 342 | <span>Outlook Calendar</span> 343 | </button> 344 | <button class="calendar-option" data-calendar-type="apple"> 345 | <svg 346 | xmlns="http://www.w3.org/2000/svg" 347 | x="0px" 348 | y="0px" 349 | width="100" 350 | height="100" 351 | viewBox="0,0,256,256" 352 | style="fill: #ffffff" 353 | > 354 | <g 355 | fill="#ffffff" 356 | fill-rule="nonzero" 357 | stroke="none" 358 | stroke-width="1" 359 | stroke-linecap="butt" 360 | stroke-linejoin="miter" 361 | stroke-miterlimit="10" 362 | stroke-dasharray="" 363 | stroke-dashoffset="0" 364 | font-family="none" 365 | font-weight="none" 366 | font-size="none" 367 | text-anchor="none" 368 | style="mix-blend-mode: normal" 369 | > 370 | <g transform="scale(5.12,5.12)"> 371 | <path 372 | d="M44.52734,34.75c-1.07812,2.39453 -1.59766,3.46484 -2.98437,5.57813c-1.94141,2.95313 -4.67969,6.64063 -8.0625,6.66406c-3.01172,0.02734 -3.78906,-1.96484 -7.87891,-1.92969c-4.08594,0.01953 -4.9375,1.96875 -7.95312,1.9375c-3.38672,-0.03125 -5.97656,-3.35156 -7.91797,-6.30078c-5.42969,-8.26953 -6.00391,-17.96484 -2.64844,-23.12109c2.375,-3.65625 6.12891,-5.80469 9.65625,-5.80469c3.59375,0 5.85156,1.97266 8.82031,1.97266c2.88281,0 4.63672,-1.97656 8.79297,-1.97656c3.14063,0 6.46094,1.71094 8.83594,4.66406c-7.76562,4.25781 -6.50391,15.34766 1.33984,18.31641zM31.19531,8.46875c1.51172,-1.94141 2.66016,-4.67969 2.24219,-7.46875c-2.46484,0.16797 -5.34766,1.74219 -7.03125,3.78125c-1.52734,1.85938 -2.79297,4.61719 -2.30078,7.28516c2.69141,0.08594 5.47656,-1.51953 7.08984,-3.59766z" 373 | ></path> 374 | </g> 375 | </g> 376 | </svg> 377 | <span>Apple Calendar</span> 378 | </button> 379 | <button class="calendar-option" data-calendar-type="ics"> 380 | <svg 381 | width="20" 382 | height="20" 383 | viewBox="0 0 24 24" 384 | fill="none" 385 | stroke="currentColor" 386 | stroke-width="1" 387 | > 388 | <path 389 | d="M12 15V3m0 12l-4-4m4 4l4-4M2 17l.621 2.485A2 2 0 004.561 21h14.878a2 2 0 001.94-1.515L22 17" 390 | stroke-linecap="round" 391 | stroke-linejoin="round" 392 | /> 393 | </svg> 394 | <span>Download .ics File</span> 395 | </button> 396 | </div> 397 | </dialog> 398 | <script src="script.js"></script> 399 | </body> 400 | </html> 401 | ``` -------------------------------------------------------------------------------- /apps/radar/src/tools/radar.tools.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { z } from 'zod' 2 | 3 | import { getCloudflareClient } from '@repo/mcp-common/src/cloudflare-api' 4 | import { getProps } from '@repo/mcp-common/src/get-props' 5 | import { 6 | PaginationLimitParam, 7 | PaginationOffsetParam, 8 | } from '@repo/mcp-common/src/types/shared.types' 9 | 10 | import { 11 | AiDimensionParam, 12 | AsnArrayParam, 13 | AsnParam, 14 | AsOrderByParam, 15 | ContinentArrayParam, 16 | DateEndArrayParam, 17 | DateEndParam, 18 | DateListParam, 19 | DateRangeArrayParam, 20 | DateRangeParam, 21 | DateStartArrayParam, 22 | DateStartParam, 23 | DnsDimensionParam, 24 | DomainParam, 25 | DomainRankingTypeParam, 26 | EmailRoutingDimensionParam, 27 | EmailSecurityDimensionParam, 28 | HttpDimensionParam, 29 | InternetQualityMetricParam, 30 | InternetServicesCategoryParam, 31 | InternetSpeedDimensionParam, 32 | InternetSpeedOrderByParam, 33 | IpParam, 34 | L3AttackDimensionParam, 35 | L7AttackDimensionParam, 36 | LocationArrayParam, 37 | LocationListParam, 38 | LocationParam, 39 | } from '../types/radar' 40 | import { resolveAndInvoke } from '../utils' 41 | 42 | import type { RadarMCP } from '../radar.app' 43 | 44 | export function registerRadarTools(agent: RadarMCP) { 45 | agent.server.tool( 46 | 'list_autonomous_systems', 47 | 'List Autonomous Systems', 48 | { 49 | limit: PaginationLimitParam, 50 | offset: PaginationOffsetParam, 51 | location: LocationParam.optional(), 52 | orderBy: AsOrderByParam, 53 | }, 54 | async ({ limit, offset, location, orderBy }) => { 55 | try { 56 | const props = getProps(agent) 57 | const client = getCloudflareClient(props.accessToken) 58 | const r = await client.radar.entities.asns.list({ 59 | limit, 60 | offset, 61 | location, 62 | orderBy, 63 | }) 64 | 65 | return { 66 | content: [ 67 | { 68 | type: 'text', 69 | text: JSON.stringify({ 70 | result: r.asns, 71 | }), 72 | }, 73 | ], 74 | } 75 | } catch (error) { 76 | return { 77 | content: [ 78 | { 79 | type: 'text', 80 | text: `Error listing ASes: ${error instanceof Error && error.message}`, 81 | }, 82 | ], 83 | } 84 | } 85 | } 86 | ) 87 | 88 | agent.server.tool( 89 | 'get_as_details', 90 | 'Get Autonomous System details by ASN', 91 | { 92 | asn: AsnParam, 93 | }, 94 | async ({ asn }) => { 95 | try { 96 | const props = getProps(agent) 97 | const client = getCloudflareClient(props.accessToken) 98 | const r = await client.radar.entities.asns.get(asn) 99 | 100 | return { 101 | content: [ 102 | { 103 | type: 'text', 104 | text: JSON.stringify({ 105 | result: r.asn, 106 | }), 107 | }, 108 | ], 109 | } 110 | } catch (error) { 111 | return { 112 | content: [ 113 | { 114 | type: 'text', 115 | text: `Error getting AS details: ${error instanceof Error && error.message}`, 116 | }, 117 | ], 118 | } 119 | } 120 | } 121 | ) 122 | 123 | agent.server.tool( 124 | 'get_ip_details', 125 | 'Get IP address information', 126 | { 127 | ip: IpParam, 128 | }, 129 | async ({ ip }) => { 130 | try { 131 | const props = getProps(agent) 132 | const client = getCloudflareClient(props.accessToken) 133 | const r = await client.radar.entities.get({ ip }) 134 | 135 | return { 136 | content: [ 137 | { 138 | type: 'text', 139 | text: JSON.stringify({ 140 | result: r.ip, 141 | }), 142 | }, 143 | ], 144 | } 145 | } catch (error) { 146 | return { 147 | content: [ 148 | { 149 | type: 'text', 150 | text: `Error getting IP details: ${error instanceof Error && error.message}`, 151 | }, 152 | ], 153 | } 154 | } 155 | } 156 | ) 157 | 158 | agent.server.tool( 159 | 'get_traffic_anomalies', 160 | 'Get traffic anomalies and outages', 161 | { 162 | limit: PaginationLimitParam, 163 | offset: PaginationOffsetParam, 164 | asn: AsnParam.optional(), 165 | location: LocationParam.optional(), 166 | dateRange: DateRangeParam.optional(), 167 | dateStart: DateStartParam.optional(), 168 | dateEnd: DateEndParam.optional(), 169 | }, 170 | async ({ limit, offset, asn, location, dateStart, dateEnd, dateRange }) => { 171 | try { 172 | const props = getProps(agent) 173 | const client = getCloudflareClient(props.accessToken) 174 | const r = await client.radar.trafficAnomalies.get({ 175 | limit, 176 | offset, 177 | asn, 178 | location, 179 | dateRange, 180 | dateStart, 181 | dateEnd, 182 | status: 'VERIFIED', 183 | }) 184 | 185 | return { 186 | content: [ 187 | { 188 | type: 'text', 189 | text: JSON.stringify({ 190 | result: r.trafficAnomalies, 191 | }), 192 | }, 193 | ], 194 | } 195 | } catch (error) { 196 | return { 197 | content: [ 198 | { 199 | type: 'text', 200 | text: `Error getting IP details: ${error instanceof Error && error.message}`, 201 | }, 202 | ], 203 | } 204 | } 205 | } 206 | ) 207 | 208 | agent.server.tool( 209 | 'get_internet_services_ranking', 210 | 'Get top Internet services', 211 | { 212 | limit: PaginationLimitParam, 213 | date: DateListParam.optional(), 214 | serviceCategory: InternetServicesCategoryParam.optional(), 215 | }, 216 | async ({ limit, date, serviceCategory }) => { 217 | try { 218 | const props = getProps(agent) 219 | const client = getCloudflareClient(props.accessToken) 220 | const r = await client.radar.ranking.internetServices.top({ 221 | limit, 222 | date, 223 | serviceCategory, 224 | }) 225 | 226 | return { 227 | content: [ 228 | { 229 | type: 'text', 230 | text: JSON.stringify({ 231 | result: r, 232 | }), 233 | }, 234 | ], 235 | } 236 | } catch (error) { 237 | return { 238 | content: [ 239 | { 240 | type: 'text', 241 | text: `Error getting Internet services ranking: ${error instanceof Error && error.message}`, 242 | }, 243 | ], 244 | } 245 | } 246 | } 247 | ) 248 | 249 | agent.server.tool( 250 | 'get_domains_ranking', 251 | 'Get top or trending domains', 252 | { 253 | limit: PaginationLimitParam, 254 | date: DateListParam.optional(), 255 | location: LocationListParam.optional(), 256 | rankingType: DomainRankingTypeParam.optional(), 257 | }, 258 | async ({ limit, date, location, rankingType }) => { 259 | try { 260 | const props = getProps(agent) 261 | const client = getCloudflareClient(props.accessToken) 262 | const r = await client.radar.ranking.top({ 263 | limit, 264 | date, 265 | location, 266 | rankingType, 267 | }) 268 | 269 | return { 270 | content: [ 271 | { 272 | type: 'text', 273 | text: JSON.stringify({ 274 | result: r, 275 | }), 276 | }, 277 | ], 278 | } 279 | } catch (error) { 280 | return { 281 | content: [ 282 | { 283 | type: 'text', 284 | text: `Error getting domains ranking: ${error instanceof Error && error.message}`, 285 | }, 286 | ], 287 | } 288 | } 289 | } 290 | ) 291 | 292 | agent.server.tool( 293 | 'get_domain_rank_details', 294 | 'Get domain rank details', 295 | { 296 | domain: DomainParam, 297 | date: DateListParam.optional(), 298 | }, 299 | async ({ domain, date }) => { 300 | try { 301 | const props = getProps(agent) 302 | const client = getCloudflareClient(props.accessToken) 303 | const r = await client.radar.ranking.domain.get(domain, { date }) 304 | 305 | return { 306 | content: [ 307 | { 308 | type: 'text', 309 | text: JSON.stringify({ 310 | result: r, 311 | }), 312 | }, 313 | ], 314 | } 315 | } catch (error) { 316 | return { 317 | content: [ 318 | { 319 | type: 'text', 320 | text: `Error getting domain ranking details: ${error instanceof Error && error.message}`, 321 | }, 322 | ], 323 | } 324 | } 325 | } 326 | ) 327 | 328 | agent.server.tool( 329 | 'get_http_data', 330 | 'Retrieve HTTP traffic trends.', 331 | { 332 | dateRange: DateRangeArrayParam.optional(), 333 | dateStart: DateStartArrayParam.optional(), 334 | dateEnd: DateEndArrayParam.optional(), 335 | asn: AsnArrayParam, 336 | continent: ContinentArrayParam, 337 | location: LocationArrayParam, 338 | dimension: HttpDimensionParam, 339 | }, 340 | async ({ dateStart, dateEnd, dateRange, asn, location, continent, dimension }) => { 341 | try { 342 | const props = getProps(agent) 343 | const client = getCloudflareClient(props.accessToken) 344 | const r = await resolveAndInvoke(client.radar.http, dimension, { 345 | asn, 346 | continent, 347 | location, 348 | dateRange, 349 | dateStart, 350 | dateEnd, 351 | }) 352 | 353 | return { 354 | content: [ 355 | { 356 | type: 'text', 357 | text: JSON.stringify({ 358 | result: r, 359 | }), 360 | }, 361 | ], 362 | } 363 | } catch (error) { 364 | return { 365 | content: [ 366 | { 367 | type: 'text', 368 | text: `Error getting HTTP data: ${error instanceof Error && error.message}`, 369 | }, 370 | ], 371 | } 372 | } 373 | } 374 | ) 375 | 376 | agent.server.tool( 377 | 'get_dns_queries_data', 378 | 'Retrieve trends in DNS queries to the 1.1.1.1 resolver.', 379 | { 380 | dateRange: DateRangeArrayParam.optional(), 381 | dateStart: DateStartArrayParam.optional(), 382 | dateEnd: DateEndArrayParam.optional(), 383 | asn: AsnArrayParam, 384 | continent: ContinentArrayParam, 385 | location: LocationArrayParam, 386 | dimension: DnsDimensionParam, 387 | }, 388 | async ({ dateStart, dateEnd, dateRange, asn, location, continent, dimension }) => { 389 | try { 390 | const props = getProps(agent) 391 | const client = getCloudflareClient(props.accessToken) 392 | const r = await resolveAndInvoke(client.radar.dns, dimension, { 393 | asn, 394 | continent, 395 | location, 396 | dateRange, 397 | dateStart, 398 | dateEnd, 399 | }) 400 | 401 | return { 402 | content: [ 403 | { 404 | type: 'text', 405 | text: JSON.stringify({ 406 | result: r, 407 | }), 408 | }, 409 | ], 410 | } 411 | } catch (error) { 412 | return { 413 | content: [ 414 | { 415 | type: 'text', 416 | text: `Error getting DNS data: ${error instanceof Error && error.message}`, 417 | }, 418 | ], 419 | } 420 | } 421 | } 422 | ) 423 | 424 | agent.server.tool( 425 | 'get_l7_attack_data', 426 | 'Retrieve application layer (L7) attack trends.', 427 | { 428 | dateRange: DateRangeArrayParam.optional(), 429 | dateStart: DateStartArrayParam.optional(), 430 | dateEnd: DateEndArrayParam.optional(), 431 | asn: AsnArrayParam, 432 | continent: ContinentArrayParam, 433 | location: LocationArrayParam, 434 | dimension: L7AttackDimensionParam, 435 | }, 436 | async ({ dateStart, dateEnd, dateRange, asn, location, continent, dimension }) => { 437 | try { 438 | const props = getProps(agent) 439 | const client = getCloudflareClient(props.accessToken) 440 | const r = await resolveAndInvoke(client.radar.attacks.layer7, dimension, { 441 | asn, 442 | continent, 443 | location, 444 | dateRange, 445 | dateStart, 446 | dateEnd, 447 | }) 448 | 449 | return { 450 | content: [ 451 | { 452 | type: 'text', 453 | text: JSON.stringify({ 454 | result: r, 455 | }), 456 | }, 457 | ], 458 | } 459 | } catch (error) { 460 | return { 461 | content: [ 462 | { 463 | type: 'text', 464 | text: `Error getting L7 attack data: ${error instanceof Error && error.message}`, 465 | }, 466 | ], 467 | } 468 | } 469 | } 470 | ) 471 | 472 | agent.server.tool( 473 | 'get_l3_attack_data', 474 | 'Retrieve application layer (L3) attack trends.', 475 | { 476 | dateRange: DateRangeArrayParam.optional(), 477 | dateStart: DateStartArrayParam.optional(), 478 | dateEnd: DateEndArrayParam.optional(), 479 | asn: AsnArrayParam, 480 | continent: ContinentArrayParam, 481 | location: LocationArrayParam, 482 | dimension: L3AttackDimensionParam, 483 | }, 484 | async ({ dateStart, dateEnd, dateRange, asn, location, continent, dimension }) => { 485 | try { 486 | const props = getProps(agent) 487 | const client = getCloudflareClient(props.accessToken) 488 | const r = await resolveAndInvoke(client.radar.attacks.layer3, dimension, { 489 | asn, 490 | continent, 491 | location, 492 | dateRange, 493 | dateStart, 494 | dateEnd, 495 | }) 496 | 497 | return { 498 | content: [ 499 | { 500 | type: 'text', 501 | text: JSON.stringify({ 502 | result: r, 503 | }), 504 | }, 505 | ], 506 | } 507 | } catch (error) { 508 | return { 509 | content: [ 510 | { 511 | type: 'text', 512 | text: `Error getting L3 attack data: ${error instanceof Error && error.message}`, 513 | }, 514 | ], 515 | } 516 | } 517 | } 518 | ) 519 | 520 | agent.server.tool( 521 | 'get_email_routing_data', 522 | 'Retrieve Email Routing trends.', 523 | { 524 | dateRange: DateRangeArrayParam.optional(), 525 | dateStart: DateStartArrayParam.optional(), 526 | dateEnd: DateEndArrayParam.optional(), 527 | dimension: EmailRoutingDimensionParam, 528 | }, 529 | async ({ dateStart, dateEnd, dateRange, dimension }) => { 530 | try { 531 | const props = getProps(agent) 532 | const client = getCloudflareClient(props.accessToken) 533 | const r = await resolveAndInvoke(client.radar.email.routing, dimension, { 534 | dateRange, 535 | dateStart, 536 | dateEnd, 537 | }) 538 | 539 | return { 540 | content: [ 541 | { 542 | type: 'text', 543 | text: JSON.stringify({ 544 | result: r, 545 | }), 546 | }, 547 | ], 548 | } 549 | } catch (error) { 550 | return { 551 | content: [ 552 | { 553 | type: 'text', 554 | text: `Error getting Email Routing data: ${error instanceof Error && error.message}`, 555 | }, 556 | ], 557 | } 558 | } 559 | } 560 | ) 561 | 562 | agent.server.tool( 563 | 'get_email_security_data', 564 | 'Retrieve Email Security trends.', 565 | { 566 | dateRange: DateRangeArrayParam.optional(), 567 | dateStart: DateStartArrayParam.optional(), 568 | dateEnd: DateEndArrayParam.optional(), 569 | dimension: EmailSecurityDimensionParam, 570 | }, 571 | async ({ dateStart, dateEnd, dateRange, dimension }) => { 572 | try { 573 | const props = getProps(agent) 574 | const client = getCloudflareClient(props.accessToken) 575 | const r = await resolveAndInvoke(client.radar.email.security, dimension, { 576 | dateRange, 577 | dateStart, 578 | dateEnd, 579 | }) 580 | 581 | return { 582 | content: [ 583 | { 584 | type: 'text', 585 | text: JSON.stringify({ 586 | result: r, 587 | }), 588 | }, 589 | ], 590 | } 591 | } catch (error) { 592 | return { 593 | content: [ 594 | { 595 | type: 'text', 596 | text: `Error getting Email Security data: ${error instanceof Error && error.message}`, 597 | }, 598 | ], 599 | } 600 | } 601 | } 602 | ) 603 | 604 | agent.server.tool( 605 | 'get_internet_speed_data', 606 | 'Retrieve summary of bandwidth, latency, jitter, and packet loss, from the previous 90 days of Cloudflare Speed Test.', 607 | { 608 | dateEnd: DateEndArrayParam.optional(), 609 | asn: AsnArrayParam, 610 | continent: ContinentArrayParam, 611 | location: LocationArrayParam, 612 | dimension: InternetSpeedDimensionParam, 613 | orderBy: InternetSpeedOrderByParam.optional(), 614 | }, 615 | async ({ dateEnd, asn, location, continent, dimension, orderBy }) => { 616 | if (orderBy && dimension === 'summary') { 617 | throw new Error('Order by is only allowed for top locations and ASes') 618 | } 619 | 620 | try { 621 | const props = getProps(agent) 622 | const client = getCloudflareClient(props.accessToken) 623 | const r = await resolveAndInvoke(client.radar.quality.speed, dimension, { 624 | asn, 625 | continent, 626 | location, 627 | dateEnd, 628 | }) 629 | 630 | return { 631 | content: [ 632 | { 633 | type: 'text', 634 | text: JSON.stringify({ 635 | result: r, 636 | }), 637 | }, 638 | ], 639 | } 640 | } catch (error) { 641 | return { 642 | content: [ 643 | { 644 | type: 'text', 645 | text: `Error getting Internet speed data: ${error instanceof Error && error.message}`, 646 | }, 647 | ], 648 | } 649 | } 650 | } 651 | ) 652 | 653 | agent.server.tool( 654 | 'get_internet_quality_data', 655 | 'Retrieves a summary or time series of bandwidth, latency, or DNS response time percentiles from the Radar Internet Quality Index (IQI).', 656 | { 657 | dateRange: DateRangeArrayParam.optional(), 658 | dateStart: DateStartArrayParam.optional(), 659 | dateEnd: DateEndArrayParam.optional(), 660 | asn: AsnArrayParam, 661 | continent: ContinentArrayParam, 662 | location: LocationArrayParam, 663 | format: z.enum(['summary', 'timeseriesGroups']), 664 | metric: InternetQualityMetricParam, 665 | }, 666 | async ({ dateRange, dateStart, dateEnd, asn, location, continent, format, metric }) => { 667 | try { 668 | const props = getProps(agent) 669 | const client = getCloudflareClient(props.accessToken) 670 | const r = await client.radar.quality.iqi[format]({ 671 | asn, 672 | continent, 673 | location, 674 | dateRange, 675 | dateStart, 676 | dateEnd, 677 | metric, 678 | }) 679 | 680 | return { 681 | content: [ 682 | { 683 | type: 'text', 684 | text: JSON.stringify({ 685 | result: r, 686 | }), 687 | }, 688 | ], 689 | } 690 | } catch (error) { 691 | return { 692 | content: [ 693 | { 694 | type: 'text', 695 | text: `Error getting Internet quality data: ${error instanceof Error && error.message}`, 696 | }, 697 | ], 698 | } 699 | } 700 | } 701 | ) 702 | 703 | agent.server.tool( 704 | 'get_ai_data', 705 | 'Retrieves AI-related data, including traffic from AI user agents, as well as popular models and model tasks specifically from Cloudflare Workers AI.', 706 | { 707 | dateRange: DateRangeArrayParam.optional(), 708 | dateStart: DateStartArrayParam.optional(), 709 | dateEnd: DateEndArrayParam.optional(), 710 | asn: AsnArrayParam, 711 | continent: ContinentArrayParam, 712 | location: LocationArrayParam, 713 | dimension: AiDimensionParam, 714 | }, 715 | async ({ dateRange, dateStart, dateEnd, asn, location, continent, dimension }) => { 716 | try { 717 | const props = getProps(agent) 718 | const client = getCloudflareClient(props.accessToken) 719 | const r = await resolveAndInvoke(client.radar.ai, dimension, { 720 | asn, 721 | continent, 722 | location, 723 | dateRange, 724 | dateStart, 725 | dateEnd, 726 | }) 727 | 728 | return { 729 | content: [ 730 | { 731 | type: 'text', 732 | text: JSON.stringify({ 733 | result: r, 734 | }), 735 | }, 736 | ], 737 | } 738 | } catch (error) { 739 | return { 740 | content: [ 741 | { 742 | type: 'text', 743 | text: `Error getting AI data: ${error instanceof Error && error.message}`, 744 | }, 745 | ], 746 | } 747 | } 748 | } 749 | ) 750 | } 751 | ``` -------------------------------------------------------------------------------- /apps/demo-day/frontend/script.js: -------------------------------------------------------------------------------- ```javascript 1 | document.addEventListener('DOMContentLoaded', () => { 2 | const container = document.querySelector('.page-wrapper') 3 | const starfield = document.createElement('div') 4 | starfield.className = 'starfield' 5 | container.appendChild(starfield) 6 | 7 | // Create initial stars 8 | const numberOfStars = 300 9 | const stars = [] 10 | 11 | function createStar() { 12 | const star = document.createElement('div') 13 | star.className = 'star' 14 | 15 | // Random position 16 | const x = Math.random() * window.innerWidth 17 | const y = Math.random() * window.innerHeight 18 | 19 | // Random size (more variation in sizes) 20 | const size = Math.random() * 2 + (Math.random() > 0.95 ? 1.5 : 0) 21 | 22 | // More subtle initial opacity 23 | const opacity = Math.random() * 0.15 + 0.05 24 | 25 | star.style.cssText = ` 26 | left: ${x}px; 27 | top: ${y}px; 28 | width: ${size}px; 29 | height: ${size}px; 30 | opacity: ${opacity}; 31 | ` 32 | 33 | return star 34 | } 35 | 36 | // Initialize stars 37 | for (let i = 0; i < numberOfStars; i++) { 38 | const star = createStar() 39 | starfield.appendChild(star) 40 | stars.push(star) 41 | } 42 | 43 | // Animate stars 44 | function twinkle() { 45 | stars.forEach((star) => { 46 | // Random chance to twinkle 47 | if (Math.random() > 0.98) { 48 | const currentOpacity = parseFloat(star.style.opacity) 49 | const targetOpacity = 50 | currentOpacity < 0.1 51 | ? Math.random() * 0.15 + 0.05 // Brighter 52 | : Math.random() * 0.05 + 0.02 // Dimmer 53 | 54 | // Slower transition for more subtle effect 55 | star.style.transition = 'opacity 1.5s ease-in-out' 56 | star.style.opacity = targetOpacity 57 | } 58 | }) 59 | 60 | requestAnimationFrame(twinkle) 61 | } 62 | 63 | // Start animation 64 | twinkle() 65 | 66 | // Form handling 67 | const emailForm = document.querySelector('.input-group') 68 | //const //emailInput = null //emailForm.querySelector('input[type="email"]') 69 | const honeypotInput = emailForm.querySelector('input[name="contact_me_by_fax"]') 70 | //const notifyButton = emailForm.querySelector('.notify-btn') 71 | 72 | // Check if user has already signed up 73 | /*if (localStorage.getItem('mcp_demo_signup')) { 74 | const savedEmail = localStorage.getItem('mcp_demo_signup') 75 | showSuccessState(savedEmail) 76 | }*/ 77 | 78 | /*function showSuccessState(email) { 79 | const inputGroup = //emailInput.closest('.input-group') 80 | inputGroup.classList.add('success') 81 | //emailInput.value = email 82 | //emailInput.disabled = true 83 | notifyButton.disabled = true 84 | 85 | // Update button 86 | notifyButton.innerHTML = ` 87 | <svg width="16" height="16" viewBox="0 0 16 16" fill="none"> 88 | <path d="M13.5 4.5L6 12L2.5 8.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 89 | </svg> 90 | ` 91 | notifyButton.classList.add('success') 92 | createConfetti(notifyButton) 93 | }*/ 94 | 95 | // Rate limiting configuration 96 | const RATE_LIMIT_DURATION = 60000 // 1 minute 97 | const MAX_ATTEMPTS = 5 98 | let attemptCount = 0 99 | let lastAttemptTime = 0 100 | 101 | function checkRateLimit() { 102 | const now = Date.now() 103 | if (now - lastAttemptTime > RATE_LIMIT_DURATION) { 104 | attemptCount = 0 105 | } 106 | 107 | if (attemptCount >= MAX_ATTEMPTS) { 108 | return false 109 | } 110 | 111 | attemptCount++ 112 | lastAttemptTime = now 113 | return true 114 | } 115 | 116 | // Enhanced email validation 117 | function isValidEmail(email) { 118 | if (email.length > 254) return false 119 | const re = 120 | /^(?=[a-zA-Z0-9@._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/ 121 | return re.test(email) 122 | } 123 | 124 | // XSS Prevention 125 | function sanitizeInput(str) { 126 | const div = document.createElement('div') 127 | div.textContent = str 128 | return div.innerHTML 129 | } 130 | 131 | // Debounced email validation 132 | const debounce = (fn, delay) => { 133 | let timeoutId 134 | return (...args) => { 135 | clearTimeout(timeoutId) 136 | timeoutId = setTimeout(() => fn(...args), delay) 137 | } 138 | } 139 | 140 | // Retry logic for API calls 141 | async function retryFetch(url, options, maxRetries = 3) { 142 | for (let i = 0; i < maxRetries; i++) { 143 | try { 144 | const response = await fetch(url, options) 145 | const data = await response.json() 146 | return { response, data } 147 | } catch (error) { 148 | if (i === maxRetries - 1) throw error 149 | await new Promise((resolve) => setTimeout(resolve, 1000 * Math.pow(2, i))) 150 | } 151 | } 152 | } 153 | 154 | // Enhanced toast function with accessibility 155 | function showToast(message, duration = 3000) { 156 | const existingToast = document.querySelector('.toast') 157 | if (existingToast) { 158 | existingToast.remove() 159 | } 160 | 161 | const toast = document.createElement('div') 162 | toast.className = 'toast' 163 | toast.setAttribute('role', 'alert') 164 | toast.setAttribute('aria-live', 'polite') 165 | toast.textContent = sanitizeInput(message) 166 | document.body.appendChild(toast) 167 | 168 | toast.offsetHeight 169 | toast.classList.add('show') 170 | 171 | setTimeout(() => { 172 | toast.classList.remove('show') 173 | setTimeout(() => toast.remove(), 300) 174 | }, duration) 175 | } 176 | 177 | // Setup accessibility attributes 178 | /*function setupAccessibility() { 179 | //emailInput.setAttribute('aria-label', 'Email address for notification') 180 | notifyButton.setAttribute('aria-label', 'Sign up for notification') 181 | document.querySelector('.success-message')?.setAttribute('role', 'status') 182 | }*/ 183 | 184 | // Debounced email validation on input 185 | const validateEmailDebounced = debounce((email) => { 186 | const isValid = isValidEmail(email) 187 | //emailInput.style.border = isValid ? '' : '1px solid red' 188 | }, 300) 189 | 190 | //emailInput.addEventListener('input', (e) => validateEmailDebounced(e.target.value)) 191 | 192 | // Enhanced click handler with all improvements 193 | /*notifyButton.addEventListener('click', async (e) => { 194 | e.preventDefault() 195 | //const email = //emailInput.value.trim() 196 | 197 | // Rate limit check 198 | if (!checkRateLimit()) { 199 | showToast('Please wait a minute before trying again.') 200 | return 201 | } 202 | 203 | // Basic validation 204 | if (!email) { 205 | //emailInput.style.border = '1px solid red' 206 | return 207 | } 208 | 209 | if (!isValidEmail(email)) { 210 | //emailInput.style.border = '1px solid red' 211 | showToast('Please enter a valid email address.') 212 | return 213 | } 214 | 215 | // Check if already signed up 216 | /*if (localStorage.getItem('mcp_demo_signup')) { 217 | return 218 | }*/ 219 | 220 | // Honeypot check 221 | /*if (honeypotInput.value) { 222 | console.log('Bot detected') 223 | return 224 | } 225 | 226 | try { 227 | const { response, data } = await retryFetch( 228 | 'https://starbasedb-3285.outerbase.workers.dev/query', 229 | { 230 | method: 'POST', 231 | headers: { 232 | 'X-Starbase-Source': 'internal', 233 | Authorization: 'Bearer 8gmjguywgvsy2hvxnqpqzapwjq896ke3', 234 | 'Content-Type': 'application/json', 235 | }, 236 | body: JSON.stringify({ 237 | sql: 'INSERT INTO signups (email, status, created_at) VALUES (?, ?, CURRENT_TIMESTAMP)', 238 | params: [sanitizeInput(email), 'pending'], 239 | }), 240 | } 241 | ) 242 | 243 | if (!response.ok) { 244 | throw new Error(data.error || 'Signup failed') 245 | } 246 | 247 | localStorage.setItem('mcp_demo_signup', email) 248 | showSuccessState(email) 249 | setupCalendarActions() 250 | setupAccessibility() 251 | } catch (error) { 252 | console.error('Error:', error) 253 | //emailInput.style.border = '1px solid red' 254 | 255 | if (error.message.includes('UNIQUE constraint failed')) { 256 | showToast('This email is already registered for the demo. Check your inbox for details.') 257 | localStorage.setItem('mcp_demo_signup', email) 258 | showSuccessState(email) 259 | setupCalendarActions() 260 | setupAccessibility() 261 | } else { 262 | showToast('Something went wrong. Please try again.') 263 | } 264 | } 265 | })*/ 266 | 267 | // Initialize accessibility 268 | //() 269 | 270 | function setupCalendarActions() { 271 | const calendarActions = document.querySelectorAll( 272 | '.success-message .calendar-action, .calendar-option' 273 | ) 274 | const eventDetails = 275 | "Get a preview of the future of agentic software. See how the world's most innovative platforms have connected agents to their services with MCP to build a new class of product experiences.\n\nJoin Live: https://cloudflare.tv/mcp-demo-day" 276 | const location = 'https://cloudflare.tv/mcp-demo-day' 277 | 278 | calendarActions.forEach((option) => { 279 | option.addEventListener('click', () => { 280 | const calendarType = option.dataset.calendarType 281 | 282 | switch (calendarType) { 283 | case 'google': 284 | window.open( 285 | 'https://calendar.google.com/calendar/render?action=TEMPLATE&text=MCP+Demo+Day&details=Get+a+preview+of+the+future+of+agentic+software.+See+how+the+world%27s+most+innovative+platforms+have+connected+agents+to+their+services+with+MCP+to+build+a+new+class+of+product+experiences.%0A%0AJoin+Live%3A+https%3A%2F%2Fcloudflare.tv%2Fmcp-demo-day&location=https%3A%2F%2Fcloudflare.tv%2Fmcp-demo-day&dates=20250501T170000Z%2F20250501T183000Z', 286 | '_blank' 287 | ) 288 | break 289 | 290 | case 'outlook': 291 | window.open( 292 | 'https://outlook.live.com/calendar/0/deeplink/compose?subject=MCP+Demo+Day&body=Get+a+preview+of+the+future+of+agentic+software.+See+how+the+world%27s+most+innovative+platforms+have+connected+agents+to+their+services+with+MCP+to+build+a+new+class+of+product+experiences.%0A%0AJoin+Live%3A+https%3A%2F%2Fcloudflare.tv%2Fmcp-demo-day&startdt=2025-05-01T17%3A00%3A00Z&enddt=2025-05-01T18%3A30%3A00Z&location=https%3A%2F%2Fcloudflare.tv%2Fmcp-demo-day', 293 | '_blank' 294 | ) 295 | break 296 | 297 | case 'apple': 298 | case 'ics': 299 | const icsContent = `BEGIN:VCALENDAR 300 | VERSION:2.0 301 | PRODID:-//MCP Demo Day//EN 302 | CALSCALE:GREGORIAN 303 | BEGIN:VEVENT 304 | SUMMARY:MCP Demo Day 305 | DESCRIPTION:${eventDetails.replace(/\n/g, '\\n')} 306 | LOCATION:${location} 307 | DTSTART:20250501T170000Z 308 | DTEND:20250501T183000Z 309 | STATUS:CONFIRMED 310 | SEQUENCE:0 311 | END:VEVENT 312 | END:VCALENDAR` 313 | 314 | if (calendarType === 'apple') { 315 | const dataUri = 'data:text/calendar;charset=utf-8,' + encodeURIComponent(icsContent) 316 | window.open(dataUri) 317 | } else { 318 | const blob = new Blob([icsContent], { type: 'text/calendar;charset=utf-8' }) 319 | const link = document.createElement('a') 320 | link.href = window.URL.createObjectURL(blob) 321 | link.download = 'mcp_demo_day.ics' 322 | document.body.appendChild(link) 323 | link.click() 324 | document.body.removeChild(link) 325 | } 326 | break 327 | } 328 | 329 | // Close the dialog if it's open 330 | const dialog = document.getElementById('calendarDialog') 331 | if (dialog) { 332 | dialog.close() 333 | } 334 | }) 335 | }) 336 | } 337 | 338 | // Call setupCalendarActions immediately if needed 339 | setupCalendarActions() 340 | 341 | // Remove red border on input focus 342 | //emailInput.addEventListener('focus', () => { 343 | //emailInput.style.border = 'none' 344 | //}) 345 | 346 | // Company list hover effect 347 | const companies = document.querySelectorAll('.demo-companies li') 348 | companies.forEach((company) => { 349 | company.addEventListener('mouseenter', () => { 350 | companies.forEach((c) => { 351 | if (c !== company) { 352 | c.style.opacity = '0.5' 353 | } 354 | }) 355 | }) 356 | 357 | company.addEventListener('mouseleave', () => { 358 | companies.forEach((c) => { 359 | c.style.opacity = '1' 360 | }) 361 | }) 362 | }) 363 | 364 | // Setup company backgrounds 365 | const companyNames = [ 366 | 'asana', 367 | 'atlassian', 368 | 'cloudflare', 369 | 'intercom', 370 | 'linear', 371 | 'paypal', 372 | 'sentry', 373 | 'square', 374 | 'stripe', 375 | 'webflow', 376 | 'more', 377 | ] 378 | 379 | const demoList = document.querySelector('.demo-companies') 380 | const companyItems = demoList.querySelectorAll('li') 381 | 382 | // Add data attributes to company items 383 | companyItems.forEach((item, index) => { 384 | const company = companyNames[index] 385 | if (company) { 386 | item.setAttribute('data-company', company) 387 | } 388 | console.log('add attrib') 389 | }) 390 | 391 | // Create background containers for each company 392 | companyNames.forEach((company) => { 393 | console.log('add container') 394 | const background = document.createElement('div') 395 | background.className = `company-background ${company}` 396 | 397 | // Load SVG from file 398 | fetch(`/public/${company}.svg`) 399 | .then((response) => response.text()) 400 | .then((svgContent) => { 401 | // Clean up the SVG to remove any fill paths 402 | const parser = new DOMParser() 403 | const doc = parser.parseFromString(svgContent, 'image/svg+xml') 404 | const svg = doc.querySelector('svg') 405 | 406 | // Remove any fill attributes and set stroke 407 | svg.querySelectorAll('path, circle, rect').forEach((path) => { 408 | path.setAttribute('fill', 'none') 409 | path.setAttribute('stroke', 'currentColor') 410 | path.setAttribute('stroke-width', '.5') 411 | }) 412 | 413 | background.innerHTML = svg.outerHTML 414 | }) 415 | .catch((error) => console.error(`Error loading ${company}.svg:`, error)) 416 | 417 | demoList.appendChild(background) 418 | }) 419 | 420 | // Add cycling animation for company backgrounds 421 | let currentBackgroundIndex = 0 422 | let isHovering = false 423 | let hoverCompany = null 424 | const backgrounds = document.querySelectorAll('.company-background') 425 | 426 | function cycleBackgrounds() { 427 | // Remove active class from all backgrounds and company names 428 | backgrounds.forEach((bg) => bg.classList.remove('active')) 429 | companyItems.forEach((item) => item.classList.remove('active')) 430 | 431 | // If hovering, show the hovered company's background and highlight its name 432 | if (isHovering && hoverCompany) { 433 | const hoverBackground = Array.from(backgrounds).find((bg) => 434 | bg.classList.contains(hoverCompany) 435 | ) 436 | const hoverItem = Array.from(companyItems).find( 437 | (item) => item.getAttribute('data-company') === hoverCompany 438 | ) 439 | if (hoverBackground) { 440 | hoverBackground.classList.add('active') 441 | if (hoverItem) hoverItem.classList.add('active') 442 | return 443 | } 444 | } 445 | 446 | // Otherwise, show the next background in the cycle and highlight its name 447 | backgrounds[currentBackgroundIndex].classList.add('active') 448 | companyItems[currentBackgroundIndex].classList.add('active') 449 | currentBackgroundIndex = (currentBackgroundIndex + 1) % backgrounds.length 450 | console.log('cucle') 451 | } 452 | 453 | // Start cycling every 3 seconds 454 | setInterval(cycleBackgrounds, 3000) 455 | // Show first background immediately 456 | cycleBackgrounds() 457 | 458 | // Handle hover states 459 | companyItems.forEach((item) => { 460 | item.addEventListener('mouseenter', () => { 461 | isHovering = true 462 | hoverCompany = item.getAttribute('data-company') 463 | cycleBackgrounds() // Show the hovered company immediately 464 | }) 465 | 466 | item.addEventListener('mouseleave', () => { 467 | isHovering = false 468 | hoverCompany = null 469 | cycleBackgrounds() // Resume normal cycling 470 | }) 471 | }) 472 | 473 | function parseDateTime() { 474 | const dateText = document.querySelector('.date-time h2').textContent.trim() // e.g., "APRIL 30TH, 2025" 475 | const timeText = document.querySelector('.date-time h3').textContent.trim() // e.g., "ONLINE, 1:00 PM PT" 476 | 477 | // Remove ordinal indicators (st, nd, rd, th) and parse date 478 | const cleanDateText = dateText.replace(/(ST|ND|RD|TH),/i, ',') 479 | 480 | // Create a more precise regex to match the date format 481 | const dateTimeParts = cleanDateText.match(/^([A-Za-z]+)\s+(\d{1,2}),\s*(\d{4})$/i) 482 | // Handle "ONLINE, " prefix in time 483 | const timeParts = timeText 484 | .replace(/^ONLINE,\s*/i, '') 485 | .match(/^(\d{1,2}):(\d{2})\s*(AM|PM)\s*(PST|PDT|EST|EDT|CST|CDT|MST|MDT|PT)?$/i) 486 | 487 | if (!dateTimeParts || !timeParts) { 488 | throw new Error('Invalid date/time format') 489 | } 490 | 491 | const [, month, day, year] = dateTimeParts 492 | const [, hours, minutes, ampm, timezone] = timeParts 493 | 494 | let hour24 = parseInt(hours) 495 | 496 | // Convert to 24-hour format 497 | if (ampm.toUpperCase() === 'PM' && hour24 < 12) hour24 += 12 498 | if (ampm.toUpperCase() === 'AM' && hour24 === 12) hour24 = 0 499 | 500 | // Create date in UTC 501 | const date = new Date( 502 | Date.UTC(parseInt(year), getMonthIndex(month), parseInt(day), hour24, parseInt(minutes), 0) 503 | ) 504 | 505 | // Since the time is specified in PT (Pacific Time), adjust for PT (-7 hours from UTC during PDT) 506 | date.setUTCHours(date.getUTCHours() - 7) 507 | 508 | if (isNaN(date.getTime())) { 509 | throw new Error('Invalid date/time format') 510 | } 511 | 512 | return date 513 | } 514 | 515 | // Helper function to get month index (0-11) from month name 516 | function getMonthIndex(month) { 517 | const months = { 518 | JANUARY: 0, 519 | JAN: 0, 520 | FEBRUARY: 1, 521 | FEB: 1, 522 | MARCH: 2, 523 | MAR: 2, 524 | APRIL: 3, 525 | APR: 3, 526 | MAY: 4, 527 | JUNE: 5, 528 | JUN: 5, 529 | JULY: 6, 530 | JUL: 6, 531 | AUGUST: 7, 532 | AUG: 7, 533 | SEPTEMBER: 8, 534 | SEP: 8, 535 | OCTOBER: 9, 536 | OCT: 9, 537 | NOVEMBER: 10, 538 | NOV: 10, 539 | DECEMBER: 11, 540 | DEC: 11, 541 | } 542 | return months[month.toUpperCase()] 543 | } 544 | }) 545 | 546 | // Helper functions 547 | function isValidEmail(email) { 548 | const re = 549 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ 550 | return re.test(email.toLowerCase()) 551 | } 552 | 553 | // Particle System 554 | function createParticle() { 555 | const particle = document.createElement('div') 556 | particle.className = 'particle' 557 | 558 | // Random size between 3-6px 559 | const size = Math.random() * 3 + 3 560 | particle.style.width = `${size}px` 561 | particle.style.height = `${size}px` 562 | 563 | // Random starting position, but keep particles within viewport bounds 564 | const startX = Math.random() * (window.innerWidth - size) 565 | const startY = window.innerHeight + size 566 | 567 | particle.style.left = `${startX}px` 568 | particle.style.top = `${startY}px` 569 | 570 | // Random animation duration between 6-10 seconds 571 | const duration = Math.random() * 4000 + 6000 572 | particle.style.animation = `floatUp ${duration}ms cubic-bezier(0.4, 0, 0.2, 1) forwards` 573 | 574 | document.body.appendChild(particle) 575 | 576 | // Cleanup after animation 577 | setTimeout(() => { 578 | if (particle && particle.parentNode) { 579 | particle.parentNode.removeChild(particle) 580 | } 581 | }, duration) 582 | } 583 | 584 | // Particle manager 585 | let particleInterval 586 | const startParticles = () => { 587 | // Create initial batch of particles 588 | for (let i = 0; i < 5; i++) { 589 | setTimeout(() => createParticle(), i * 200) 590 | } 591 | 592 | // Create a new particle every 400ms 593 | particleInterval = setInterval(() => { 594 | // Limit to 15 particles at a time for better performance 595 | if (document.querySelectorAll('.particle').length < 15) { 596 | createParticle() 597 | } 598 | }, 400) 599 | } 600 | 601 | // Cleanup function 602 | const cleanupParticles = () => { 603 | if (particleInterval) { 604 | clearInterval(particleInterval) 605 | particleInterval = null 606 | } 607 | document.querySelectorAll('.particle').forEach((particle) => { 608 | if (particle.parentNode) { 609 | particle.parentNode.removeChild(particle) 610 | } 611 | }) 612 | } 613 | 614 | // Start particles when page loads 615 | startParticles() 616 | 617 | // Cleanup on page unload 618 | window.addEventListener('unload', cleanupParticles) 619 | 620 | // Pause particles when page is not visible 621 | document.addEventListener('visibilitychange', () => { 622 | if (document.hidden) { 623 | cleanupParticles() 624 | } else { 625 | startParticles() 626 | } 627 | }) 628 | 629 | // Restart particles on window resize 630 | let resizeTimeout 631 | window.addEventListener('resize', () => { 632 | if (resizeTimeout) { 633 | clearTimeout(resizeTimeout) 634 | } 635 | resizeTimeout = setTimeout(() => { 636 | cleanupParticles() 637 | startParticles() 638 | }, 200) 639 | }) 640 | 641 | function createConfetti(button) { 642 | const colors = ['#FF6633', '#FF8533', '#FF9966', '#FFAA80'] 643 | const confettiCount = 20 644 | 645 | for (let i = 0; i < confettiCount; i++) { 646 | const confetti = document.createElement('div') 647 | confetti.className = 'confetti' 648 | 649 | // Random size between 4-8px 650 | const size = Math.random() * 4 + 4 651 | confetti.style.width = `${size}px` 652 | confetti.style.height = `${size}px` 653 | 654 | // Random color from our palette 655 | confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)] 656 | 657 | // Random position behind the button 658 | const startX = Math.random() * button.offsetWidth 659 | confetti.style.left = `${startX}px` 660 | confetti.style.top = '50%' 661 | 662 | // Random animation duration and delay 663 | const duration = Math.random() * 400 + 600 664 | const delay = Math.random() * 200 665 | confetti.style.animation = `confettiFall ${duration}ms cubic-bezier(0.4, 0, 0.2, 1) ${delay}ms forwards` 666 | 667 | button.appendChild(confetti) 668 | 669 | // Cleanup 670 | setTimeout(() => { 671 | if (confetti.parentNode === button) { 672 | button.removeChild(confetti) 673 | } 674 | }, duration + delay) 675 | } 676 | } 677 | ``` -------------------------------------------------------------------------------- /apps/demo-day/frontend/public/intercom.svg: -------------------------------------------------------------------------------- ``` 1 | <svg width="491" height="490" viewBox="0 0 491 490" fill="none" xmlns="http://www.w3.org/2000/svg"> 2 | <mask id="path-1-inside-1_1164_3" fill="white"> 3 | <path d="M425.137 269.635C425.137 274.005 423.416 278.193 420.353 281.282C417.29 284.37 413.138 286.106 408.806 286.106C404.476 286.106 400.321 284.37 397.258 281.282C394.195 278.193 392.475 274.005 392.475 269.635V122.5C392.475 118.133 394.195 113.944 397.258 110.856C400.321 107.765 404.476 106.031 408.806 106.031C413.138 106.031 417.29 107.765 420.353 110.856C423.416 113.944 425.137 118.133 425.137 122.5V269.635ZM419.468 371.584C417.31 373.761 356.576 424.803 245.229 424.803C133.885 424.803 73.5572 374.034 70.9925 371.855C69.3751 370.481 68.0455 368.799 67.0746 366.905C66.1059 365.01 65.5152 362.942 65.3391 360.817C65.1651 358.693 65.4057 356.555 66.0522 354.524C66.6987 352.495 67.7341 350.613 69.1023 348.988C71.9205 345.7 75.9157 343.669 80.2138 343.336C84.5119 343.005 88.7648 344.402 92.0469 347.219C92.992 347.9 147.248 392.271 245.096 392.271C342.945 392.271 397.604 347.627 398.143 347.219C401.462 344.425 405.73 343.048 410.039 343.379C414.35 343.71 418.362 345.721 421.223 348.988C423.977 352.229 425.352 356.435 425.047 360.69C424.744 364.945 422.787 368.91 419.604 371.719L419.468 371.584ZM65.1887 122.5C65.4336 118.12 67.3861 114.013 70.6231 111.079C73.8601 108.146 78.1173 106.624 82.4648 106.847C86.4923 107.077 90.2942 108.805 93.136 111.696C95.9777 114.587 97.6553 118.436 97.8507 122.5V269.365C97.8507 273.732 96.1302 277.92 93.0672 281.009C90.0042 284.099 85.85 285.833 81.5197 285.833C77.1873 285.833 73.0353 284.099 69.9723 281.009C66.9092 277.92 65.1887 273.732 65.1887 269.365V122.5ZM147.112 89.8328C147.355 85.4529 149.31 81.3459 152.547 78.4124C155.784 75.4788 160.041 73.9594 164.386 74.1807C168.416 74.4128 172.218 76.1386 175.059 79.0292C177.899 81.9197 179.579 85.7688 179.772 89.8328V307.611C179.772 311.98 178.052 316.168 174.991 319.257C171.928 322.345 167.774 324.079 163.443 324.079C159.111 324.079 154.957 322.345 151.896 319.257C148.833 316.168 147.112 311.98 147.112 307.611V89.8328ZM229.44 81.6661C229.44 77.2991 231.16 73.1105 234.223 70.0222C237.286 66.9339 241.438 65.1974 245.771 65.1974C250.101 65.1974 254.255 66.9339 257.318 70.0222C260.381 73.1105 262.102 77.2991 262.102 81.6661V318.5C262.102 322.867 260.381 327.056 257.318 330.146C254.255 333.235 250.101 334.969 245.771 334.969C241.438 334.969 237.286 333.235 234.223 330.146C231.16 327.056 229.44 322.867 229.44 318.5V81.6661ZM310.418 89.8328C310.418 85.4658 312.139 81.2772 315.202 78.1889C318.262 75.1006 322.417 73.3641 326.749 73.3641C331.079 73.3641 335.234 75.1006 338.297 78.1889C341.357 81.2772 343.078 85.4658 343.078 89.8328V307.611C343.078 311.98 341.357 316.168 338.297 319.257C335.234 322.345 331.079 324.079 326.749 324.079C322.417 324.079 318.262 322.345 315.202 319.257C312.139 316.168 310.418 311.98 310.418 307.611V89.8328ZM429.592 0.00135809H61.4104C53.3878 -0.0523702 45.4338 1.48856 38.0019 4.54032C30.572 7.58994 23.8102 12.0902 18.1074 17.779C12.4024 23.4677 7.86801 30.2375 4.7599 37.6971C1.65394 45.1546 0.0365155 53.1601 0 61.2516V428.751C0.0365155 436.84 1.65394 444.845 4.7599 452.305C7.86801 459.763 12.4024 466.532 18.1074 472.221C23.8102 477.91 30.572 482.41 38.0019 485.46C45.4338 488.511 53.3878 490.052 61.4104 489.999H429.592C437.602 490.052 445.545 488.516 452.966 485.473C460.389 482.432 467.143 477.944 472.845 472.268C478.548 466.595 483.087 459.842 486.201 452.398C489.316 444.955 490.946 436.965 491 428.886V61.2516C490.963 53.1708 489.35 45.1782 486.253 37.7272C483.153 30.2762 478.63 23.515 472.94 17.8262C467.252 12.1396 460.505 7.63722 453.091 4.579C445.676 1.52079 437.737 -0.0351771 429.725 0.00135809"/> 4 | </mask> 5 | <path d="M397.258 110.856L397.968 111.56L397.969 111.56L397.258 110.856ZM420.353 110.856L419.643 111.56L419.643 111.56L420.353 110.856ZM419.468 371.584L420.176 370.877L419.466 370.166L418.758 370.88L419.468 371.584ZM70.9925 371.855L71.6401 371.093L71.6398 371.092L70.9925 371.855ZM67.0746 366.905L66.1842 367.36L66.1848 367.361L67.0746 366.905ZM65.3391 360.817L64.3424 360.898L64.3425 360.899L65.3391 360.817ZM66.0522 354.524L65.0994 354.22L65.0993 354.221L66.0522 354.524ZM69.1023 348.988L68.343 348.337L68.3374 348.344L69.1023 348.988ZM80.2138 343.336L80.137 342.339L80.1365 342.339L80.2138 343.336ZM92.0469 347.219L91.3956 347.978L91.4278 348.005L91.4622 348.03L92.0469 347.219ZM398.143 347.219L398.747 348.016L398.768 348.001L398.787 347.984L398.143 347.219ZM410.039 343.379L409.962 344.376L409.962 344.376L410.039 343.379ZM421.223 348.988L421.985 348.34L421.98 348.335L421.976 348.329L421.223 348.988ZM425.047 360.69L424.049 360.618L424.049 360.619L425.047 360.69ZM419.604 371.719L418.896 372.426L419.561 373.091L420.265 372.469L419.604 371.719ZM65.1887 122.5L64.1903 122.444L64.1887 122.472V122.5H65.1887ZM82.4648 106.847L82.5218 105.849L82.5162 105.849L82.4648 106.847ZM97.8507 122.5H98.8507V122.476L98.8496 122.452L97.8507 122.5ZM93.0672 281.009L92.3572 280.305L92.357 280.305L93.0672 281.009ZM69.9723 281.009L70.6825 280.305L70.6823 280.305L69.9723 281.009ZM147.112 89.8328L146.114 89.7775L146.112 89.8052V89.8328H147.112ZM164.386 74.1807L164.444 73.1824L164.437 73.182L164.386 74.1807ZM175.059 79.0292L175.773 78.3284L175.773 78.3281L175.059 79.0292ZM179.772 89.8328H180.772V89.8091L180.771 89.7853L179.772 89.8328ZM174.991 319.257L175.701 319.961L175.701 319.961L174.991 319.257ZM151.896 319.257L152.606 318.553L152.606 318.553L151.896 319.257ZM257.318 70.0222L256.608 70.7264L257.318 70.0222ZM257.318 330.146L258.028 330.851L258.028 330.85L257.318 330.146ZM234.223 330.146L233.513 330.85L233.513 330.851L234.223 330.146ZM315.202 78.1889L315.912 78.893L315.912 78.8928L315.202 78.1889ZM338.297 78.1889L339.007 77.4849L339.007 77.4847L338.297 78.1889ZM338.297 319.257L339.007 319.961L339.007 319.961L338.297 319.257ZM315.202 319.257L315.912 318.553L315.912 318.553L315.202 319.257ZM61.4104 0.00135809L61.4037 1.00136H61.4104V0.00135809ZM38.0019 4.54032L38.3816 5.46542L38.3817 5.46537L38.0019 4.54032ZM18.1074 17.779L18.8135 18.4871L18.8136 18.4869L18.1074 17.779ZM4.7599 37.6971L3.83682 37.3125L3.83677 37.3126L4.7599 37.6971ZM0 61.2516L-1 61.247V61.2516H0ZM0 428.751H-1.00001L-0.99999 428.755L0 428.751ZM4.7599 452.305L3.83673 452.689L3.83686 452.69L4.7599 452.305ZM18.1074 472.221L18.8136 471.513L18.8135 471.513L18.1074 472.221ZM38.0019 485.46L38.3817 484.535L38.3816 484.535L38.0019 485.46ZM61.4104 489.999V488.999L61.4037 488.999L61.4104 489.999ZM429.592 489.999L429.598 488.999H429.592V489.999ZM452.966 485.473L452.587 484.547L452.587 484.547L452.966 485.473ZM472.845 472.268L472.14 471.559L472.14 471.56L472.845 472.268ZM486.201 452.398L485.279 452.011L485.279 452.012L486.201 452.398ZM491 428.886L492 428.893V428.886H491ZM491 61.2516L492 61.2516L492 61.247L491 61.2516ZM486.253 37.7272L487.176 37.3433L487.176 37.3431L486.253 37.7272ZM472.94 17.8262L473.647 17.1191L473.647 17.1191L472.94 17.8262ZM425.137 269.635H424.137C424.137 273.742 422.52 277.677 419.643 280.577L420.353 281.282L421.063 281.986C424.313 278.709 426.137 274.267 426.137 269.635H425.137ZM420.353 281.282L419.643 280.577C416.767 283.478 412.87 285.106 408.806 285.106V286.106V287.106C413.407 287.106 417.814 285.262 421.063 281.986L420.353 281.282ZM408.806 286.106V285.106C404.744 285.106 400.845 283.478 397.968 280.577L397.258 281.282L396.548 281.986C399.798 285.262 404.207 287.106 408.806 287.106V286.106ZM397.258 281.282L397.968 280.577C395.092 277.677 393.475 273.742 393.475 269.635H392.475H391.475C391.475 274.267 393.299 278.709 396.548 281.986L397.258 281.282ZM392.475 269.635H393.475V122.5H392.475H391.475V269.635H392.475ZM392.475 122.5H393.475C393.475 118.395 395.092 114.46 397.968 111.56L397.258 110.856L396.548 110.151C393.299 113.428 391.475 117.87 391.475 122.5H392.475ZM397.258 110.856L397.969 111.56C400.845 108.658 404.743 107.031 408.806 107.031V106.031V105.031C404.208 105.031 399.798 106.873 396.548 110.152L397.258 110.856ZM408.806 106.031V107.031C412.87 107.031 416.767 108.658 419.643 111.56L420.353 110.856L421.064 110.152C417.814 106.873 413.406 105.031 408.806 105.031V106.031ZM420.353 110.856L419.643 111.56C422.52 114.46 424.137 118.395 424.137 122.5H425.137H426.137C426.137 117.87 424.313 113.428 421.063 110.151L420.353 110.856ZM425.137 122.5H424.137V269.635H425.137H426.137V122.5H425.137ZM419.468 371.584L418.758 370.88C416.764 372.891 356.277 423.803 245.229 423.803V424.803V425.803C356.875 425.803 417.856 374.63 420.178 372.288L419.468 371.584ZM245.229 424.803V423.803C134.205 423.803 74.0994 373.182 71.6401 371.093L70.9925 371.855L70.345 372.617C73.015 374.885 133.565 425.803 245.229 425.803V424.803ZM70.9925 371.855L71.6398 371.092C70.1235 369.805 68.876 368.226 67.9645 366.449L67.0746 366.905L66.1848 367.361C67.2151 369.371 68.6267 371.158 70.3453 372.617L70.9925 371.855ZM67.0746 366.905L67.9651 366.45C67.0555 364.67 66.501 362.729 66.3357 360.734L65.3391 360.817L64.3425 360.899C64.5294 363.155 65.1563 365.349 66.1842 367.36L67.0746 366.905ZM65.3391 360.817L66.3357 360.735C66.1723 358.741 66.3983 356.733 67.0051 354.827L66.0522 354.524L65.0993 354.221C64.413 356.377 64.1579 358.646 64.3424 360.898L65.3391 360.817ZM66.0522 354.524L67.005 354.828C67.6121 352.922 68.584 351.156 69.8672 349.632L69.1023 348.988L68.3374 348.344C66.8841 350.069 65.7854 352.068 65.0994 354.22L66.0522 354.524ZM69.1023 348.988L69.8616 349.639C72.5079 346.551 76.2582 344.645 80.291 344.333L80.2138 343.336L80.1365 342.339C75.5731 342.692 71.333 344.848 68.343 348.337L69.1023 348.988ZM80.2138 343.336L80.2905 344.333C84.3226 344.022 88.3139 345.332 91.3956 347.978L92.0469 347.219L92.6983 346.46C89.2157 343.471 84.7011 341.987 80.137 342.339L80.2138 343.336ZM92.0469 347.219L91.4622 348.03C91.4594 348.028 91.4717 348.037 91.517 348.073C91.5568 348.103 91.6087 348.144 91.6767 348.197C91.8112 348.302 91.9988 348.448 92.2385 348.631C92.7179 348.998 93.4041 349.515 94.2947 350.16C96.0758 351.45 98.6726 353.252 102.066 355.392C108.853 359.672 118.827 365.307 131.837 370.919C157.857 382.143 196.017 393.271 245.096 393.271V392.271V391.271C147.571 391.271 93.5301 347.056 92.6317 346.408L92.0469 347.219ZM245.096 392.271V393.271C294.176 393.271 332.438 382.074 358.507 370.816C371.541 365.188 381.528 359.544 388.296 355.277C391.68 353.143 394.259 351.353 396.013 350.082C396.89 349.446 397.56 348.94 398.021 348.585C398.251 348.407 398.429 348.268 398.554 348.169C398.616 348.12 398.665 348.081 398.7 348.053C398.743 348.02 398.751 348.014 398.747 348.016L398.143 347.219L397.54 346.422C397.069 346.778 342.624 391.271 245.096 391.271V392.271ZM398.143 347.219L398.787 347.984C401.906 345.358 405.916 344.065 409.962 344.376L410.039 343.379L410.115 342.382C405.544 342.03 401.018 343.492 397.499 346.454L398.143 347.219ZM410.039 343.379L409.962 344.376C414.011 344.687 417.781 346.576 420.471 349.647L421.223 348.988L421.976 348.329C418.943 344.866 414.688 342.733 410.115 342.382L410.039 343.379ZM421.223 348.988L420.461 349.635C423.045 352.676 424.336 356.623 424.049 360.618L425.047 360.69L426.044 360.761C426.368 356.246 424.909 351.781 421.985 348.34L421.223 348.988ZM425.047 360.69L424.049 360.619C423.765 364.614 421.928 368.335 418.942 370.969L419.604 371.719L420.265 372.469C423.646 369.486 425.723 365.276 426.044 360.761L425.047 360.69ZM419.604 371.719L420.311 371.012L420.176 370.877L419.468 371.584L418.761 372.291L418.896 372.426L419.604 371.719ZM65.1887 122.5L66.1872 122.555C66.4174 118.436 68.2536 114.576 71.2946 111.82L70.6231 111.079L69.9516 110.338C66.5186 113.449 64.4497 117.803 64.1903 122.444L65.1887 122.5ZM70.6231 111.079L71.2946 111.82C74.3353 109.064 78.3328 107.636 82.4135 107.846L82.4648 106.847L82.5162 105.849C77.9019 105.612 73.3848 107.227 69.9516 110.338L70.6231 111.079ZM82.4648 106.847L82.4078 107.846C86.1858 108.062 89.7542 109.683 92.4228 112.397L93.136 111.696L93.8491 110.995C90.8341 107.928 86.7988 106.093 82.5218 105.849L82.4648 106.847ZM93.136 111.696L92.4228 112.397C95.0913 115.111 96.6682 118.727 96.8519 122.548L97.8507 122.5L98.8496 122.452C98.6424 118.144 96.8641 114.062 93.8491 110.995L93.136 111.696ZM97.8507 122.5H96.8507V269.365H97.8507H98.8507V122.5H97.8507ZM97.8507 269.365H96.8507C96.8507 273.469 95.2336 277.404 92.3572 280.305L93.0672 281.009L93.7772 281.713C97.0269 278.436 98.8507 273.994 98.8507 269.365H97.8507ZM93.0672 281.009L92.357 280.305C89.481 283.207 85.5822 284.833 81.5197 284.833V285.833V286.833C86.1179 286.833 90.5275 284.992 93.7775 281.713L93.0672 281.009ZM81.5197 285.833V284.833C77.4552 284.833 73.5586 283.207 70.6825 280.305L69.9723 281.009L69.262 281.713C72.512 284.992 76.9193 286.833 81.5197 286.833V285.833ZM69.9723 281.009L70.6823 280.305C67.8059 277.404 66.1887 273.469 66.1887 269.365H65.1887H64.1887C64.1887 273.994 66.0126 278.436 69.2622 281.713L69.9723 281.009ZM65.1887 269.365H66.1887V122.5H65.1887H64.1887V269.365H65.1887ZM147.112 89.8328L148.111 89.8882C148.339 85.7698 150.177 81.9095 153.218 79.1534L152.547 78.4124L151.875 77.6714C148.442 80.7824 146.371 85.1361 146.114 89.7775L147.112 89.8328ZM152.547 78.4124L153.218 79.1534C156.259 76.3979 160.256 74.9716 164.335 75.1794L164.386 74.1807L164.437 73.182C159.826 72.9471 155.309 74.5598 151.875 77.6714L152.547 78.4124ZM164.386 74.1807L164.329 75.1791C168.11 75.3968 171.678 77.0161 174.346 79.7302L175.059 79.0292L175.773 78.3281C172.757 75.2611 168.722 73.4288 164.444 73.1824L164.386 74.1807ZM175.059 79.0292L174.346 79.73C177.013 82.4446 178.592 86.0609 178.773 89.8804L179.772 89.8328L180.771 89.7853C180.566 85.4768 178.785 81.3949 175.773 78.3284L175.059 79.0292ZM179.772 89.8328H178.772V307.611H179.772H180.772V89.8328H179.772ZM179.772 307.611H178.772C178.772 311.717 177.155 315.653 174.28 318.553L174.991 319.257L175.701 319.961C178.948 316.684 180.772 312.242 180.772 307.611H179.772ZM174.991 319.257L174.281 318.553C171.405 321.452 167.506 323.079 163.443 323.079V324.079V325.079C168.041 325.079 172.451 323.238 175.701 319.961L174.991 319.257ZM163.443 324.079V323.079C159.379 323.079 155.48 321.452 152.606 318.553L151.896 319.257L151.186 319.961C154.434 323.238 158.843 325.079 163.443 325.079V324.079ZM151.896 319.257L152.606 318.553C149.729 315.652 148.112 311.717 148.112 307.611H147.112H146.112C146.112 312.242 147.936 316.684 151.186 319.961L151.896 319.257ZM147.112 307.611H148.112V89.8328H147.112H146.112V307.611H147.112ZM229.44 81.6661H230.44C230.44 77.5617 232.057 73.6265 234.933 70.7264L234.223 70.0222L233.513 69.318C230.264 72.5944 228.44 77.0366 228.44 81.6661H229.44ZM234.223 70.0222L234.933 70.7264C237.81 67.8262 241.706 66.1974 245.771 66.1974V65.1974V64.1974C241.17 64.1974 236.763 66.0415 233.513 69.318L234.223 70.0222ZM245.771 65.1974V66.1974C249.833 66.1974 253.732 67.8263 256.608 70.7264L257.318 70.0222L258.028 69.318C254.778 66.0414 250.369 64.1974 245.771 64.1974V65.1974ZM257.318 70.0222L256.608 70.7264C259.484 73.6265 261.102 77.5617 261.102 81.6661H262.102H263.102C263.102 77.0366 261.278 72.5944 258.028 69.318L257.318 70.0222ZM262.102 81.6661H261.102V318.5H262.102H263.102V81.6661H262.102ZM262.102 318.5H261.102C261.102 322.605 259.485 326.54 256.608 329.442L257.318 330.146L258.028 330.85C261.278 327.572 263.102 323.13 263.102 318.5H262.102ZM257.318 330.146L256.608 329.442C253.732 332.342 249.833 333.969 245.771 333.969V334.969V335.969C250.369 335.969 254.778 334.127 258.028 330.851L257.318 330.146ZM245.771 334.969V333.969C241.706 333.969 237.809 332.342 234.933 329.442L234.223 330.146L233.513 330.851C236.763 334.127 241.17 335.969 245.771 335.969V334.969ZM234.223 330.146L234.933 329.442C232.057 326.54 230.44 322.605 230.44 318.5H229.44H228.44C228.44 323.13 230.264 327.572 233.513 330.85L234.223 330.146ZM229.44 318.5H230.44V81.6661H229.44H228.44V318.5H229.44ZM310.418 89.8328H311.418C311.418 85.7284 313.035 81.7932 315.912 78.893L315.202 78.1889L314.492 77.4847C311.242 80.7611 309.418 85.2033 309.418 89.8328H310.418ZM315.202 78.1889L315.912 78.8928C318.786 75.9931 322.685 74.3641 326.749 74.3641V73.3641V72.3641C322.149 72.3641 317.739 74.2081 314.491 77.4849L315.202 78.1889ZM326.749 73.3641V74.3641C330.811 74.3641 334.71 75.993 337.587 78.893L338.297 78.1889L339.007 77.4847C335.757 74.2081 331.348 72.3641 326.749 72.3641V73.3641ZM338.297 78.1889L337.586 78.8928C340.461 81.793 342.078 85.7283 342.078 89.8328H343.078H344.078C344.078 85.2033 342.254 80.7613 339.007 77.4849L338.297 78.1889ZM343.078 89.8328H342.078V307.611H343.078H344.078V89.8328H343.078ZM343.078 307.611H342.078C342.078 311.717 340.461 315.653 337.586 318.553L338.297 319.257L339.007 319.961C342.254 316.684 344.078 312.242 344.078 307.611H343.078ZM338.297 319.257L337.587 318.553C334.711 321.452 330.812 323.079 326.749 323.079V324.079V325.079C331.347 325.079 335.757 323.238 339.007 319.961L338.297 319.257ZM326.749 324.079V323.079C322.684 323.079 318.786 321.452 315.912 318.553L315.202 319.257L314.491 319.961C317.739 323.238 322.149 325.079 326.749 325.079V324.079ZM315.202 319.257L315.912 318.553C313.035 315.652 311.418 311.717 311.418 307.611H310.418H309.418C309.418 312.242 311.242 316.684 314.492 319.961L315.202 319.257ZM310.418 307.611H311.418V89.8328H310.418H309.418V307.611H310.418ZM429.592 0.00135809V-0.998642H61.4104V0.00135809V1.00136H429.592V0.00135809ZM61.4104 0.00135809L61.4171 -0.998619C53.2619 -1.05324 45.1766 0.513168 37.622 3.61527L38.0019 4.54032L38.3817 5.46537C45.6911 2.46394 53.5136 0.948495 61.4037 1.00134L61.4104 0.00135809ZM38.0019 4.54032L37.6222 3.61522C30.0698 6.71513 23.1971 11.2894 17.4012 17.071L18.1074 17.779L18.8136 18.4869C24.4234 12.8911 31.0743 8.46474 38.3816 5.46542L38.0019 4.54032ZM18.1074 17.779L17.4013 17.0708C11.603 22.8526 6.99511 29.7324 3.83682 37.3125L4.7599 37.6971L5.68298 38.0817C8.74092 30.7425 13.2018 24.0828 18.8135 18.4871L18.1074 17.779ZM4.7599 37.6971L3.83677 37.3126C0.680544 44.8908 -0.962887 53.0254 -0.99999 61.247L0 61.2516L0.99999 61.2561C1.03592 53.2948 2.62733 45.4184 5.68304 38.0816L4.7599 37.6971ZM0 61.2516H-1V428.751H0H1V61.2516H0ZM0 428.751L-0.99999 428.755C-0.962886 436.975 0.680557 445.109 3.83673 452.689L4.7599 452.305L5.68307 451.921C2.62732 444.582 1.03592 436.705 0.99999 428.746L0 428.751ZM4.7599 452.305L3.83686 452.69C6.99514 460.268 11.603 467.147 17.4013 472.929L18.1074 472.221L18.8135 471.513C13.2018 465.917 8.74089 459.258 5.68294 451.92L4.7599 452.305ZM18.1074 472.221L17.4012 472.929C23.1971 478.711 30.0698 483.285 37.6222 486.385L38.0019 485.46L38.3816 484.535C31.0743 481.535 24.4234 477.109 18.8136 471.513L18.1074 472.221ZM38.0019 485.46L37.622 486.385C45.1766 489.487 53.2619 491.053 61.4171 490.999L61.4104 489.999L61.4037 488.999C53.5136 489.052 45.6911 487.536 38.3817 484.535L38.0019 485.46ZM61.4104 489.999V490.999H429.592V489.999V488.999H61.4104V489.999ZM429.592 489.999L429.585 490.999C437.727 491.053 445.802 489.491 453.345 486.398L452.966 485.473L452.587 484.547C445.288 487.54 437.476 489.052 429.598 488.999L429.592 489.999ZM452.966 485.473L453.345 486.398C460.891 483.307 467.755 478.746 473.551 472.977L472.845 472.268L472.14 471.56C466.53 477.143 459.888 481.556 452.587 484.547L452.966 485.473ZM472.845 472.268L473.551 472.977C479.347 467.211 483.959 460.349 487.124 452.783L486.201 452.398L485.279 452.012C482.215 459.336 477.75 465.978 472.14 471.559L472.845 472.268ZM486.201 452.398L487.124 452.784C490.289 445.221 491.945 437.101 492 428.893L491 428.886L490 428.879C489.947 436.828 488.343 444.689 485.279 452.011L486.201 452.398ZM491 428.886H492V61.2516H491H490V428.886H491ZM491 61.2516L492 61.247C491.963 53.0362 490.324 44.9148 487.176 37.3433L486.253 37.7272L485.33 38.111C488.377 45.4417 489.964 53.3054 490 61.2561L491 61.2516ZM486.253 37.7272L487.176 37.3431C484.027 29.7716 479.43 22.9006 473.647 17.1191L472.94 17.8262L472.233 18.5334C477.83 24.1294 482.28 30.7807 485.33 38.1113L486.253 37.7272ZM472.94 17.8262L473.647 17.1191C467.866 11.3395 461.009 6.76314 453.472 3.65455L453.091 4.579L452.709 5.50346C460.002 8.51129 466.638 12.9398 472.233 18.5334L472.94 17.8262ZM453.091 4.579L453.472 3.65455C445.935 0.545961 437.865 -1.03577 429.72 -0.998632L429.725 0.00135809L429.729 1.00135C437.609 0.965417 445.417 2.49563 452.709 5.50346L453.091 4.579Z" fill="white" mask="url(#path-1-inside-1_1164_3)"/> 6 | </svg> 7 | ``` -------------------------------------------------------------------------------- /apps/demo-day/frontend/styles.css: -------------------------------------------------------------------------------- ```css 1 | :root { 2 | --primary-color: rgb(255, 102, 51); 3 | --text-color: #ffffff; 4 | --background-color: #0a0a0a; 5 | --input-background: rgba(255, 255, 255, 0.05); 6 | --button-hover: #ff8533; 7 | } 8 | 9 | * { 10 | margin: 0; 11 | padding: 0; 12 | box-sizing: border-box; 13 | } 14 | 15 | body { 16 | font-family: 'Inter', sans-serif; 17 | background-color: var(--background-color); 18 | color: var(--text-color); 19 | line-height: 1.5; 20 | -webkit-font-smoothing: antialiased; 21 | min-height: 100vh; 22 | position: relative; 23 | overflow-x: hidden; 24 | overflow-y: auto; 25 | width: 100%; 26 | } 27 | 28 | body::before { 29 | content: ''; 30 | position: fixed; 31 | top: 0; 32 | left: 0; 33 | right: 0; 34 | bottom: 0; 35 | background: 36 | radial-gradient( 37 | circle at 30% 50%, 38 | rgba(255, 255, 255, 0.02) 0%, 39 | rgba(255, 255, 255, 0.01) 30%, 40 | transparent 60% 41 | ), 42 | linear-gradient( 43 | 45deg, 44 | rgba(10, 10, 10, 0.98) 0%, 45 | rgba(15, 15, 15, 0.98) 50%, 46 | rgba(10, 10, 10, 0.98) 100% 47 | ); 48 | z-index: 0; 49 | animation: gradientFlow 30s ease infinite; 50 | } 51 | 52 | @keyframes gradientFlow { 53 | 0% { 54 | background-position: 55 | 0% 50%, 56 | 0% 50%; 57 | } 58 | 59 | 50% { 60 | background-position: 61 | 100% 50%, 62 | 100% 50%; 63 | } 64 | 65 | 100% { 66 | background-position: 67 | 0% 50%, 68 | 0% 50%; 69 | } 70 | } 71 | 72 | .page-wrapper { 73 | position: relative; 74 | min-height: 100vh; 75 | display: flex; 76 | flex-direction: column; 77 | z-index: 2; 78 | min-width: 0; 79 | width: 100%; 80 | overflow-x: hidden; 81 | overflow-y: hidden; 82 | } 83 | 84 | .container { 85 | display: grid; 86 | grid-template-columns: 1fr 1fr; 87 | flex: 1; 88 | min-width: 0; 89 | width: 100%; 90 | overflow: hidden; 91 | } 92 | 93 | /* Left Panel Styles */ 94 | .left-panel { 95 | padding: 3rem 4rem; 96 | display: flex; 97 | flex-direction: column; 98 | } 99 | 100 | .header { 101 | display: flex; 102 | justify-content: space-between; 103 | align-items: flex-start; 104 | } 105 | 106 | .logo { 107 | display: flex; 108 | align-items: flex-start; 109 | } 110 | 111 | .cloud-logo { 112 | width: 140px; 113 | height: auto; 114 | } 115 | 116 | .logo-text { 117 | display: flex; 118 | flex-direction: column; 119 | font-weight: 700; 120 | font-size: 1.75rem; 121 | line-height: 1; 122 | letter-spacing: -0.02em; 123 | } 124 | 125 | .content { 126 | margin-top: 4rem; 127 | } 128 | 129 | .date-time { 130 | display: inline-flex; 131 | align-items: center; 132 | gap: 1rem; 133 | border-radius: 14px; 134 | cursor: pointer; 135 | transition: all 0.2s ease; 136 | } 137 | 138 | .date-time-text { 139 | display: flex; 140 | flex-direction: column; 141 | gap: 0.25rem; 142 | order: 2; 143 | } 144 | 145 | .date-time h2 { 146 | font-size: 0.75rem; 147 | font-weight: 600; 148 | letter-spacing: 0.02em; 149 | line-height: 1.2; 150 | color: var(--text-color); 151 | } 152 | 153 | .date-time h3 { 154 | font-size: 0.75rem; 155 | color: rgba(255, 255, 255, 0.6); 156 | font-weight: 500; 157 | letter-spacing: 0.02em; 158 | line-height: 1.2; 159 | } 160 | 161 | .calendar-trigger { 162 | display: flex; 163 | align-items: center; 164 | justify-content: center; 165 | background: rgba(255, 255, 255, 0.03); 166 | border: 1px solid rgba(255, 255, 255, 0.1); 167 | padding: 0.5rem; 168 | color: rgba(255, 255, 255, 0.5); 169 | transition: all 0.2s ease; 170 | border-radius: 10px; 171 | order: 1; 172 | } 173 | 174 | .date-time:hover .calendar-trigger { 175 | color: var(--text-color); 176 | transform: scale(1.05); 177 | background: rgba(255, 255, 255, 0.06); 178 | border-color: rgba(255, 255, 255, 0.2); 179 | } 180 | 181 | h1 { 182 | font-size: 4rem; 183 | line-height: 1; 184 | margin-bottom: 2rem; 185 | font-weight: 700; 186 | letter-spacing: -0.03em; 187 | } 188 | 189 | .description { 190 | font-size: 1.25rem; 191 | color: rgba(255, 255, 255, 0.7); 192 | max-width: 85%; 193 | margin-bottom: 2.5rem; 194 | line-height: 1.4; 195 | } 196 | 197 | .input-group { 198 | display: flex; 199 | gap: 1rem; 200 | margin-bottom: 2rem; 201 | max-width: 560px; 202 | position: relative; 203 | flex-wrap: nowrap; 204 | } 205 | 206 | .input-group.success { 207 | animation: successSlide 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards; 208 | } 209 | 210 | @keyframes successSlide { 211 | 0% { 212 | transform: translateY(0); 213 | } 214 | 215 | 100% { 216 | transform: translateY(-20px); 217 | } 218 | } 219 | 220 | .success-message { 221 | position: absolute; 222 | left: 0; 223 | top: calc(100% + 24px); 224 | width: 100%; 225 | opacity: 0; 226 | transform: translateY(10px); 227 | transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); 228 | display: flex; 229 | flex-direction: column; 230 | gap: 1rem; 231 | pointer-events: none; 232 | } 233 | 234 | .input-group.success .success-message { 235 | opacity: 1; 236 | transform: translateY(0); 237 | pointer-events: all; 238 | } 239 | 240 | .success-text { 241 | display: flex; 242 | align-items: center; 243 | gap: 0.75rem; 244 | color: var(--text-color); 245 | font-size: 0.875rem; 246 | font-weight: 500; 247 | } 248 | 249 | .success-text svg { 250 | width: 18px; 251 | height: 18px; 252 | color: var(--primary-color); 253 | } 254 | 255 | .calendar-actions { 256 | display: flex; 257 | gap: 0.75rem; 258 | align-items: center; 259 | flex-wrap: wrap; 260 | } 261 | 262 | .calendar-action { 263 | display: flex; 264 | align-items: center; 265 | gap: 0.5rem; 266 | padding: 0.5rem 0.75rem; 267 | background: rgba(255, 255, 255, 0.03); 268 | border: 1px solid rgba(255, 255, 255, 0.1); 269 | border-radius: 6px; 270 | color: rgba(255, 255, 255, 0.8); 271 | font-size: 0.875rem; 272 | font-weight: 500; 273 | cursor: pointer; 274 | transition: all 0.2s ease; 275 | } 276 | 277 | .calendar-action:hover { 278 | background: rgba(255, 255, 255, 0.06); 279 | border-color: rgba(255, 255, 255, 0.2); 280 | transform: translateY(-1px); 281 | } 282 | 283 | .calendar-action svg { 284 | width: 16px; 285 | height: 16px; 286 | opacity: 0.7; 287 | transition: all 0.2s ease; 288 | } 289 | 290 | .calendar-action:hover svg { 291 | opacity: 1; 292 | } 293 | 294 | input[type='email'] { 295 | flex: 1; 296 | background: rgba(255, 255, 255, 0.03); 297 | border: 1px solid rgba(255, 255, 255, 0.2); 298 | min-height: 38px; 299 | padding: 0 16px; 300 | color: var(--text-color); 301 | font-size: 14px; 302 | border-radius: 6px; 303 | font-family: 'Inter', sans-serif; 304 | } 305 | 306 | input[type='email']::placeholder { 307 | color: rgba(255, 255, 255, 0.5); 308 | } 309 | 310 | input[type='email']:focus { 311 | outline: none; 312 | border-color: rgba(255, 255, 255, 0.4); 313 | } 314 | 315 | /* Add keyframes for glow animation */ 316 | @keyframes glowPulse { 317 | 0% { 318 | box-shadow: 0 0 0 0 rgba(255, 107, 0, 0.4); 319 | } 320 | 321 | 70% { 322 | box-shadow: 0 0 0 10px rgba(255, 107, 0, 0); 323 | } 324 | 325 | 100% { 326 | box-shadow: 0 0 0 0 rgba(255, 107, 0, 0); 327 | } 328 | } 329 | 330 | .notify-btn { 331 | text-decoration: none; 332 | background: transparent; 333 | border: 1px solid var(--primary-color); 334 | color: var(--primary-color); 335 | height: 38px; 336 | padding: 8px 16px; 337 | border-radius: 6px; 338 | display: flex; 339 | align-items: center; 340 | gap: 8px; 341 | cursor: pointer; 342 | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); 343 | font-size: 14px; 344 | font-weight: 500; 345 | position: relative; 346 | overflow: visible; 347 | } 348 | 349 | .notify-btn.success { 350 | background: var(--primary-color); 351 | color: var(--text-color); 352 | border-color: var(--primary-color); 353 | pointer-events: none; 354 | } 355 | 356 | .notify-btn.success svg { 357 | animation: checkmark 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards; 358 | } 359 | 360 | @keyframes checkmark { 361 | 0% { 362 | transform: scale(0); 363 | opacity: 0; 364 | } 365 | 366 | 50% { 367 | transform: scale(1.2); 368 | } 369 | 370 | 100% { 371 | transform: scale(1); 372 | opacity: 1; 373 | } 374 | } 375 | 376 | .notify-btn:hover { 377 | background: rgba(255, 107, 0, 0.1); 378 | border-color: var(--primary-color); 379 | animation: glowPulse 2s infinite; 380 | } 381 | 382 | .notify-btn svg { 383 | transition: all 0.3s ease; 384 | } 385 | 386 | .notify-btn:hover svg { 387 | filter: drop-shadow(0 0 8px rgba(255, 107, 0, 0.6)); 388 | transform: scale(1.02); 389 | opacity: 1; 390 | } 391 | 392 | .calendar-links { 393 | display: flex; 394 | align-items: center; 395 | gap: 1rem; 396 | color: rgba(255, 255, 255, 0.6); 397 | font-size: 0.875rem; 398 | } 399 | 400 | .calendar-icons { 401 | display: flex; 402 | gap: 0.75rem; 403 | } 404 | 405 | .calendar-icon { 406 | color: rgba(255, 255, 255, 0.6); 407 | transition: all 0.2s ease; 408 | display: flex; 409 | } 410 | 411 | .calendar-icon:hover { 412 | color: var(--text-color); 413 | } 414 | 415 | .calendar-icon svg { 416 | transition: all 0.3s ease; 417 | } 418 | 419 | .calendar-icon:hover svg { 420 | filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.4)); 421 | transform: scale(1.02); 422 | } 423 | 424 | /* Right Panel Styles */ 425 | .right-panel { 426 | padding: 3rem 4rem; 427 | position: relative; 428 | border-left: 1px solid rgba(255, 255, 255, 0.1); 429 | display: flex; 430 | flex-direction: column; 431 | overflow: hidden; 432 | } 433 | 434 | .company-background { 435 | position: absolute; 436 | bottom: -120%; 437 | right: -80%; 438 | width: 200%; 439 | height: 200%; 440 | opacity: 0; 441 | transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); 442 | pointer-events: none; 443 | z-index: 1; 444 | transform: scale(0.95); 445 | } 446 | 447 | .company-background.cloudflare { 448 | right: -100%; 449 | width: 180%; 450 | height: 180%; 451 | } 452 | 453 | .company-background.active { 454 | opacity: 1; 455 | transform: scale(1); 456 | } 457 | 458 | .company-background svg { 459 | width: 100%; 460 | height: 100%; 461 | object-fit: contain; 462 | opacity: 0.15; 463 | fill: none; 464 | stroke: #ffffff; 465 | filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.2)) 466 | drop-shadow(0 0 40px rgba(255, 255, 255, 0.1)); 467 | transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); 468 | } 469 | 470 | .company-background svg path, 471 | .company-background svg circle, 472 | .company-background svg rect { 473 | stroke: #ffffff; 474 | stroke-width: 1; 475 | transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); 476 | } 477 | 478 | .company-background.active svg path, 479 | .company-background.active svg circle, 480 | .company-background.active svg rect { 481 | stroke: #ffffff; 482 | stroke-width: 1.5; 483 | filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.3)); 484 | } 485 | 486 | /* Add a subtle pulse animation for active backgrounds */ 487 | @keyframes pulseGlow { 488 | 0% { 489 | filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.2)) 490 | drop-shadow(0 0 40px rgba(255, 255, 255, 0.1)); 491 | } 492 | 493 | 50% { 494 | filter: drop-shadow(0 0 30px rgba(255, 255, 255, 0.3)) 495 | drop-shadow(0 0 60px rgba(255, 255, 255, 0.15)); 496 | } 497 | 498 | 100% { 499 | filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.2)) 500 | drop-shadow(0 0 40px rgba(255, 255, 255, 0.1)); 501 | } 502 | } 503 | 504 | .company-background.active svg { 505 | animation: pulseGlow 3s infinite ease-in-out; 506 | } 507 | 508 | .demos-section { 509 | position: relative; 510 | z-index: 3; 511 | } 512 | 513 | .demos-section h4 { 514 | color: rgba(255, 255, 255, 0.5); 515 | font-size: 0.875rem; 516 | margin-bottom: 2.5rem; 517 | font-weight: 500; 518 | letter-spacing: 0.05em; 519 | } 520 | 521 | .demo-companies { 522 | list-style: none; 523 | position: relative; 524 | z-index: 2; 525 | } 526 | 527 | .demo-companies li { 528 | font-size: 2rem; 529 | font-weight: 600; 530 | margin-bottom: 0rem; 531 | transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); 532 | letter-spacing: -0.02em; 533 | line-height: 1.1; 534 | cursor: pointer; 535 | color: rgba(255, 255, 255, 0.3); 536 | text-shadow: 0 0 8px rgba(255, 255, 255, 0.1); 537 | } 538 | 539 | .demo-companies li.active { 540 | color: var(--primary-color); 541 | text-shadow: 542 | 0 0 15px rgba(255, 107, 0, 0.5), 543 | 0 0 30px rgba(255, 107, 0, 0.2); 544 | transform: scale(1.02); 545 | } 546 | 547 | .demo-companies li:hover { 548 | color: var(--primary-color); 549 | text-shadow: 550 | 0 0 15px rgba(255, 107, 0, 0.5), 551 | 0 0 30px rgba(255, 107, 0, 0.2); 552 | transform: scale(1.02); 553 | } 554 | 555 | /* Company-specific background visibility */ 556 | .demo-companies li[data-company='atlassian']:hover ~ .company-background.atlassian, 557 | .demo-companies li[data-company='canva']:hover ~ .company-background.canva, 558 | .demo-companies li[data-company='linear']:hover ~ .company-background.linear, 559 | .demo-companies li[data-company='paypal']:hover ~ .company-background.paypal, 560 | .demo-companies li[data-company='sentry']:hover ~ .company-background.sentry, 561 | .demo-companies li[data-company='cloudflare']:hover ~ .company-background.cloudflare, 562 | .demo-companies li[data-company='webflow']:hover ~ .company-background.webflow { 563 | opacity: 1; 564 | } 565 | 566 | /* Footer Styles */ 567 | footer { 568 | padding: 2rem 4rem; 569 | border-top: 1px solid rgba(255, 255, 255, 0.1); 570 | display: flex; 571 | justify-content: space-between; 572 | align-items: center; 573 | position: relative; 574 | } 575 | 576 | .footer-left { 577 | display: flex; 578 | align-items: center; 579 | gap: 3rem; 580 | } 581 | 582 | .cloudflare-logo { 583 | height: 20px; 584 | width: auto; 585 | filter: brightness(0) invert(1); 586 | opacity: 1; 587 | } 588 | 589 | .footer-links { 590 | position: absolute; 591 | left: 50%; 592 | transform: translateX(-50%); 593 | display: flex; 594 | gap: 2rem; 595 | } 596 | 597 | .footer-links a { 598 | color: rgba(255, 255, 255, 0.6); 599 | text-decoration: none; 600 | transition: color 0.2s ease; 601 | font-size: 0.875rem; 602 | } 603 | 604 | .footer-links a:hover { 605 | color: var(--text-color); 606 | } 607 | 608 | .build-btn { 609 | background: transparent; 610 | border: 1px solid var(--primary-color); 611 | color: var(--primary-color); 612 | height: 38px; 613 | padding: 8px 16px; 614 | border-radius: 6px; 615 | display: flex; 616 | align-items: center; 617 | gap: 8px; 618 | cursor: pointer; 619 | text-decoration: none; 620 | transition: all 0.2s ease; 621 | font-size: 14px; 622 | font-weight: 500; 623 | position: relative; 624 | overflow: visible; 625 | } 626 | 627 | .build-btn:hover { 628 | background: rgba(255, 107, 0, 0.1); 629 | border-color: var(--primary-color); 630 | animation: glowPulse 2s infinite; 631 | } 632 | 633 | .build-btn img { 634 | width: 24px; 635 | height: 24px; 636 | opacity: 0.7; 637 | transition: all 0.3s ease; 638 | } 639 | 640 | .build-btn:hover img { 641 | filter: drop-shadow(0 0 8px rgba(255, 107, 0, 0.6)); 642 | transform: scale(1.02); 643 | opacity: 1; 644 | } 645 | 646 | /* Responsive Design */ 647 | @media (max-width: 1400px) { 648 | h1 { 649 | font-size: 4rem; 650 | } 651 | 652 | .demo-companies li { 653 | font-size: 2.75rem; 654 | } 655 | } 656 | 657 | @media (max-width: 1200px) { 658 | h1 { 659 | font-size: 3.5rem; 660 | } 661 | 662 | .demo-companies li { 663 | font-size: 2.5rem; 664 | } 665 | 666 | .description { 667 | max-width: 100%; 668 | } 669 | 670 | .input-group { 671 | max-width: 560px; 672 | } 673 | } 674 | 675 | @media (max-width: 968px) { 676 | body { 677 | height: auto; 678 | overflow: auto; 679 | } 680 | 681 | .container { 682 | grid-template-columns: 1fr; 683 | } 684 | 685 | .right-panel { 686 | padding: 2rem; 687 | border-left: none; 688 | border-top: 1px solid rgba(255, 255, 255, 0.1); 689 | } 690 | 691 | .left-panel { 692 | padding: 2rem; 693 | } 694 | 695 | h1 { 696 | font-size: 3rem; 697 | } 698 | 699 | .input-group { 700 | max-width: 100%; 701 | flex-wrap: nowrap; 702 | gap: 0.75rem; 703 | } 704 | 705 | input[type='email'] { 706 | min-width: 0; 707 | flex: 1; 708 | } 709 | 710 | .notify-btn { 711 | width: fit-content; 712 | min-height: 38px; 713 | } 714 | 715 | footer { 716 | padding: 2rem; 717 | flex-direction: column; 718 | gap: 2rem; 719 | } 720 | 721 | .footer-links { 722 | position: static; 723 | transform: none; 724 | margin: 0 auto; 725 | } 726 | } 727 | 728 | @media (max-width: 480px) { 729 | .left-panel, 730 | .right-panel { 731 | padding: 1rem; 732 | min-width: 0; 733 | width: 100%; 734 | } 735 | 736 | .container { 737 | min-width: 0; 738 | width: 100%; 739 | overflow: hidden; 740 | } 741 | 742 | .page-wrapper { 743 | min-width: 0; 744 | width: 100%; 745 | overflow-x: hidden; 746 | } 747 | 748 | .date-time { 749 | padding: 0.5rem; 750 | } 751 | 752 | /*.date-time-text { 753 | display: none; 754 | }*/ 755 | 756 | .calendar-trigger { 757 | order: 1; 758 | margin: 0; 759 | } 760 | 761 | .input-group { 762 | flex-direction: column; 763 | gap: 0.75rem; 764 | width: 100%; 765 | } 766 | 767 | .input-group.success { 768 | margin-bottom: 125px; 769 | } 770 | 771 | input[type='email'] { 772 | width: 100%; 773 | min-width: 0; 774 | height: 38px; 775 | } 776 | 777 | .notify-btn { 778 | width: 100%; 779 | justify-content: center; 780 | height: 38px; 781 | } 782 | 783 | h1 { 784 | font-size: 2.5rem; 785 | max-width: 100%; 786 | } 787 | 788 | .description { 789 | font-size: 1rem; 790 | max-width: 100%; 791 | } 792 | 793 | .demo-companies li { 794 | font-size: 2rem; 795 | } 796 | 797 | .footer-left { 798 | flex-direction: column; 799 | gap: 1.5rem; 800 | } 801 | 802 | .footer-links { 803 | flex-direction: column; 804 | align-items: center; 805 | gap: 1rem; 806 | } 807 | } 808 | 809 | /* Add a subtle light effect */ 810 | .left-panel::before { 811 | content: ''; 812 | position: absolute; 813 | top: 0; 814 | left: 0; 815 | right: 0; 816 | bottom: 0; 817 | background: linear-gradient( 818 | 90deg, 819 | transparent 0%, 820 | rgba(255, 255, 255, 0.01) 30%, 821 | rgba(255, 255, 255, 0.005) 50%, 822 | transparent 100% 823 | ); 824 | z-index: -1; 825 | pointer-events: none; 826 | animation: lightBeam 15s ease-in-out infinite; 827 | transform-origin: left; 828 | filter: blur(40px); 829 | } 830 | 831 | @keyframes lightBeam { 832 | 0%, 833 | 100% { 834 | opacity: 0.3; 835 | transform: scaleX(0.9) translateX(-5%); 836 | } 837 | 838 | 50% { 839 | opacity: 0.4; 840 | transform: scaleX(1.1) translateX(5%); 841 | } 842 | } 843 | 844 | /* Add a subtle depth effect */ 845 | .left-panel::after { 846 | content: ''; 847 | position: absolute; 848 | top: 0; 849 | left: 0; 850 | right: 0; 851 | bottom: 0; 852 | background: radial-gradient(circle at 30% 50%, rgba(255, 255, 255, 0.01) 0%, transparent 60%); 853 | z-index: -2; 854 | pointer-events: none; 855 | animation: depthPulse 20s ease-in-out infinite; 856 | filter: blur(50px); 857 | } 858 | 859 | @keyframes depthPulse { 860 | 0%, 861 | 100% { 862 | opacity: 0.2; 863 | transform: scale(1); 864 | } 865 | 866 | 50% { 867 | opacity: 0.3; 868 | transform: scale(1.05); 869 | } 870 | } 871 | 872 | /* Remove the old animations */ 873 | .starfield, 874 | .floating-particle, 875 | body::after { 876 | display: none; 877 | } 878 | 879 | .calendar-popover { 880 | background: rgb(23, 23, 23); 881 | border-radius: 12px; 882 | padding: 1.5rem; 883 | width: 320px; 884 | box-shadow: 885 | 0 0 0 1px rgba(255, 255, 255, 0.1), 886 | 0 8px 32px rgba(0, 0, 0, 0.4), 887 | 0 2px 8px rgba(0, 0, 0, 0.2); 888 | position: relative; 889 | animation: modalAppear 0.2s cubic-bezier(0.21, 1.02, 0.73, 1); 890 | transform-origin: center center; 891 | } 892 | 893 | @keyframes modalAppear { 894 | from { 895 | opacity: 0; 896 | transform: scale(0.98); 897 | } 898 | 899 | to { 900 | opacity: 1; 901 | transform: scale(1); 902 | } 903 | } 904 | 905 | .calendar-popover h4 { 906 | font-size: 1.125rem; 907 | font-weight: 600; 908 | margin-bottom: 1rem; 909 | color: var(--text-color); 910 | padding-right: 2rem; 911 | } 912 | 913 | .calendar-options { 914 | display: flex; 915 | flex-direction: column; 916 | gap: 0.5rem; 917 | } 918 | 919 | .calendar-option { 920 | display: flex; 921 | align-items: center; 922 | gap: 0.75rem; 923 | padding: 0.75rem; 924 | border-radius: 8px; 925 | background: transparent; 926 | border: none; 927 | cursor: pointer; 928 | transition: all 0.15s ease; 929 | color: rgba(255, 255, 255, 0.8); 930 | width: 100%; 931 | text-align: left; 932 | } 933 | 934 | .calendar-option:hover { 935 | background: rgba(255, 255, 255, 0.06); 936 | color: var(--text-color); 937 | } 938 | 939 | .calendar-option svg { 940 | width: 20px; 941 | height: 20px; 942 | opacity: 0.7; 943 | transition: all 0.2s ease; 944 | } 945 | 946 | .calendar-option:hover svg { 947 | opacity: 1; 948 | } 949 | 950 | .calendar-option span { 951 | font-size: 0.875rem; 952 | font-weight: 500; 953 | } 954 | 955 | .close-button { 956 | position: absolute; 957 | top: 1rem; 958 | right: 1rem; 959 | background: transparent; 960 | border: none; 961 | color: rgba(255, 255, 255, 0.5); 962 | padding: 0.375rem; 963 | cursor: pointer; 964 | transition: all 0.2s ease; 965 | border-radius: 6px; 966 | display: flex; 967 | align-items: center; 968 | justify-content: center; 969 | } 970 | 971 | .close-button:hover { 972 | background: rgba(255, 255, 255, 0.06); 973 | color: var(--text-color); 974 | } 975 | 976 | .close-button svg { 977 | width: 16px; 978 | height: 16px; 979 | } 980 | 981 | dialog { 982 | position: fixed; 983 | top: 50%; 984 | left: 50%; 985 | transform: translate(-50%, -50%) !important; 986 | margin: 0; 987 | background: transparent; 988 | border: none; 989 | padding: 0; 990 | width: fit-content; 991 | height: fit-content; 992 | } 993 | 994 | dialog::backdrop { 995 | background: rgba(0, 0, 0, 0.5); 996 | backdrop-filter: blur(4px); 997 | animation: backdropFade 0.2s ease; 998 | } 999 | 1000 | @keyframes backdropFade { 1001 | from { 1002 | opacity: 0; 1003 | } 1004 | 1005 | to { 1006 | opacity: 1; 1007 | } 1008 | } 1009 | 1010 | .attendees { 1011 | display: flex; 1012 | align-items: center; 1013 | gap: 0.75rem; 1014 | margin-top: 1rem; 1015 | font-size: 0.875rem; 1016 | color: rgba(255, 255, 255, 0.7); 1017 | opacity: 1; 1018 | transform: translateY(0); 1019 | transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); 1020 | } 1021 | 1022 | .input-group.success ~ .attendees { 1023 | opacity: 0; 1024 | transform: translateY(-10px); 1025 | pointer-events: none; 1026 | } 1027 | 1028 | .attendee-avatars { 1029 | display: flex; 1030 | align-items: center; 1031 | } 1032 | 1033 | .attendee-avatar { 1034 | width: 32px; 1035 | height: 32px; 1036 | border-radius: 50%; 1037 | overflow: visible; 1038 | position: relative; 1039 | border: 2px solid rgba(255, 255, 255, 0.1); 1040 | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); 1041 | margin-right: -8px; 1042 | background: var(--background-color); 1043 | } 1044 | 1045 | .attendee-avatar:hover { 1046 | transform: translateY(-2px); 1047 | border-color: rgba(255, 255, 255, 0.3); 1048 | z-index: 2; 1049 | margin-right: 4px; 1050 | } 1051 | 1052 | .attendee-avatar img { 1053 | width: 100%; 1054 | height: 100%; 1055 | object-fit: cover; 1056 | border-radius: 50%; 1057 | } 1058 | 1059 | .attendee-avatar[data-tooltip] { 1060 | cursor: pointer; 1061 | } 1062 | 1063 | .attendee-avatar[data-tooltip]::before { 1064 | content: attr(data-tooltip); 1065 | position: absolute; 1066 | bottom: calc(100% + 8px); 1067 | left: 50%; 1068 | transform: translateX(-50%); 1069 | padding: 0.5rem 0.75rem; 1070 | background: rgba(23, 23, 23, 0.95); 1071 | color: white; 1072 | font-size: 0.875rem; 1073 | border-radius: 6px; 1074 | white-space: nowrap; 1075 | opacity: 0; 1076 | visibility: hidden; 1077 | transition: all 0.2s ease; 1078 | backdrop-filter: blur(8px); 1079 | border: 1px solid rgba(255, 255, 255, 0.1); 1080 | z-index: 1000; 1081 | pointer-events: none; 1082 | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); 1083 | width: max-content; 1084 | } 1085 | 1086 | .attendee-avatar[data-tooltip]::after { 1087 | content: ''; 1088 | position: absolute; 1089 | bottom: calc(100% + 4px); 1090 | left: 50%; 1091 | transform: translateX(-50%); 1092 | border: 6px solid transparent; 1093 | border-top-color: rgba(23, 23, 23, 0.95); 1094 | opacity: 0; 1095 | visibility: hidden; 1096 | transition: all 0.2s ease; 1097 | z-index: 1000; 1098 | pointer-events: none; 1099 | } 1100 | 1101 | .attendee-avatar[data-tooltip]:hover::before, 1102 | .attendee-avatar[data-tooltip]:hover::after { 1103 | opacity: 1; 1104 | visibility: visible; 1105 | transform: translateX(-50%) translateY(-4px); 1106 | pointer-events: none; 1107 | } 1108 | 1109 | .attendee-count { 1110 | font-weight: 500; 1111 | margin-left: 4px; 1112 | } 1113 | 1114 | .attendee-count strong { 1115 | color: var(--text-color); 1116 | font-weight: 600; 1117 | } 1118 | 1119 | .particle { 1120 | position: fixed; 1121 | pointer-events: none; 1122 | border-radius: 50%; 1123 | background: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.05)); 1124 | box-shadow: 0 0 4px rgba(255, 255, 255, 0.1); 1125 | opacity: 0; 1126 | z-index: 10; 1127 | will-change: transform, opacity; 1128 | } 1129 | 1130 | @keyframes floatUp { 1131 | 0% { 1132 | opacity: 0; 1133 | transform: translateY(0) scale(1); 1134 | } 1135 | 1136 | 15% { 1137 | opacity: 0.3; 1138 | } 1139 | 1140 | 50% { 1141 | opacity: 0.2; 1142 | } 1143 | 1144 | 85% { 1145 | opacity: 0.1; 1146 | } 1147 | 1148 | 100% { 1149 | opacity: 0; 1150 | transform: translateY(-100vh) scale(0.8); 1151 | } 1152 | } 1153 | 1154 | /* Confetti piece */ 1155 | .confetti { 1156 | position: absolute; 1157 | pointer-events: none; 1158 | transform-origin: center; 1159 | mix-blend-mode: screen; 1160 | will-change: transform, opacity; 1161 | } 1162 | 1163 | @keyframes confettiFall { 1164 | 0% { 1165 | transform: translateY(0) rotate(0deg) scale(0); 1166 | opacity: 1; 1167 | } 1168 | 1169 | 100% { 1170 | transform: translateY(20px) rotate(360deg) scale(1); 1171 | opacity: 0; 1172 | } 1173 | } 1174 | 1175 | @keyframes successPop { 1176 | 0% { 1177 | transform: scale(1); 1178 | } 1179 | 1180 | 50% { 1181 | transform: scale(1.1); 1182 | } 1183 | 1184 | 100% { 1185 | transform: scale(1); 1186 | } 1187 | } 1188 | 1189 | .notify-btn.success { 1190 | animation: successPop 0.4s cubic-bezier(0.4, 0, 0.2, 1); 1191 | } 1192 | 1193 | /* Honeypot field - hide it from users but keep it visible to bots */ 1194 | .contact-field { 1195 | display: none !important; 1196 | position: absolute !important; 1197 | left: -9999px !important; 1198 | } 1199 | 1200 | .toast { 1201 | position: fixed; 1202 | bottom: 24px; 1203 | left: 50%; 1204 | transform: translateX(-50%); 1205 | background: rgba(17, 17, 17, 0.95); 1206 | color: #fff; 1207 | padding: 12px 24px; 1208 | border-radius: 8px; 1209 | font-size: 14px; 1210 | z-index: 1000; 1211 | opacity: 0; 1212 | transition: opacity 0.3s ease; 1213 | backdrop-filter: blur(8px); 1214 | border: 1px solid rgba(255, 255, 255, 0.1); 1215 | box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2); 1216 | pointer-events: none; 1217 | } 1218 | 1219 | .toast.show { 1220 | opacity: 1; 1221 | } 1222 | ```